import { useEffect, useRef } from 'react' import { APP_VERSION } from '@/lib/version' import { Link, useRouterState } from '@tanstack/react-router' import { Monitor, Building2, Users, Settings, ChevronLeft, ChevronRight, Download, Terminal, FileCode, LayoutDashboard, ClipboardList, Wifi, BarChart3, MapPin, } from 'lucide-react' import { cn } from '@/lib/utils' import { useAuth, isSuperAdmin, isTenantAdmin } from '@/lib/auth' import { useUIStore } from '@/lib/store' import { RugLogo } from '@/components/brand/RugLogo' interface NavItem { label: string href: string icon: React.FC<{ className?: string }> exact?: boolean } interface NavSection { label: string items: NavItem[] visible: boolean } export function Sidebar() { const { user } = useAuth() const { sidebarCollapsed, toggleSidebar, mobileSidebarOpen, setMobileSidebarOpen } = useUIStore() const routerState = useRouterState() const currentPath = routerState.location.pathname // Mobile sidebar focus trap useEffect(() => { if (!mobileSidebarOpen) return const sidebar = document.getElementById('mobile-sidebar') if (!sidebar) return const focusable = sidebar.querySelectorAll('a, button, input') if (focusable.length) focusable[0].focus() function handleKeyDown(e: KeyboardEvent) { if (e.key === 'Escape') { setMobileSidebarOpen(false) return } if (e.key === 'Tab') { const els = sidebar!.querySelectorAll('a, button, input') const first = els[0] const last = els[els.length - 1] if (e.shiftKey && document.activeElement === first) { e.preventDefault() last.focus() } else if (!e.shiftKey && document.activeElement === last) { e.preventDefault() first.focus() } } } document.addEventListener('keydown', handleKeyDown) return () => document.removeEventListener('keydown', handleKeyDown) }, [mobileSidebarOpen, setMobileSidebarOpen]) const navRef = useRef(null) // Keyboard toggle: [ key collapses/expands sidebar useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if ( e.key === '[' && !['INPUT', 'TEXTAREA', 'SELECT'].includes( (e.target as HTMLElement).tagName, ) ) { e.preventDefault() toggleSidebar() } } document.addEventListener('keydown', handleKeyDown) return () => document.removeEventListener('keydown', handleKeyDown) }, [toggleSidebar]) const sections: NavSection[] = [ { label: 'Fleet', visible: true, items: [ { label: 'Overview', href: '/', icon: LayoutDashboard, exact: true, }, // Only show Devices for non-super_admin with a tenant_id ...(!isSuperAdmin(user) && user?.tenant_id ? [ { label: 'Devices', href: `/tenants/${user.tenant_id}/devices`, icon: Monitor, }, ] : []), ...(!isSuperAdmin(user) && user?.tenant_id ? [ { label: 'Sites', href: `/tenants/${user.tenant_id}/sites`, icon: MapPin, }, ] : []), ...(!isSuperAdmin(user) && user?.tenant_id ? [{ label: 'Wireless Links', href: `/tenants/${user.tenant_id}/wireless-links`, icon: Wifi, }] : [{ label: 'Wireless Links', href: '/wireless', icon: Wifi, }] ), { label: 'Traffic', href: '/traffic', icon: BarChart3, }, ], }, { label: 'Config', visible: true, items: [ { label: 'Editor', href: '/config-editor', icon: Terminal, }, { label: 'Templates', href: '/templates', icon: FileCode, }, { label: 'Firmware', href: '/firmware', icon: Download, }, ], }, { label: 'Admin', visible: isSuperAdmin(user) || isTenantAdmin(user), items: [ ...(isTenantAdmin(user) && user?.tenant_id ? [ { label: 'Users', href: `/tenants/${user.tenant_id}/users`, icon: Users, }, ] : []), ...(isSuperAdmin(user) || isTenantAdmin(user) ? [ { label: 'Organizations', href: '/tenants', icon: Building2, }, ] : []), { label: 'Audit Log', href: '/audit', icon: ClipboardList, }, { label: 'Settings', href: '/settings', icon: Settings, }, ], }, ] const visibleSections = sections.filter((s) => s.visible) const isActive = (item: NavItem) => { if (item.exact) return currentPath === item.href // Settings should only match exact to avoid catching everything if (item.href === '/settings') return currentPath === '/settings' || currentPath.startsWith('/settings/') return currentPath.startsWith(item.href) && item.href.length > 1 } const sidebarContent = (showCollapsed: boolean) => ( <> {/* Logo */}
{!showCollapsed && ( TOD )}
{/* Navigation */} {/* Version identifier */} {!showCollapsed && (
TOD {APP_VERSION}
)} {/* Collapse toggle (hidden on mobile) */} ) return ( <> {/* Desktop sidebar */} {/* Mobile overlay */} {mobileSidebarOpen && ( <>
setMobileSidebarOpen(false)} /> )} ) }