diff --git a/client/src/components/DashboardLayout.tsx b/client/src/components/DashboardLayout.tsx index 32bdc1f..9df67a0 100644 --- a/client/src/components/DashboardLayout.tsx +++ b/client/src/components/DashboardLayout.tsx @@ -21,7 +21,7 @@ import { } from "@/components/ui/sidebar"; import { APP_LOGO, APP_TITLE, getLoginUrl } from "@/const"; import { useIsMobile } from "@/hooks/useMobile"; -import { LayoutDashboard, LogOut, PanelLeft, Users, GraduationCap, Calendar, CalendarDays, Bell, BarChart3, UserCog, Mail, Settings, TrendingUp, Building2, FileSpreadsheet, ClipboardList } from "lucide-react"; +import { LayoutDashboard, LogOut, PanelLeft, Users, GraduationCap, Calendar, CalendarDays, Bell, BarChart3, UserCog, Mail, Settings, TrendingUp, Building2, FileSpreadsheet, ClipboardList, ChevronDown } from "lucide-react"; import { CSSProperties, useEffect, useRef, useState } from "react"; import { useLocation } from "wouter"; import { DashboardLayoutSkeleton } from './DashboardLayoutSkeleton'; @@ -159,6 +159,40 @@ function DashboardLayoutContent({ const sidebarRef = useRef(null); const activeMenuItem = menuSections.flatMap(section => section.items).find(item => item.path === location); const isMobile = useIsMobile(); + + // État pour gérer les sections ouvertes/fermées (accordéon) + const [openSections, setOpenSections] = useState>(() => { + // Par défaut, ouvrir toutes les sections + const initial: Record = {}; + menuSections.forEach(section => { + initial[section.title] = true; + }); + return initial; + }); + + // Fonction pour toggle une section + const toggleSection = (sectionTitle: string) => { + setOpenSections(prev => ({ + ...prev, + [sectionTitle]: !prev[sectionTitle] + })); + }; + + // S'assurer que la section contenant l'item actif est ouverte + useEffect(() => { + const activeSection = menuSections.find(section => + section.items.some(item => + item.path === location || + ('subItems' in item && item.subItems?.some((sub: any) => sub.path === location)) + ) + ); + if (activeSection && !openSections[activeSection.title]) { + setOpenSections(prev => ({ + ...prev, + [activeSection.title]: true + })); + } + }, [location]); useEffect(() => { if (isCollapsed) { @@ -244,61 +278,74 @@ function DashboardLayoutContent({ - {menuSections.map((section, sectionIndex) => ( -
- {sectionIndex > 0 && ( -
- )} -
-

- {section.title} -

-
- - {section.items.map(item => { - const isActive = location === item.path; - const hasSubItems = 'subItems' in item && item.subItems && item.subItems.length > 0; - const isSubItemActive = hasSubItems && item.subItems.some((sub: any) => location === sub.path); - return ( -
- - setLocation(item.path)} - tooltip={item.label} - className={`h-10 transition-all font-normal`} - > - - {item.label} - - - {hasSubItems && ( -
- {item.subItems.map((subItem: any) => { - const isSubActive = location === subItem.path; - return ( - - setLocation(subItem.path)} - tooltip={subItem.label} - className="h-9 text-sm font-normal" - > - {subItem.label} - - - ); - })} + {menuSections.map((section, sectionIndex) => { + const isOpen = openSections[section.title] ?? true; + return ( +
+ {sectionIndex > 0 && ( +
+ )} + + {isOpen && ( + + {section.items.map(item => { + const isActive = location === item.path; + const hasSubItems = 'subItems' in item && item.subItems && item.subItems.length > 0; + const isSubItemActive = hasSubItems && item.subItems.some((sub: any) => location === sub.path); + return ( +
+ + setLocation(item.path)} + tooltip={item.label} + className={`h-10 transition-all font-normal`} + > + + {item.label} + + + {hasSubItems && ( +
+ {item.subItems.map((subItem: any) => { + const isSubActive = location === subItem.path; + return ( + + setLocation(subItem.path)} + tooltip={subItem.label} + className="h-9 text-sm font-normal" + > + {subItem.label} + + + ); + })} +
+ )}
- )} -
- ); - })} - -
- ))} + ); + })} + + )} +
+ ); + })} diff --git a/todo.md b/todo.md index 22214fa..8d95127 100644 --- a/todo.md +++ b/todo.md @@ -139,3 +139,11 @@ - [x] Vérifier que les liens sont bien dans le menu DashboardLayout - [x] Ajouter la gestion des sous-menus dans DashboardLayout - [x] Tester l'accès aux pages /admin/rappels/historique et /admin/rappels/statistiques + +## Système plier/déplier pour le menu de navigation + +- [x] Ajouter un état pour gérer les sections ouvertes/fermées +- [x] Ajouter des icônes chevron pour indiquer l'état +- [x] Implémenter la logique de toggle pour chaque section +- [x] Garder la section active automatiquement ouverte +- [x] Tester le comportement sur toutes les sections