diff --git a/components/app-sidebar.tsx b/components/app-sidebar.tsx index 457e6fd..2513239 100644 --- a/components/app-sidebar.tsx +++ b/components/app-sidebar.tsx @@ -15,6 +15,7 @@ import { MessageSquare, Users, CreditCard, BookUser, Download, LogOut, Vote, ShieldAlert, ScrollText, LineChart, UserCircle, UserSearch, MessagesSquare, SlidersHorizontal, ClipboardList, FileText, Award, BadgeCheck, GraduationCap, Hammer, + ChevronDown, } from 'lucide-react' interface NavLinkProps { @@ -52,6 +53,54 @@ function NavLink({ href, label, icon: Icon, badge, active, onClick }: NavLinkPro ) } +// Collapsible category. Open/closed is remembered per category in +// localStorage so it survives navigation; defaults to open so nothing is +// hidden on first visit. +function NavSection({ + id, + title, + children, +}: { + id: string + title: string + children: React.ReactNode +}) { + const storageKey = `sidebar:section:${id}` + const [open, setOpen] = useState(true) + useEffect(() => { + try { + if (window.localStorage.getItem(storageKey) === 'closed') setOpen(false) + } catch { + /* localStorage unavailable; keep default */ + } + }, [storageKey]) + const toggle = () => { + setOpen(prev => { + const next = !prev + try { + window.localStorage.setItem(storageKey, next ? 'open' : 'closed') + } catch { + /* ignore */ + } + return next + }) + } + return ( +