Modified by www.SourceFiles.app

This commit is contained in:
2026-08-07 05:33:58 +00:00
parent 5f9baa202d
commit 8ef0b55785
+67 -16
View File
@@ -3,8 +3,22 @@ import { useAuth, highestRole } from "@/hooks/use-auth";
import { supabase } from "@/integrations/supabase/client"; import { supabase } from "@/integrations/supabase/client";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { import {
GraduationCap, LayoutDashboard, Users, ClipboardCheck, Receipt, GraduationCap,
MessageSquare, FileText, CalendarDays, Settings, LogOut, Loader2, BookOpen, ClipboardList, Printer, Mail LayoutDashboard,
Users,
ClipboardCheck,
Receipt,
MessageSquare,
FileText,
CalendarDays,
Settings,
LogOut,
Loader2,
BookOpen,
ClipboardList,
Printer,
Mail,
CreditCard,
} from "lucide-react"; } from "lucide-react";
import { useEffect } from "react"; import { useEffect } from "react";
@@ -23,7 +37,11 @@ function ProtectedLayout() {
}, [loading, user, navigate]); }, [loading, user, navigate]);
if (loading || !user) { if (loading || !user) {
return <div className="min-h-screen flex items-center justify-center"><Loader2 className="h-6 w-6 animate-spin text-muted-foreground" /></div>; return (
<div className="min-h-screen flex items-center justify-center">
<Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
</div>
);
} }
const role = highestRole(roles); const role = highestRole(roles);
@@ -32,11 +50,32 @@ function ProtectedLayout() {
const nav = [ const nav = [
{ to: "/dashboard", label: "Dashboard", icon: LayoutDashboard, show: true }, { to: "/dashboard", label: "Dashboard", icon: LayoutDashboard, show: true },
{ to: "/students", label: "Students", icon: Users, show: true }, { to: "/students", label: "Students", icon: Users, show: true },
{ to: "/classes", label: "Classes", icon: BookOpen, show: isAdmin || roles.includes("teacher") }, {
{ to: "/attendance", label: "Attendance", icon: ClipboardCheck, show: isAdmin || roles.includes("teacher") }, to: "/classes",
{ to: "/plans", label: "504 / IEP", icon: ClipboardList, show: isAdmin || roles.includes("teacher") }, label: "Classes",
icon: BookOpen,
show: isAdmin || roles.includes("teacher"),
},
{
to: "/attendance",
label: "Attendance",
icon: ClipboardCheck,
show: isAdmin || roles.includes("teacher"),
},
{
to: "/plans",
label: "504 / IEP",
icon: ClipboardList,
show: isAdmin || roles.includes("teacher"),
},
{ to: "/reports", label: "Reports", icon: Printer, show: isAdmin || roles.includes("teacher") }, { to: "/reports", label: "Reports", icon: Printer, show: isAdmin || roles.includes("teacher") },
{ to: "/ledger", label: "Tuition", icon: Receipt, show: true }, { to: "/ledger", label: "Tuition", icon: Receipt, show: true },
{
to: "/billing",
label: "Billing",
icon: CreditCard,
show: isAdmin || roles.includes("billing_admin"),
},
{ to: "/messages", label: "Messages", icon: MessageSquare, show: true }, { to: "/messages", label: "Messages", icon: MessageSquare, show: true },
{ to: "/mail", label: "Mail", icon: Mail, show: isAdmin || roles.includes("teacher") }, { to: "/mail", label: "Mail", icon: Mail, show: isAdmin || roles.includes("teacher") },
{ to: "/forms", label: "Forms", icon: FileText, show: true }, { to: "/forms", label: "Forms", icon: FileText, show: true },
@@ -56,23 +95,35 @@ function ProtectedLayout() {
<img src="/bayside-logo.png" alt="Bayside Academy" className="h-9 w-auto" /> <img src="/bayside-logo.png" alt="Bayside Academy" className="h-9 w-auto" />
</div> </div>
<nav className="p-3 flex-1 space-y-1"> <nav className="p-3 flex-1 space-y-1">
{nav.filter((n) => n.show).map((n) => { {nav
const active = path.startsWith(n.to); .filter((n) => n.show)
return ( .map((n) => {
<Link key={n.to} to={n.to} className={`flex items-center gap-2 px-3 py-2 rounded-md text-sm ${active ? "bg-primary text-primary-foreground" : "hover:bg-muted"}`}> const active = path.startsWith(n.to);
<n.icon className="h-4 w-4" /> {n.label} return (
</Link> <Link
); key={n.to}
})} to={n.to}
className={`flex items-center gap-2 px-3 py-2 rounded-md text-sm ${active ? "bg-primary text-primary-foreground" : "hover:bg-muted"}`}
>
<n.icon className="h-4 w-4" /> {n.label}
</Link>
);
})}
</nav> </nav>
<div className="p-3 border-t"> <div className="p-3 border-t">
<div className="text-xs text-muted-foreground mb-2 px-1 truncate">{user.email}<br/><span className="capitalize">{role ?? "no role"}</span></div> <div className="text-xs text-muted-foreground mb-2 px-1 truncate">
{user.email}
<br />
<span className="capitalize">{role ?? "no role"}</span>
</div>
<Button variant="ghost" size="sm" className="w-full justify-start" onClick={signOut}> <Button variant="ghost" size="sm" className="w-full justify-start" onClick={signOut}>
<LogOut className="h-4 w-4 mr-2" /> Sign out <LogOut className="h-4 w-4 mr-2" /> Sign out
</Button> </Button>
</div> </div>
</aside> </aside>
<main className="flex-1 overflow-auto"><Outlet /></main> <main className="flex-1 overflow-auto">
<Outlet />
</main>
</div> </div>
); );
} }