import { ReactNode, useState, useEffect, useRef } from 'react'; import { Link, useLocation } from '@remix-run/react'; import { useFocusTrap } from '~/hooks/useFocusTrap'; import { designTokens } from '~/lib/design-tokens'; interface SidebarProps { isCollapsed: boolean; onToggle: () => void; isMobile: boolean; isOpen: boolean; onClose: () => void; userAuthLevel: number; } interface NavigationItem { name: string; href: string; icon: ReactNode; authLevel?: number; // Minimum auth level required } const navigationItems: NavigationItem[] = [ { name: 'لوحة التحكم', href: '/dashboard', icon: ( ), }, { name: 'العملاء', href: '/customers', icon: ( ), }, { name: 'المركبات', href: '/vehicles', icon: ( ), }, { name: 'زيارات الصيانة', href: '/maintenance-visits', icon: ( ), }, { name: 'المصروفات', href: '/expenses', icon: ( ), authLevel: 2, // Admin and above }, { name: 'التقارير المالية', href: '/financial-reports', icon: ( ), authLevel: 2, // Admin and above }, { name: 'إدارة المستخدمين', href: '/users', icon: ( ), authLevel: 2, // Admin and above }, { name: 'إعدادات النظام', href: '/settings', icon: ( ), authLevel: 2, // Admin and above }, ]; export function Sidebar({ isCollapsed, onToggle, isMobile, isOpen, onClose, userAuthLevel }: SidebarProps) { const location = useLocation(); const sidebarRef = useRef(null); const [announcement, setAnnouncement] = useState(''); const [isClient, setIsClient] = useState(false); // Set client-side flag useEffect(() => { setIsClient(true); }, []); // Filter navigation items based on user auth level const filteredNavItems = navigationItems.filter(item => !item.authLevel || userAuthLevel <= item.authLevel ); // Enable focus trap for mobile menu when open useFocusTrap(sidebarRef, isOpen && isClient); // Close sidebar on route change useEffect(() => { if (isOpen) { onClose(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [location.pathname]); // Handle Escape key to close mobile menu useEffect(() => { if (!isClient) return; const handleEscape = (e: KeyboardEvent) => { if (e.key === 'Escape' && isOpen) { onClose(); setAnnouncement('القائمة مغلقة'); } }; document.addEventListener('keydown', handleEscape); return () => document.removeEventListener('keydown', handleEscape); }, [isOpen, onClose, isClient]); // Announce menu state changes for screen readers useEffect(() => { if (isOpen && isClient) { setAnnouncement('القائمة مفتوحة'); } }, [isOpen, isClient]); // Render both mobile and desktop sidebars, use CSS to show/hide return ( <> {/* Screen reader announcement */}
{announcement}
{/* Mobile overlay - only show on mobile/tablet */} {isOpen && (