"use client"; /** * The dashboard's navigation. * * From lg up it's a fixed column beside the page. Below that it's a drawer * that slides in from the left, opened from the top bar's menu button, so * phones get the full width for the page itself. */ import { useEffect } from "react"; import Link from "next/link"; import { ClipboardCheck, Flag, ShieldCheck, Gift, Megaphone, Quote, FolderClosed, LayoutDashboard, LayoutGrid, Link2, LogOut, MessageSquare, Users, X, } from "lucide-react"; import { MANAGE_STAFF, type Me, type StaffMe } from "@/lib/api"; import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; // Each entry names the permission that unlocks it, so the sidebar only shows // what the signed-in role can actually use. export const NAV = [ { href: "/", label: "Overview", icon: LayoutDashboard, perm: "stats:read" }, { href: "/users", label: "Users", icon: Users, perm: "users:read" }, { href: "/posts", label: "Posts", icon: LayoutGrid, perm: "posts:moderate" }, { href: "/collections", label: "Collections", icon: FolderClosed, perm: "collections:read", }, { href: "/short-urls", label: "Short URLs", icon: Link2, perm: "short_urls:read", }, { href: "/feedback", label: "Feedback", icon: MessageSquare, perm: "feedback:read", }, { href: "/reports", label: "Reports", icon: Flag, perm: "reports:read" }, { href: "/broadcasts", label: "Announcements", icon: Megaphone, perm: "broadcasts:read", }, { href: "/reward-gifts", label: "Gifts", icon: Gift, perm: "rewards:read" }, { href: "/vani", label: "Vāṇī of the Day", icon: Quote, perm: "vani:read" }, { href: "/quizzes", label: "Quizzes", icon: ClipboardCheck, perm: "quizzes:read", }, { href: "/staff", label: "Staff & roles", icon: ShieldCheck, perm: MANAGE_STAFF, }, ]; export function Sidebar({ me, staffMe, pathname, open, onClose, onSignOut, }: { me: Me; staffMe: StaffMe; pathname: string; /** Drawer state below lg; ignored from lg up, where it's always shown. */ open: boolean; onClose: () => void; onSignOut: () => void; }) { // While the drawer is open: Escape closes it and the page behind it // doesn't scroll. useEffect(() => { if (!open) return; const onKey = (e: KeyboardEvent) => e.key === "Escape" && onClose(); document.addEventListener("keydown", onKey); const prev = document.body.style.overflow; document.body.style.overflow = "hidden"; return () => { document.removeEventListener("keydown", onKey); document.body.style.overflow = prev; }; }, [open, onClose]); return ( <> {/* Backdrop — drawer only. */}
> ); }