diff --git a/src/routes/_authenticated/attendance.tsx b/src/routes/_authenticated/attendance.tsx deleted file mode 100644 index 1ca0a37..0000000 --- a/src/routes/_authenticated/attendance.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { createFileRoute } from "@tanstack/react-router"; -import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; -import { supabase } from "@/integrations/supabase/client"; -import { useAuth } from "@/hooks/use-auth"; -import { Button } from "@/components/ui/button"; -import { Input } from "@/components/ui/input"; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; -import { useState } from "react"; -import { toast } from "sonner"; - -export const Route = createFileRoute("/_authenticated/attendance")({ - head: () => ({ meta: [{ title: "Attendance — School Portal" }] }), - component: AttendancePage, -}); - -function AttendancePage() { - const { user, roles, loading } = useAuth(); - const isAdmin = roles.includes("admin"); - const qc = useQueryClient(); - const [date, setDate] = useState(new Date().toISOString().slice(0, 10)); - const [classId, setClassId] = useState(""); - - const { data: classes } = useQuery({ - // isAdmin is in the key so the query refetches once roles resolve; gated on - // !loading so it never runs with a not-yet-known (false) admin status. - queryKey: ["my-classes", user?.id, isAdmin], - queryFn: async () => { - let q = supabase.from("classes").select("id, name, teacher_id"); - if (!isAdmin) q = q.eq("teacher_id", user!.id); - return (await q.order("name")).data ?? []; - }, - enabled: !!user && !loading, - }); - - const { data: students } = useQuery({ - queryKey: ["class-students", classId, date], - queryFn: async () => { - if (!classId) return []; - const { data } = await supabase.from("students").select("id, first_name, last_name, attendance(status, date, id)").eq("class_id", classId); - return data ?? []; - }, - enabled: !!classId, - }); - - const mark = useMutation({ - mutationFn: async ({ studentId, status }: { studentId: string; status: string }) => { - const { error } = await supabase.from("attendance").upsert( - { student_id: studentId, date, status: status as "present" | "absent" | "late" | "excused", recorded_by: user!.id }, - { onConflict: "student_id,date" } - ); - if (error) throw error; - }, - onSuccess: () => qc.invalidateQueries({ queryKey: ["class-students", classId, date] }), - onError: (e: Error) => toast.error(e.message), - }); - - const getStatus = (s: { attendance: { date: string; status: string }[] }) => - s.attendance.find((a) => a.date === date)?.status ?? ""; - - return ( -
-

Attendance

-

Mark today's attendance for your class.

- -
-
- -
- setDate(e.target.value)} /> -
- - {classId && ( -
- {(students ?? []).map((s) => { - const status = getStatus(s as { attendance: { date: string; status: string }[] }); - return ( -
-
{s.last_name}, {s.first_name}
-
- {["present", "absent", "late", "excused"].map((opt) => ( - - ))} -
-
- ); - })} - {students?.length === 0 &&
No students in this class.
} -
- )} - {!classId &&

Select a class to begin.

} -
- ); -}