mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-21 05:58:23 +02:00
Organize navigation menu into logical sections for better user experience
Refactor the Sidebar component in client/src/components/Sidebar.tsx to group navigation links into sections like "GESTION PRINCIPALE", "LOGISTIQUE", and "ANALYSES" for improved UI organization. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 1e4433b5-47ab-464c-b663-fea2e53367dd Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: 1ca378ce-ae32-4181-ba52-5042a0f06d7a Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/1e4433b5-47ab-464c-b663-fea2e53367dd/oKSi9br
This commit is contained in:
1 parent
14b6e7c995
commit
b1c1e2989e
1 file changed
+183
-141
+183
-141
@@ -228,90 +228,110 @@ export default function Sidebar() {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const menuItems = [
|
const menuSections = [
|
||||||
{
|
{
|
||||||
path: "/dashboard",
|
title: "GESTION PRINCIPALE",
|
||||||
label: "Tableau de bord",
|
items: [
|
||||||
icon: BarChart3,
|
{
|
||||||
roles: ["admin", "directeur", "manager", "employee"]
|
path: "/dashboard",
|
||||||
|
label: "Tableau de bord",
|
||||||
|
icon: BarChart3,
|
||||||
|
roles: ["admin", "directeur", "manager", "employee"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/calendar",
|
||||||
|
label: "Calendrier",
|
||||||
|
icon: Calendar,
|
||||||
|
roles: ["admin", "directeur", "manager", "employee"]
|
||||||
|
},
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/calendar",
|
title: "LOGISTIQUE",
|
||||||
label: "Calendrier",
|
items: [
|
||||||
icon: Calendar,
|
{
|
||||||
roles: ["admin", "directeur", "manager", "employee"]
|
path: "/orders",
|
||||||
|
label: "Commandes",
|
||||||
|
icon: Package,
|
||||||
|
roles: ["admin", "directeur", "manager"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/deliveries",
|
||||||
|
label: "Livraisons",
|
||||||
|
icon: Truck,
|
||||||
|
roles: ["admin", "directeur", "manager"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/bl-reconciliation",
|
||||||
|
label: "Rapprochement",
|
||||||
|
icon: FileText,
|
||||||
|
roles: ["admin", "directeur"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/payment-schedule",
|
||||||
|
label: "Échéance",
|
||||||
|
icon: CreditCard,
|
||||||
|
roles: ["admin", "directeur"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/avoirs",
|
||||||
|
label: "Avoirs",
|
||||||
|
icon: Receipt,
|
||||||
|
roles: ["admin", "directeur", "manager"]
|
||||||
|
},
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/orders",
|
title: "ANALYSES",
|
||||||
label: "Commandes",
|
items: [
|
||||||
icon: Package,
|
{
|
||||||
roles: ["admin", "directeur", "manager"]
|
path: "/analytics",
|
||||||
|
label: "Statistiques",
|
||||||
|
icon: BarChart3,
|
||||||
|
roles: ["admin", "directeur", "manager"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/sales-analysis",
|
||||||
|
label: "Analyse Vente",
|
||||||
|
icon: TrendingUp,
|
||||||
|
roles: ["admin", "directeur"]
|
||||||
|
},
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/deliveries",
|
title: "OPÉRATIONS",
|
||||||
label: "Livraisons",
|
items: [
|
||||||
icon: Truck,
|
{
|
||||||
roles: ["admin", "directeur", "manager"]
|
path: "/publicities",
|
||||||
},
|
label: "Publicités",
|
||||||
{
|
icon: Megaphone,
|
||||||
path: "/bl-reconciliation",
|
roles: ["admin", "directeur", "manager", "employee"]
|
||||||
label: "Rapprochement",
|
},
|
||||||
icon: FileText,
|
{
|
||||||
roles: ["admin", "directeur"]
|
path: "/customer-orders",
|
||||||
},
|
label: "Commandes Client",
|
||||||
{
|
icon: ShoppingCart,
|
||||||
path: "/payment-schedule",
|
roles: ["admin", "directeur", "manager", "employee"]
|
||||||
label: "Échéance",
|
},
|
||||||
icon: CreditCard,
|
{
|
||||||
roles: ["admin", "directeur"]
|
path: "/dlc",
|
||||||
},
|
label: "Gestion DLC",
|
||||||
{
|
icon: Clock,
|
||||||
path: "/analytics",
|
roles: ["admin", "directeur", "manager", "employee"]
|
||||||
label: "Statistiques",
|
},
|
||||||
icon: BarChart3,
|
{
|
||||||
roles: ["admin", "directeur", "manager"]
|
path: "/tasks",
|
||||||
},
|
label: "Tâches",
|
||||||
{
|
icon: ListTodo,
|
||||||
path: "/sales-analysis",
|
roles: ["admin", "directeur", "manager", "employee"]
|
||||||
label: "Analyse Vente",
|
},
|
||||||
icon: TrendingUp,
|
{
|
||||||
roles: ["admin", "directeur"]
|
path: "/sav",
|
||||||
},
|
label: "SAV",
|
||||||
{
|
icon: Wrench,
|
||||||
path: "/avoirs",
|
roles: ["admin", "directeur", "manager", "employee"]
|
||||||
label: "Avoirs",
|
},
|
||||||
icon: Receipt,
|
]
|
||||||
roles: ["admin", "directeur", "manager"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/publicities",
|
|
||||||
label: "Publicités",
|
|
||||||
icon: Megaphone,
|
|
||||||
roles: ["admin", "directeur", "manager", "employee"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/customer-orders",
|
|
||||||
label: "Commandes Client",
|
|
||||||
icon: ShoppingCart,
|
|
||||||
roles: ["admin", "directeur", "manager", "employee"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/dlc",
|
|
||||||
label: "Gestion DLC",
|
|
||||||
icon: Clock,
|
|
||||||
roles: ["admin", "directeur", "manager", "employee"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/tasks",
|
|
||||||
label: "Tâches",
|
|
||||||
icon: ListTodo,
|
|
||||||
roles: ["admin", "directeur", "manager", "employee"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/sav",
|
|
||||||
label: "SAV",
|
|
||||||
icon: Wrench,
|
|
||||||
roles: ["admin", "directeur", "manager", "employee"]
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -558,70 +578,90 @@ export default function Sidebar() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Navigation */}
|
{/* Navigation */}
|
||||||
<nav className="flex-1 py-4 px-3">
|
<nav className="flex-1 py-5 px-3 overflow-y-auto">
|
||||||
<div className="space-y-1">
|
<div className="space-y-7">
|
||||||
{menuItems.map((item) => {
|
{menuSections.map((section, sectionIndex) => {
|
||||||
const hasRolePermission = hasPermission(item.roles);
|
// Vérifier si au moins un item de la section est accessible
|
||||||
// console.log(`🔍 Menu item ${item.path} (${item.label}):`, {
|
const hasAccessibleItems = section.items.some(item => hasPermission(item.roles));
|
||||||
// roles: item.roles,
|
if (!hasAccessibleItems) return null;
|
||||||
// hasPermission: hasRolePermission,
|
|
||||||
// userRole: user?.role
|
|
||||||
// });
|
|
||||||
|
|
||||||
if (!hasRolePermission) return null;
|
|
||||||
|
|
||||||
const Icon = item.icon;
|
|
||||||
const active = isActive(item.path);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link key={item.path} href={item.path}>
|
<div key={section.title} className="space-y-3">
|
||||||
<div
|
{/* Titre de section - caché en mode collapsed */}
|
||||||
className={`flex items-center transition-colors hover:bg-gray-100 ${
|
{!sidebarCollapsed && (
|
||||||
// Espacement adaptatif selon l'écran et l'état
|
<h3 className="px-3 mb-3 text-[11px] font-bold text-gray-500 uppercase tracking-widest">
|
||||||
sidebarCollapsed && !isMobile
|
{section.title}
|
||||||
? 'px-3 py-3 justify-center min-h-[44px]'
|
</h3>
|
||||||
: isMobileOrTablet
|
)}
|
||||||
? 'px-4 py-3 min-h-[48px]'
|
|
||||||
: 'px-3 py-2 min-h-[40px]'
|
{/* Séparateur visuel en mode collapsed */}
|
||||||
} text-sm font-medium ${
|
{sidebarCollapsed && sectionIndex > 0 && (
|
||||||
active
|
<div className="border-t border-gray-200 my-4"></div>
|
||||||
? 'bg-gray-100 text-gray-900 border-r-2 border-blue-600'
|
)}
|
||||||
: 'text-gray-700'
|
|
||||||
}`}
|
{/* Items du menu */}
|
||||||
title={sidebarCollapsed && !isMobile ? item.label : undefined}
|
<div className="space-y-1.5">
|
||||||
onClick={handleMenuClick}
|
{section.items.map((item) => {
|
||||||
>
|
const hasRolePermission = hasPermission(item.roles);
|
||||||
<Icon className={`${
|
|
||||||
// Tailles d'icônes adaptatives
|
if (!hasRolePermission) return null;
|
||||||
isMobile ? 'h-5 w-5' :
|
|
||||||
isTablet ? 'h-6 w-6' :
|
const Icon = item.icon;
|
||||||
'h-5 w-5'
|
const active = isActive(item.path);
|
||||||
} ${sidebarCollapsed && !isMobile ? '' : 'mr-3'}`} />
|
|
||||||
{(!sidebarCollapsed || isMobile) && (
|
return (
|
||||||
<span className={`${isMobileOrTablet ? 'text-base' : 'text-sm'} font-medium`}>
|
<Link key={item.path} href={item.path}>
|
||||||
{item.label}
|
<div
|
||||||
</span>
|
className={`flex items-center transition-colors hover:bg-gray-100 rounded-md ${
|
||||||
)}
|
// Espacement adaptatif selon l'écran et l'état
|
||||||
|
sidebarCollapsed && !isMobile
|
||||||
|
? 'px-3 py-3 justify-center min-h-11'
|
||||||
|
: isMobileOrTablet
|
||||||
|
? 'px-4 py-3.5 min-h-12'
|
||||||
|
: 'px-3 py-3 min-h-11'
|
||||||
|
} ${
|
||||||
|
active
|
||||||
|
? 'bg-blue-50 text-blue-700 border-r-2 border-blue-600'
|
||||||
|
: 'text-gray-700'
|
||||||
|
}`}
|
||||||
|
title={sidebarCollapsed && !isMobile ? item.label : undefined}
|
||||||
|
onClick={handleMenuClick}
|
||||||
|
>
|
||||||
|
<Icon className={`${
|
||||||
|
// Tailles d'icônes adaptatives
|
||||||
|
isMobile ? 'h-5 w-5' :
|
||||||
|
isTablet ? 'h-6 w-6' :
|
||||||
|
'h-5 w-5'
|
||||||
|
} ${
|
||||||
|
active ? 'text-blue-700' : 'text-gray-600'
|
||||||
|
} ${sidebarCollapsed && !isMobile ? '' : 'mr-3'}`} />
|
||||||
|
{(!sidebarCollapsed || isMobile) && (
|
||||||
|
<span className={`${isMobileOrTablet ? 'text-base' : 'text-[15px]'} font-medium`}>
|
||||||
|
{item.label}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
{/* Administration Section */}
|
{/* Administration Section */}
|
||||||
{adminItems.some(item => hasPermission(item.roles)) && (
|
{adminItems.some(item => hasPermission(item.roles)) && (
|
||||||
<div className="border-t border-gray-200 py-4 px-3">
|
<div className="border-t border-gray-200 py-5 px-3">
|
||||||
{!sidebarCollapsed && (
|
{!sidebarCollapsed && (
|
||||||
<div className="mb-2">
|
<div className="mb-3">
|
||||||
<h3 className="px-3 text-xs font-medium text-gray-500 uppercase tracking-wider">
|
<h3 className="px-3 text-[11px] font-bold text-gray-500 uppercase tracking-widest">
|
||||||
Administration
|
Administration
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="space-y-1">
|
<div className="space-y-1.5">
|
||||||
{adminItems.map((item) => {
|
{adminItems.map((item) => {
|
||||||
if (!hasPermission(item.roles)) return null;
|
if (!hasPermission(item.roles)) return null;
|
||||||
|
|
||||||
@@ -632,13 +672,13 @@ export default function Sidebar() {
|
|||||||
return (
|
return (
|
||||||
<div key={item.path}>
|
<div key={item.path}>
|
||||||
<div
|
<div
|
||||||
className={`flex items-center cursor-pointer transition-colors hover:bg-gray-100 text-gray-700 ${
|
className={`flex items-center cursor-pointer transition-colors hover:bg-gray-100 rounded-md ${
|
||||||
sidebarCollapsed && !isMobile
|
sidebarCollapsed && !isMobile
|
||||||
? 'px-3 py-3 justify-center min-h-[44px]'
|
? 'px-3 py-3 justify-center min-h-11'
|
||||||
: isMobileOrTablet
|
: isMobileOrTablet
|
||||||
? 'px-4 py-3 min-h-[48px]'
|
? 'px-4 py-3.5 min-h-12'
|
||||||
: 'px-3 py-2 min-h-[40px]'
|
: 'px-3 py-3 min-h-11'
|
||||||
} text-sm font-medium`}
|
} text-gray-700`}
|
||||||
title={sidebarCollapsed && !isMobile ? item.label : undefined}
|
title={sidebarCollapsed && !isMobile ? item.label : undefined}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setShowBapModal(true);
|
setShowBapModal(true);
|
||||||
@@ -649,9 +689,9 @@ export default function Sidebar() {
|
|||||||
isMobile ? 'h-5 w-5' :
|
isMobile ? 'h-5 w-5' :
|
||||||
isTablet ? 'h-6 w-6' :
|
isTablet ? 'h-6 w-6' :
|
||||||
'h-5 w-5'
|
'h-5 w-5'
|
||||||
} ${sidebarCollapsed && !isMobile ? '' : 'mr-3'}`} />
|
} text-gray-600 ${sidebarCollapsed && !isMobile ? '' : 'mr-3'}`} />
|
||||||
{(!sidebarCollapsed || isMobile) && (
|
{(!sidebarCollapsed || isMobile) && (
|
||||||
<span className={`${isMobileOrTablet ? 'text-base' : 'text-sm'} font-medium`}>
|
<span className={`${isMobileOrTablet ? 'text-base' : 'text-[15px]'} font-medium`}>
|
||||||
{item.label}
|
{item.label}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
@@ -663,27 +703,29 @@ export default function Sidebar() {
|
|||||||
return (
|
return (
|
||||||
<Link key={item.path} href={item.path}>
|
<Link key={item.path} href={item.path}>
|
||||||
<div
|
<div
|
||||||
className={`flex items-center transition-colors hover:bg-gray-100 ${
|
className={`flex items-center transition-colors hover:bg-gray-100 rounded-md ${
|
||||||
sidebarCollapsed && !isMobile
|
sidebarCollapsed && !isMobile
|
||||||
? 'px-3 py-3 justify-center min-h-[44px]'
|
? 'px-3 py-3 justify-center min-h-11'
|
||||||
: isMobileOrTablet
|
: isMobileOrTablet
|
||||||
? 'px-4 py-3 min-h-[48px]'
|
? 'px-4 py-3.5 min-h-12'
|
||||||
: 'px-3 py-2 min-h-[40px]'
|
: 'px-3 py-3 min-h-11'
|
||||||
} text-sm font-medium ${
|
} ${
|
||||||
active
|
active
|
||||||
? 'bg-gray-100 text-gray-900 border-r-2 border-blue-600'
|
? 'bg-blue-50 text-blue-700 border-r-2 border-blue-600'
|
||||||
: 'text-gray-700'
|
: 'text-gray-700'
|
||||||
}`}
|
}`}
|
||||||
title={sidebarCollapsed && !isMobile ? item.label : undefined}
|
title={sidebarCollapsed && !isMobile ? item.label : undefined}
|
||||||
onClick={() => console.log(`Navigating to admin: ${item.path}`)}
|
onClick={handleMenuClick}
|
||||||
>
|
>
|
||||||
<Icon className={`${
|
<Icon className={`${
|
||||||
isMobile ? 'h-5 w-5' :
|
isMobile ? 'h-5 w-5' :
|
||||||
isTablet ? 'h-6 w-6' :
|
isTablet ? 'h-6 w-6' :
|
||||||
'h-5 w-5'
|
'h-5 w-5'
|
||||||
|
} ${
|
||||||
|
active ? 'text-blue-700' : 'text-gray-600'
|
||||||
} ${sidebarCollapsed && !isMobile ? '' : 'mr-3'}`} />
|
} ${sidebarCollapsed && !isMobile ? '' : 'mr-3'}`} />
|
||||||
{(!sidebarCollapsed || isMobile) && (
|
{(!sidebarCollapsed || isMobile) && (
|
||||||
<span className={`${isMobileOrTablet ? 'text-base' : 'text-sm'} font-medium`}>
|
<span className={`${isMobileOrTablet ? 'text-base' : 'text-[15px]'} font-medium`}>
|
||||||
{item.label}
|
{item.label}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in new issue
Block a user