Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions fix_lint.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import fs from 'fs';
import path from 'path';

// Fix toast dependencies
const toastFiles = [
'src/components/FocusTimer.tsx',
'src/components/GroupPomodoro.tsx',
'src/hooks/useCreateSession.ts',
'src/hooks/useSessions.ts',
'src/hooks/useSkillEndorsements.ts',
'src/pages/Portfolio.tsx',
'src/pages/ReviewSubmission.tsx'
];

for(const file of toastFiles) {
let content = fs.readFileSync(file, 'utf-8');
content = content.replace(/(?<=(\[|,)\s*)toast(?=\s*(,|\]))/g, '');
content = content.replace(/,\s*,/g, ',');
content = content.replace(/\[\s*,/g, '[');
content = content.replace(/,\s*\]/g, ']');
fs.writeFileSync(file, content, 'utf-8');
}

// Fix fast refresh warnings
const fastRefreshFiles = [
'src/components/markdown/MarkdownRenderer.tsx',
'src/components/theme-provider.tsx',
'src/components/ui/sonner.tsx'
];

for(const file of fastRefreshFiles) {
let content = fs.readFileSync(file, 'utf-8');
if (!content.includes('eslint-disable-next-line react-refresh/only-export-components') && !content.includes('eslint-disable react-refresh/only-export-components')) {
content = `/* eslint-disable react-refresh/only-export-components */\n` + content;
fs.writeFileSync(file, content, 'utf-8');
}
}

// Fix seedTestimonials dependency
const testimonialsFile = 'src/components/landing/Testimonials.tsx';
let testContent = fs.readFileSync(testimonialsFile, 'utf-8');
testContent = testContent.replace(/\[searchTerm, categoryFilter\]/g, '[searchTerm, categoryFilter, seedTestimonials]');
fs.writeFileSync(testimonialsFile, testContent, 'utf-8');
2 changes: 0 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React, { useEffect, Suspense, useState, useRef } from "react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { BrowserRouter, Routes, Route, Navigate, Router, useLocation } from "react-router-dom";

import { Toaster } from "@/components/ui/toaster";
import { Toaster as Sonner } from "@/components/ui/sonner";
import { TooltipProvider } from "@/components/ui/tooltip";

