import { createFileRoute, Link } 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 { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Switch } from "@/components/ui/switch"; import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"; import { ArrowLeft, Upload, Trash2, Plus, FileText } from "lucide-react"; import { useState } from "react"; import { toast } from "sonner"; export const Route = createFileRoute("/_authenticated/students/$id")({ head: () => ({ meta: [{ title: "Student — School Portal" }] }), component: StudentDetail, }); function StudentDetail() { const { id } = Route.useParams(); const { roles } = useAuth(); const isAdmin = roles.includes("admin"); const qc = useQueryClient(); const { data: student } = useQuery({ queryKey: ["student", id], queryFn: async () => { const { data, error } = await supabase.from("students").select("*, classes(name)").eq("id", id).single(); if (error) throw error; return data; }, }); return (
All students

{student?.first_name} {student?.last_name}

{(student?.classes as { name: string } | null)?.name ?? "No class"}

Info Authorized pickup Attendance Tuition ledger {isAdmin && Contracts} {isAdmin && }
); } function InfoTab({ studentId, canEdit }: { studentId: string; canEdit: boolean }) { const qc = useQueryClient(); const { data: s } = useQuery({ queryKey: ["student", studentId], queryFn: async () => (await supabase.from("students").select("*").eq("id", studentId).single()).data, }); const [form, setForm] = useState | null>(null); const current = form ?? (s as Record | null); const save = useMutation({ mutationFn: async () => { if (!current) return; const { error } = await supabase.from("students").update({ first_name: current.first_name as string, last_name: current.last_name as string, dob: (current.dob as string) || null, allergies: (current.allergies as string) || null, photo_release: !!current.photo_release, notes: (current.notes as string) || null, }).eq("id", studentId); if (error) throw error; }, onSuccess: () => { toast.success("Saved"); qc.invalidateQueries({ queryKey: ["student", studentId] }); setForm(null); }, onError: (e: Error) => toast.error(e.message), }); if (!current) return null; const upd = (k: string, v: unknown) => setForm({ ...(current as Record), [k]: v }); return (
upd("first_name", e.target.value)} />
upd("last_name", e.target.value)} />
upd("dob", e.target.value)} />
upd("allergies", e.target.value)} />
upd("photo_release", v)} />