diff --git a/src/routes/_authenticated/reports.tsx b/src/routes/_authenticated/reports.tsx new file mode 100644 index 0000000..e1abfa3 --- /dev/null +++ b/src/routes/_authenticated/reports.tsx @@ -0,0 +1,191 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { useQuery } 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 { Label } from "@/components/ui/label"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { FileText, Printer } from "lucide-react"; +import { useState } from "react"; +import { IepProgressDoc, ReportCardDoc } from "@/components/reports"; +import { REPORT_TYPES, monthToDateRange, schoolYearRange, type ReportType } from "@/lib/reports"; + +export const Route = createFileRoute("/_authenticated/reports")({ + head: () => ({ meta: [{ title: "Reports — School Portal" }] }), + component: ReportsPage, +}); + +const ALL = "__all__"; + +function ReportsPage() { + const { user, roles, loading } = useAuth(); + const isAdmin = roles.includes("admin"); + + const [type, setType] = useState("report_card"); + const [classId, setClassId] = useState(""); + const [studentId, setStudentId] = useState(ALL); + const year = schoolYearRange(); + const [from, setFrom] = useState(year.from); + const [to, setTo] = useState(year.to); + + const { data: classes } = useQuery({ + 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: ["report-class-students", classId], + enabled: !!classId, + queryFn: async () => + ( + await supabase + .from("students") + .select("id, first_name, last_name") + .eq("class_id", classId) + .order("last_name") + ).data ?? [], + }); + + const selected = + studentId === ALL ? (students ?? []) : (students ?? []).filter((s) => s.id === studentId); + + const applyPreset = (preset: "year" | "month") => { + const r = preset === "year" ? schoolYearRange() : monthToDateRange(); + setFrom(r.from); + setTo(r.to); + }; + + return ( +
+
+

+ Reports +

+

+ Build report cards, academic progress reports, and 504 / IEP goal progress reports. Print + or save as PDF from your browser — each student starts on a new page. +

+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ + {/* Uncontrolled + keyed so Safari's native picker isn't reset by React. */} + setFrom(e.target.value)} + /> +
+
+ + setTo(e.target.value)} + /> +
+
+ + +
+
+ +
+ + {classId + ? `${selected.length} document${selected.length === 1 ? "" : "s"} ready` + : "Select a class to begin."} + + +
+
+
+ +
+ {selected.map((s) => + type === "iep" ? ( + + ) : ( + + ), + )} +
+
+ ); +}