'use client'; import { useEffect, useState, type ComponentType } from 'react'; import Link from 'next/link'; import { usePathname, useRouter } from 'next/navigation'; import { parseJwt, getAccessToken } from '@/services/api/client'; import { LayoutDashboard, Users, Shield, ChevronLeft, ChevronDown, Wrench, Package, Megaphone, Warehouse, Receipt, } from 'lucide-react'; import { cn } from '@/lib/utils'; interface SidebarProps { collapsed: boolean; onToggle: () => void; overlay?: boolean; } type NavChild = { name: string; href: string }; type NavGroup = { name: string; icon: ComponentType<{ className?: string }>; children: NavChild[]; }; const NAV_GROUPS: NavGroup[] = [ { name: 'Dashboard', icon: LayoutDashboard, children: [ { name: 'Main Dashboard', href: '/dashboard' }, { name: 'Product Dashboard', href: '/products/dashboard' }, ], }, { name: 'Catalog Management', icon: Package, children: [ { name: 'Product Categories', href: '/categories' }, { name: 'Brands', href: '/brands' }, { name: 'Device Series', href: '/series' }, { name: 'Device Models', href: '/models' }, { name: 'Products', href: '/products' }, { name: 'Master Attributes', href: '/attributes' }, { name: 'Bulk Product Import', href: '/migration' }, ], }, { name: 'Marketing', icon: Megaphone, children: [ { name: 'Homepage Layout', href: '/storefront-sections' }, { name: 'Storefront CMS', href: '/storefront-cms' }, { name: 'Customer Reviews', href: '/reviews-moderation' }, ], }, { name: 'Inventory and Purchase', icon: Warehouse, children: [ { name: 'Stock Ledger', href: '/inventory' }, { name: 'Supplier Purchase Orders', href: '/purchases' }, ], }, { name: 'Sales and Billings', icon: Receipt, children: [ { name: 'Customer Store Orders', href: '/orders' }, { name: 'Sales Invoices', href: '/invoices' }, { name: 'POS Synchronization', href: '/pos-sync' }, ], }, { name: 'Repair and Services', icon: Wrench, children: [ { name: 'Service Catalog Manager', href: '/service-catalog' }, { name: 'Service Jobs Queue', href: '/services' }, { name: 'Walk-In Device Queue', href: '/services/intake' }, { name: 'Technician Workspace', href: '/technician' }, { name: 'Service Quotations', href: '/service-quotes' }, { name: 'Service Invoices', href: '/service-invoices' }, ], }, { name: 'User Management', icon: Users, children: [ { name: 'Manage Users', href: '/users' }, { name: 'E-Commerce Customers', href: '/customers' }, { name: 'Roles & Permissions', href: '/roles' }, { name: 'Staff Directory', href: '/staff-directory' }, { name: 'User Activity Logs', href: '/activity-logs' }, ], }, { name: 'System Infrastructure', icon: Shield, children: [ { name: 'Security & Sessions', href: '/security' }, { name: 'System Settings', href: '/settings' }, ], }, ]; function pathMatches(href: string, pathname: string) { if (pathname === href) return true; if (href === '/products' && pathname.startsWith('/products/') && pathname !== '/products/dashboard') { return true; } if (href === '/services' && pathname.startsWith('/services/') && !pathname.startsWith('/services/intake')) { return true; } return false; } function groupHasActive(group: NavGroup, pathname: string) { return group.children.some((child) => pathMatches(child.href, pathname)); } export function Sidebar({ collapsed, onToggle, overlay = false }: SidebarProps) { const pathname = usePathname(); const router = useRouter(); const [userRole, setUserRole] = useState(''); const [openGroups, setOpenGroups] = useState([]); useEffect(() => { const token = getAccessToken(); if (token) { const payload = parseJwt(token); if (payload) { setUserRole(((payload.role as string) || '').toLowerCase()); } } }, []); const isSuperAdmin = userRole === 'super admin' || userRole === 'super_admin' || userRole === 'superadmin'; const isAdmin = userRole === 'admin' || isSuperAdmin; const groups = NAV_GROUPS.filter((group) => { if (group.name === 'System Infrastructure') return isSuperAdmin; if (group.name === 'User Management') return isAdmin; return true; }).map((group) => { if (group.name !== 'System Infrastructure') return group; return { ...group, children: group.children.filter((item) => { if (item.name === 'System Settings') return isSuperAdmin; return isSuperAdmin; }), }; }); useEffect(() => { const active = groups.find((group) => groupHasActive(group, pathname)); if (active) { setOpenGroups((current) => (current.includes(active.name) ? current : [...current, active.name])); } }, [pathname, userRole]); useEffect(() => { groups.forEach((group) => { if (!openGroups.includes(group.name)) return; group.children.forEach((child) => { router.prefetch(child.href); }); }); }, [openGroups, userRole, router]); useEffect(() => { const prefetchAll = () => { groups.forEach((group) => { group.children.forEach((child) => router.prefetch(child.href)); }); }; const idle = window.requestIdleCallback?.(prefetchAll); if (idle) { return () => window.cancelIdleCallback(idle); } const timeout = window.setTimeout(prefetchAll, 1000); return () => window.clearTimeout(timeout); }, [userRole, router]); const toggleGroup = (name: string) => { if (collapsed) { onToggle(); setOpenGroups((current) => (current.includes(name) ? current : [...current, name])); return; } setOpenGroups((current) => current.includes(name) ? current.filter((item) => item !== name) : [...current, name] ); }; return ( ); }