import React, { useMemo, useState } from 'react'; import { LayoutDashboard, Tag, MapPin, Users, Package, FileText, HelpCircle, LogOut, ChevronDown, ChevronRight, Layers, Type, FileBox, Settings } from 'lucide-react'; import { cn } from '../ui/utils'; import { ScrollArea } from '../ui/scroll-area'; import logo from "figma:asset/773f0c39e1986271e9144596caac519f934a6ae6.png"; import type { CurrentUserMenuNodeDto } from '../../types/authSession'; interface SidebarProps { currentView: string; setCurrentView: (view: string) => void; menus?: CurrentUserMenuNodeDto[]; onLogout?: () => void; } const FALLBACK_ICONS = { Dashboard: LayoutDashboard, Labeling: Tag, Labels: Tag, "Label Categories": Layers, "Label Types": Type, "Label Templates": FileBox, "Multiple Option Sets": Settings, "Multiple Options": Settings, "Location Manager": MapPin, "Account Management": Users, "Menu Management": Package, "System Menu": Settings, Reports: FileText, Support: HelpCircle, "Log Out": LogOut, } as const; function normalizeLabel(name: string) { return name.trim() || "N/A"; } function displayMenuLabel(name: string) { const s = normalizeLabel(name); if (s === "Multiple Options") return "Multiple Option Sets"; return s; } function pickIconKeyFromNode(node: CurrentUserMenuNodeDto, label: string): keyof typeof FALLBACK_ICONS | null { const raw = String((node as any)?.menuIcon ?? (node as any)?.MenuIcon ?? "").trim(); if (raw && raw in FALLBACK_ICONS) return raw as keyof typeof FALLBACK_ICONS; if (label in FALLBACK_ICONS) return label as keyof typeof FALLBACK_ICONS; return null; } function MenuNode({ node, level, currentKey, onSelect, }: { node: CurrentUserMenuNodeDto; level: number; currentKey: string; onSelect: (key: string) => void; }) { const [open, setOpen] = React.useState(true); const children = node.children ?? []; const isDir = (node.menuType ?? 0) === 0 || children.length > 0; const label = normalizeLabel(String(node.menuName ?? node.routerName ?? node.routeUrl ?? node.id ?? "")); const viewKey = label === "Multiple Options" ? "Multiple Option Sets" : label; const active = currentKey === viewKey; const iconKey = pickIconKeyFromNode(node, viewKey); const Icon = iconKey ? FALLBACK_ICONS[iconKey] : null; if (isDir) { return (
{open && children.length > 0 && (
{children.map((c) => ( ))}
)}
); } return ( ); } export function Sidebar({ currentView, setCurrentView, menus, onLogout }: SidebarProps) { const [labelingOpen, setLabelingOpen] = useState(true); const fallbackMenuItems = [ { name: 'Dashboard', icon: LayoutDashboard, type: 'item' }, { type: 'header', name: 'MODULES' }, { name: 'Labeling', icon: Tag, type: 'sub', isOpen: labelingOpen, toggle: () => setLabelingOpen(!labelingOpen), children: [ { name: 'Labels', icon: Tag }, { name: 'Label Categories', icon: Layers }, { name: 'Label Types', icon: Type }, { name: 'Label Templates', icon: FileBox }, { name: 'Multiple Option Sets', icon: Settings }, ] }, { type: 'header', name: 'MANAGEMENT' }, { name: 'Account Management', icon: Users, type: 'item' }, { name: 'Menu Management', icon: Package, type: 'item' }, { name: 'System Menu', icon: Settings, type: 'item' }, { name: 'Reports', icon: FileText, type: 'item' }, { name: 'Support', icon: HelpCircle, type: 'item' }, { name: 'Log Out', icon: LogOut, type: 'item' }, ]; const hasRemoteMenus = (menus?.length ?? 0) > 0; const logoutHandler = () => (onLogout ? onLogout() : setCurrentView("Log Out")); const remoteMenuNodes = useMemo(() => menus ?? [], [menus]); const { moduleMenus, accountMenus } = useMemo(() => { const ACCOUNT_LABELS = new Set([ "Location Manager", "Account Management", "Menu Management", "System Menu", "Reports", "Support", ]); const roots = remoteMenuNodes; const moduleMenus: CurrentUserMenuNodeDto[] = []; const accountMenus: CurrentUserMenuNodeDto[] = []; for (const n of roots) { const label = normalizeLabel(String(n.menuName ?? n.routerName ?? n.routeUrl ?? n.id ?? "")); if (label === "Management") { const children = n.children ?? []; for (const c of children) { const cl = normalizeLabel(String(c.menuName ?? c.routerName ?? c.routeUrl ?? c.id ?? "")); if (ACCOUNT_LABELS.has(cl)) accountMenus.push(c); else moduleMenus.push(c); } continue; } if (ACCOUNT_LABELS.has(label)) { accountMenus.push(n); continue; } moduleMenus.push(n); } return { moduleMenus, accountMenus }; }, [remoteMenuNodes]); return (
MedVantage
{hasRemoteMenus ? ( <>
MODULES
{moduleMenus.map((n) => ( ))}
MANAGEMENT
{accountMenus.map((n) => ( ))} ) : ( fallbackMenuItems.map((item, index) => { if (item.type === 'header') { return (
{item.name}
); } if (item.type === 'sub') { const Icon = item.icon; return (
{item.isOpen && (
{item.children?.map((child, childIndex) => ( ))}
)}
); } const Icon = item.icon; return ( ); }))}
); }