import FormContainer from "@/components/FormContainer"; import Table from "@/components/Table"; import { getSupabaseClient } from "@/lib/supabase"; import { Tables } from "@/types/supabase"; import { auth } from "@clerk/nextjs/server"; import { notFound } from "next/navigation"; import GenerateLessonsForm from "@/components/forms/GenerateLessonsForm"; type EntryList = Tables<"TeacherTimetableEntry"> & { class: Tables<"Class"> | null; subject: Tables<"Subject"> | null; slot: Tables<"SchoolTimetableSlot"> | null; }; const SingleTemplatePage = async ({ params: { id }, }: { params: { id: string }; }) => { const { sessionClaims, userId } = auth(); const role = (sessionClaims?.metadata as { role?: string })?.role; const schoolId = (sessionClaims?.metadata as { schoolId?: string })?.schoolId; const teacherType = (sessionClaims?.metadata as { teacherType?: string })?.teacherType; const canManageSchool = role === "admin" || (role === "teacher" && (teacherType === "INDEPENDENT" || teacherType === "AGENCY")); const isTemplateOwner = (tid: string) => tid === userId; const supabase = await getSupabaseClient(); // Fetch the template const { data: template, error: templateError } = await supabase .from("TeacherTimetableTemplate") .select("*, teacher:Teacher(*)") .eq("id", parseInt(id)) .single(); if (templateError || !template) { return notFound(); } // Ensure it belongs to the current school if (schoolId && template.schoolId !== schoolId) { return notFound(); } // Fetch the entries const { data: rawEntries } = await supabase .from("TeacherTimetableEntry") .select("*, class:Class(*), subject:Subject(*), slot:SchoolTimetableSlot(*)") .eq("teacherTimetableTemplateId", template.id) .order("dayOfWeek", { ascending: true }); const entries = (rawEntries || []) as unknown as EntryList[]; // Sort entries by day then by slot position entries.sort((a, b) => { if (a.dayOfWeek !== b.dayOfWeek) return a.dayOfWeek - b.dayOfWeek; const posA = (a.slot as { position?: number })?.position ?? 0; const posB = (b.slot as { position?: number })?.position ?? 0; return posA - posB; }); const schoolForTerms = schoolId || template.schoolId; const terms = schoolForTerms ? (await supabase .from("Term") .select("id, name, startDate, endDate") .eq("schoolId", schoolForTerms) .order("startDate", { ascending: true })).data ?? [] : []; const columns = [ { header: "Day", accessor: "dayOfWeek" }, { header: "Time Slot", accessor: "slot" }, { header: "Class", accessor: "class", className: "hidden md:table-cell" }, { header: "Subject", accessor: "subject", className: "hidden md:table-cell" }, ...(role === "admin" ? [{ header: "Actions", accessor: "action" }] : []), ]; const getDayName = (day: number) => { const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; // JS days: 0 = Sunday, 1 = Monday. We'll map assuming 1 = Monday like our form (1-7). if (day >= 1 && day <= 7) { // Just map standard ISO 1=Monday... 7=Sunday const isoDays = ["", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; return isoDays[day]; } return "Unknown"; } const renderRow = (item: EntryList) => ( {getDayName(item.dayOfWeek)} {item.slot ? `${item.slot.name} (${item.slot.startTime}-${item.slot.endTime})` : "-"} {item.class?.name || "-"} {item.subject?.name || "-"}
{role === "admin" && ( <> )}
); return (
{/* LEFT */}
{/* TOP INFO */}

{template.name}

Teacher Owner: {template.teacher ? `${template.teacher.name} ${template.teacher.surname}` : "Unknown"}

{/* GENERATE LESSONS: template owner or admin; use template.schoolId when session school not set (e.g. admin) */} {canManageSchool && (role === "admin" || isTemplateOwner(template.teacherId)) && (schoolId || template.schoolId) && ( )} {/* ENTRIES LIST */}

Timetable Entries

{role === "admin" && ( )}
); }; export default SingleTemplatePage;