Modified by www.SourceFiles.app
This commit is contained in:
@@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user