Expand Down Expand Up @@ -399,7 +398,6 @@ function App() {
<QueryClientProvider client={queryClient}>
<ThemeProvider>
<TooltipProvider>
<Toaster />
<Sonner />

<BrowserRouter>
Expand Down
1 change: 0 additions & 1 deletion src/components/AvatarUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React, { useRef, useState } from "react";
import { Camera, Loader2 } from "lucide-react";
import { supabase } from "@/integrations/supabase/client";
import { API_BASE_URL } from "@/config/api";

type AvatarUploadProps = {
currentAvatarUrl: string;
onUploadSuccess: (url: string) => void;
Expand Down
2 changes: 1 addition & 1 deletion src/components/FloatingAI.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

files=(
  src/components/FloatingAI.tsx
  src/components/NotificationsDropdown.tsx
  src/components/Room/ChatBox.tsx
  src/components/Room/InviteMenu.tsx
  src/features/notifications/pushNotifications.ts
  src/features/notifications/useNotifications.ts
  src/hooks/useRoomChat.ts
  src/hooks/useRoomDetails.ts
  src/pages/Discover.tsx
)

for f in "${files[@]}"; do
  echo "===== $f ====="
  if [ -f "$f" ]; then
    wc -l "$f"
    sed -n '1,220p' "$f" | cat -n
  else
    echo "missing"
  fi
  echo
done

Repository: durdana3105/peer-learning

Length of output: 42061


Replace the remaining any usages

The no-explicit-any suppressions were removed, but these files still contain explicit any types/casts:

  • src/components/FloatingAI.tsx: useState<any[]>
  • src/components/NotificationsDropdown.tsx: (supabase as any) / payload: any
  • src/components/Room/ChatBox.tsx: messages: any[]
  • src/components/Room/InviteMenu.tsx: (supabase.rpc as any)
  • src/features/notifications/pushNotifications.ts: (supabase as any)
  • src/features/notifications/useNotifications.ts: (supabase as any)
  • src/hooks/useRoomChat.ts: useState<any[]> / as any
  • src/hooks/useRoomDetails.ts: useState<any> / as any
  • src/pages/Discover.tsx: multiple any usages
📍 Affects 9 files
  • src/components/FloatingAI.tsx#L1-L1 (this comment)
  • src/components/NotificationsDropdown.tsx#L1-L1
  • src/components/Room/ChatBox.tsx#L12-L13
  • src/components/Room/InviteMenu.tsx#L17-L18
  • src/features/notifications/pushNotifications.ts#L1-L1
  • src/features/notifications/useNotifications.ts#L1-L1
  • src/hooks/useRoomChat.ts#L7-L13
  • src/hooks/useRoomChat.ts#L33-L34
  • src/hooks/useRoomDetails.ts#L8-L16
  • src/pages/Discover.tsx#L1-L1
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/FloatingAI.tsx` at line 1, Remove all explicit any usages
across the listed sites: replace FloatingAI.tsx:1-1 useState<any[]>;
NotificationsDropdown.tsx:1-1 Supabase casts and payload; ChatBox.tsx:12-13
messages; InviteMenu.tsx:17-18 rpc cast; pushNotifications.ts:1-1 and
useNotifications.ts:1-1 Supabase casts; useRoomChat.ts:7-13,33-34 state and
cast; useRoomDetails.ts:8-16 state and cast; and Discover.tsx:1-1 usages. Use
the appropriate existing domain, component, or generated Supabase types and
preserve each current behavior without weakening type safety.

import { useState } from "react";
import { Bot, Send, X, User } from "lucide-react";
import { API_BASE_URL } from "@/config/api";
Expand Down
20 changes: 9 additions & 11 deletions src/components/FocusTimer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
DropdownMenuTrigger,
DropdownMenuContent,
} from '@/components/ui/dropdown-menu';
import { useToast } from '@/components/ui/use-toast';
import { toast } from "sonner";

const clampDuration = (value: string, min: number, max: number, fallback: number) => {
const next = Number(value);
Expand All @@ -18,7 +18,7 @@ const clampDuration = (value: string, min: number, max: number, fallback: number

export default function FocusTimer() {
const { user } = useAuth();
const { toast } = useToast();


const [isActive, setIsActive] = useState(false);
const [isBreak, setIsBreak] = useState(false);
Expand Down Expand Up @@ -49,10 +49,9 @@ export default function FocusTimer() {

const handleTimerComplete = useCallback(async () => {
if (!isBreak) {
toast({
title: "Focus Session Complete! 🎉",
description: `Great job focusing for ${workDuration} minutes! Time for a break.`,
});
toast("Focus Session Complete! 🎉", {
description: `Great job focusing for ${workDuration} minutes! Time for a break.`
});

setIsBreak(true);
setTimeLeft(breakDuration * 60);
Expand All @@ -66,15 +65,14 @@ export default function FocusTimer() {
.eq('id', user.id);
}
} else {
toast({
title: "Break Over!",
description: "Ready for another focus session?",
});
toast("Break Over!", {
description: "Ready for another focus session?"
});
setIsBreak(false);
setIsActive(false);
setTimeLeft(workDuration * 60);
}
}, [isBreak, workDuration, breakDuration, focusTimeThisWeek, user, toast]);
}, [isBreak, workDuration, breakDuration, focusTimeThisWeek, user]);

// Timer logic
useEffect(() => {
Expand Down
40 changes: 17 additions & 23 deletions src/components/GroupPomodoro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { supabase } from '@/integrations/supabase/client';
import { useAuth } from '@/contexts/useAuth';
import { Play, Square, Coffee, Clock } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { useToast } from '@/components/ui/use-toast';
import { toast } from "sonner";
import { motion } from 'framer-motion';
import { logError } from '@/utils/logger';

Expand Down Expand Up @@ -31,7 +31,7 @@ const formatTime = (seconds: number) => {
};

export default memo(function GroupPomodoro({ roomId, creatorId }: GroupPomodoroProps) {
const { toast } = useToast();

const { user } = useAuth();

const isCreator = creatorId !== null && user?.id === creatorId;
Expand Down Expand Up @@ -75,11 +75,9 @@ export default memo(function GroupPomodoro({ roomId, creatorId }: GroupPomodoroP
}
} catch (err: any) {
logError(err, { context: "GroupPomodoro.fetchTimerState", roomId });
toast({
title: "Failed to load timer",
description: err.message || "Could not sync the room's timer state.",
variant: "destructive",
});
toast.error("Failed to load timer", {
description: err.message || "Could not sync the room's timer state."
});
}
};

Expand All @@ -105,7 +103,7 @@ export default memo(function GroupPomodoro({ roomId, creatorId }: GroupPomodoroP
active = false;
supabase.removeChannel(channel);
};
}, [roomId, toast]);
}, [roomId]);

const clampDurations = useCallback(() => ({
work: Math.min(WORK_MAX, Math.max(WORK_MIN, Math.floor(workDuration))),
Expand Down Expand Up @@ -137,31 +135,27 @@ export default memo(function GroupPomodoro({ roomId, creatorId }: GroupPomodoroP
}
} catch (err: any) {
logError(err, { context: "GroupPomodoro.setGroupTimer", roomId, newState });
toast({
title: 'Timer update failed',
description: err.message || 'Could not sync the timer. Please try again.',
variant: 'destructive',
});
toast.error('Timer update failed', {
description: err.message || 'Could not sync the timer. Please try again.'
});
}
}, [clampDurations, roomId, toast]);
}, [clampDurations, roomId]);

const handleTimerComplete = useCallback(async () => {
if (!isCreator) return;

if (timerState === 'work') {
toast({
title: 'Group Focus Session Complete! 🎉',
description: 'Great job focusing! Time for a short break.',
});
toast('Group Focus Session Complete! 🎉', {
description: 'Great job focusing! Time for a short break.'
});
await setGroupTimer('break');
} else if (timerState === 'break') {
toast({
title: 'Break Over!',
description: 'Back to focus?',
});
toast('Break Over!', {
description: 'Back to focus?'
});
await setGroupTimer('idle');
}
}, [isCreator, timerState, setGroupTimer, toast]);
}, [isCreator, timerState, setGroupTimer]);

// Countdown logic
useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/NotificationsDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useState, useEffect, useRef } from "react";
import { Bell } from "lucide-react";
import { supabase } from "@/integrations/supabase/client";
Expand Down
2 changes: 1 addition & 1 deletion src/components/Room/ChatBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const MarkdownRenderer = React.lazy(() =>
);

interface ChatBoxProps {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
messages: any[];
user: User | null;
onSendMessage: (msg: string) => Promise<void>;
Expand Down
2 changes: 1 addition & 1 deletion src/components/Room/InviteMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const InviteMenu = React.memo(function InviteMenu({ roomId }: InviteMenuP
const handleInvite = async () => {
if (!inviteEmail.trim()) return;
setIsInviting(true);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { error } = await (supabase.rpc as any)("invite_to_study_room", {
p_room_id: roomId,
p_user_email: inviteEmail,
Expand Down
2 changes: 1 addition & 1 deletion src/components/Sparkles.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useEffect, useRef } from 'react';

const Sparkles: React.FC = () => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/StudyRooms.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { supabase } from '@/integrations/supabase/client';
Expand Down
2 changes: 1 addition & 1 deletion src/components/Whiteboard/Canvas.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useCallback, useEffect, useRef, useState } from "react";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/contexts/useAuth";
Expand Down
2 changes: 1 addition & 1 deletion src/components/dashboard/RecentActivity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default function RecentActivity() {
supabase
.from("resources")
.select("id, title, created_at")
.eq("user_id", user.id)
.eq("uploaded_by", user.id)
.order("created_at", { ascending: false })
.limit(3),
supabase
Expand Down
Loading
Loading