"use client"; import React, { useState, useEffect, useMemo, useCallback, memo } from 'react'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; import { cn } from '@/lib/utils'; import { Users, LogOut, Menu, X, ChevronLeft, ChevronRight, ChevronDown, FileText, HelpCircle, LayoutDashboard, User, ClipboardList, FileBarChart, PenLine, Zap } from 'lucide-react'; interface SubNavigationItem { id: string; name: string; href: string; } interface NavigationItem { id: string; name: string; icon: React.ComponentType<{ className?: string }>; href: string; badge?: string; subItems?: SubNavigationItem[]; } interface EPDSidebarProps { className?: string; userEmail?: string; userName?: string; } // LEVEL 1: Behandelaar Context Navigation const level1NavigationItems: NavigationItem[] = [ { id: "cortex", name: "Cortex", icon: Zap, href: "/epd/cortex" }, { id: "clients", name: "Cliënten", icon: Users, href: "/epd/patients" }, { id: "verpleegrapportage", name: "Verpleegrapportage", icon: ClipboardList, href: "/epd/verpleegrapportage", subItems: [ { id: "rapportage", name: "Rapportage", href: "/epd/verpleegrapportage" }, { id: "overdracht", name: "Overdracht", href: "/epd/verpleegrapportage/overdracht" }, ] }, { id: "agenda", name: "Agenda", icon: FileText, href: "/epd/agenda" }, ]; // LEVEL 2: Client Dossier Context Navigation (clientId gets injected) const level2NavigationItems: NavigationItem[] = [ { id: "dashboard", name: "Dashboard", icon: LayoutDashboard, href: "" }, { id: "basisgegevens", name: "Basisgegevens", icon: User, href: "/basisgegevens" }, { id: "screening", name: "Screening", icon: ClipboardList, href: "/screening" }, { id: "intake", name: "Intake", icon: FileText, href: "/intakes" }, { id: "rapportage", name: "Rapportage", icon: FileBarChart, href: "/rapportage" }, ]; // Memoized sidebar item component to prevent unnecessary re-renders interface SidebarItemProps { item: NavigationItem; isActive: boolean; isCollapsed: boolean; onClick: () => void; } const SidebarItem = memo(function SidebarItem({ item, isActive, isCollapsed, onClick }: SidebarItemProps) { const Icon = item.icon; return (
  • {!isCollapsed && (
    {item.name} {item.badge && ( {item.badge} )}
    )} {/* Tooltip for collapsed state */} {isCollapsed && (
    {item.name}
    )}
  • ); }, (prev, next) => { // Custom comparison - only re-render if these props change return prev.item.href === next.item.href && prev.isActive === next.isActive && prev.isCollapsed === next.isCollapsed; }); // Sidebar item with expandable submenu interface SidebarItemWithSubmenuProps { item: NavigationItem; isActive: boolean; isCollapsed: boolean; onClick: () => void; pathname: string | null; } const SidebarItemWithSubmenu = memo(function SidebarItemWithSubmenu({ item, isActive, isCollapsed, onClick, pathname }: SidebarItemWithSubmenuProps) { const Icon = item.icon; // Check if any subitem is active const isSubItemActive = item.subItems?.some(sub => pathname === sub.href) || false; const isParentOrChildActive = isActive || isSubItemActive; // Auto-expand when a child is active const [isExpanded, setIsExpanded] = useState(isSubItemActive); // Update expanded state when route changes useEffect(() => { if (isSubItemActive) { setIsExpanded(true); } }, [isSubItemActive]); const handleToggle = (e: React.MouseEvent) => { e.preventDefault(); if (!isCollapsed) { setIsExpanded(prev => !prev); } }; return (
  • {/* Main menu item */} {/* Submenu items */} {!isCollapsed && isExpanded && item.subItems && ( )} {/* Collapsed state: show submenu on hover */} {isCollapsed && item.subItems && (
    {item.name}
    {item.subItems.map((subItem) => { const isSubActive = pathname === subItem.href; return ( {subItem.name} ); })}
    )}
  • ); }); export function EPDSidebar({ className = "", userEmail, userName }: EPDSidebarProps) { const pathname = usePathname(); const [isCollapsed, setIsCollapsed] = useState(false); const [isMobile, setIsMobile] = useState(false); const [isOpen, setIsOpen] = useState(false); // Context detection: Level 2 if URL contains /patients/[id] const isPatientContext = pathname?.match(/\/epd\/patients\/[^\/]+/); const patientId = isPatientContext ? pathname.split('/')[3] : null; // Memoize navigation items to prevent recreation on every render const navigationItems = useMemo(() => { if (isPatientContext) { return level2NavigationItems.map(item => ({ ...item, href: `/epd/patients/${patientId}${item.href}` })); } return level1NavigationItems; }, [isPatientContext, patientId]); const toggleCollapse = useCallback(() => { setIsCollapsed(prev => !prev); }, []); const toggleSidebar = useCallback(() => { setIsOpen(prev => !prev); }, []); const handleItemClick = useCallback(() => { if (isMobile) { setIsOpen(false); } }, [isMobile]); // Memoize isActive check function const getIsActive = useCallback((item: NavigationItem): boolean => { if (item.id === 'dashboard') { return pathname === item.href; } // For items with subItems, check if current path matches any subItem if (item.subItems) { return item.subItems.some(sub => pathname === sub.href || Boolean(pathname?.startsWith(sub.href + '/')) ); } return pathname === item.href || Boolean(item.href && pathname?.startsWith(item.href + '/')); }, [pathname]); // Track mobile state and auto-collapse on mobile useEffect(() => { const handleResize = () => { const mobile = window.innerWidth < 768; setIsMobile(mobile); // Auto-collapse on mobile, remember preference on desktop if (mobile) { setIsCollapsed(true); } }; handleResize(); window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); // Effective collapsed state: always collapsed on mobile const effectiveCollapsed = isMobile || isCollapsed; // Get user initials const userInitials = userName ? userName.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2) : userEmail?.slice(0, 2).toUpperCase() || 'EP'; return ( <> {/* Mobile hamburger button */} {/* Mobile overlay */} {isOpen && (
    )} {/* Sidebar */}
    {/* Header with logo and collapse button */}
    {!isCollapsed && (
    AI
    Mini-EPD Prototype
    )} {isCollapsed && ( AI )} {/* Desktop collapse button */}
    {/* Navigation */} {/* Bottom section with profile and logout */}
    {/* Profile Section */}
    {!isCollapsed ? (
    {userInitials}

    {userName || userEmail || 'Demo User'}

    {userEmail || 'demo@mini-epd.demo'}

    ) : (
    {userInitials}
    )}
    {/* Logout Button */}
    ); }