feat: implement Sidebar component including navigation, user details, logout, and BAP document upload with webhook integration.

This commit is contained in:
Michael committed 2025-12-08 09:12:45 +01:00
1 parent 9ec9cfcca3
commit 6b719fb111
1 file changed
+26 -35
+26 -35
View File
@@ -383,9 +383,8 @@ export default function Sidebar() {
// Classes responsives adaptées avec support tablette // Classes responsives adaptées avec support tablette
const getSidebarClasses = () => { const getSidebarClasses = () => {
if (isMobile) { if (isMobile) {
return `fixed inset-y-0 left-0 z-50 w-64 bg-white border-r border-gray-200 shadow-lg transform transition-transform duration-300 ease-in-out ${ return `fixed inset-y-0 left-0 z-50 w-64 bg-white border-r border-gray-200 shadow-lg transform transition-transform duration-300 ease-in-out ${mobileMenuOpen ? 'translate-x-0' : '-translate-x-full'
mobileMenuOpen ? 'translate-x-0' : '-translate-x-full' }`;
}`;
} }
// Mode tablette : semi-collapsed par défaut ou collapsed si forcé // Mode tablette : semi-collapsed par défaut ou collapsed si forcé
@@ -578,7 +577,7 @@ export default function Sidebar() {
</div> </div>
{/* Navigation */} {/* Navigation */}
<nav className="flex-1 py-2 px-3 overflow-y-hidden"> <nav className="flex-1 py-2 px-3 overflow-y-auto">
<div className="space-y-3"> <div className="space-y-3">
{menuSections.map((section, sectionIndex) => { {menuSections.map((section, sectionIndex) => {
// Vérifier si au moins un item de la section est accessible // Vérifier si au moins un item de la section est accessible
@@ -619,22 +618,20 @@ export default function Sidebar() {
: isMobileOrTablet : isMobileOrTablet
? 'px-4 py-2.5 min-h-10' ? 'px-4 py-2.5 min-h-10'
: 'px-3 py-2 min-h-9' : 'px-3 py-2 min-h-9'
} ${ } ${active
active
? 'bg-blue-50 text-blue-700 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={handleMenuClick} onClick={handleMenuClick}
> >
<Icon className={`${ <Icon className={`${
// Tailles d'icônes adaptatives // Tailles d'icônes adaptatives
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'
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-[15px]'} font-medium`}> <span className={`${isMobileOrTablet ? 'text-base' : 'text-[15px]'} font-medium`}>
{item.label} {item.label}
@@ -672,24 +669,22 @@ 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 rounded-md ${ className={`flex items-center cursor-pointer transition-colors hover:bg-gray-100 rounded-md ${sidebarCollapsed && !isMobile
sidebarCollapsed && !isMobile
? 'px-3 py-2 justify-center min-h-9' ? 'px-3 py-2 justify-center min-h-9'
: isMobileOrTablet : isMobileOrTablet
? 'px-4 py-2.5 min-h-10' ? 'px-4 py-2.5 min-h-10'
: 'px-3 py-2 min-h-9' : 'px-3 py-2 min-h-9'
} text-gray-700`} } text-gray-700`}
title={sidebarCollapsed && !isMobile ? item.label : undefined} title={sidebarCollapsed && !isMobile ? item.label : undefined}
onClick={() => { onClick={() => {
setShowBapModal(true); setShowBapModal(true);
if (isMobile) setMobileMenuOpen(false); if (isMobile) setMobileMenuOpen(false);
}} }}
> >
<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' } text-gray-600 ${sidebarCollapsed && !isMobile ? '' : 'mr-3'}`} />
} text-gray-600 ${sidebarCollapsed && !isMobile ? '' : 'mr-3'}`} />
{(!sidebarCollapsed || isMobile) && ( {(!sidebarCollapsed || isMobile) && (
<span className={`${isMobileOrTablet ? 'text-base' : 'text-[15px]'} font-medium`}> <span className={`${isMobileOrTablet ? 'text-base' : 'text-[15px]'} font-medium`}>
{item.label} {item.label}
@@ -703,27 +698,23 @@ 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 rounded-md ${ className={`flex items-center transition-colors hover:bg-gray-100 rounded-md ${sidebarCollapsed && !isMobile
sidebarCollapsed && !isMobile
? 'px-3 py-2 justify-center min-h-9' ? 'px-3 py-2 justify-center min-h-9'
: isMobileOrTablet : isMobileOrTablet
? 'px-4 py-2.5 min-h-10' ? 'px-4 py-2.5 min-h-10'
: 'px-3 py-2 min-h-9' : 'px-3 py-2 min-h-9'
} ${ } ${active
active
? 'bg-blue-50 text-blue-700 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={handleMenuClick} 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'}`} />
active ? 'text-blue-700' : 'text-gray-600'
} ${sidebarCollapsed && !isMobile ? '' : 'mr-3'}`} />
{(!sidebarCollapsed || isMobile) && ( {(!sidebarCollapsed || isMobile) && (
<span className={`${isMobileOrTablet ? 'text-base' : 'text-[15px]'} font-medium`}> <span className={`${isMobileOrTablet ? 'text-base' : 'text-[15px]'} font-medium`}>
{item.label} {item.label}
@@ -870,7 +861,7 @@ export default function Sidebar() {
</Dialog> </Dialog>
{/* Modal d'attente */} {/* Modal d'attente */}
<Dialog open={showWaitingModal} onOpenChange={() => {}}> <Dialog open={showWaitingModal} onOpenChange={() => { }}>
<DialogContent className="sm:max-w-md"> <DialogContent className="sm:max-w-md">
<DialogHeader> <DialogHeader>
<DialogTitle className="flex items-center gap-2"> <DialogTitle className="flex items-center gap-2">
@@ -911,8 +902,8 @@ export default function Sidebar() {
</p> </p>
<p className="text-xs text-gray-500 truncate"> <p className="text-xs text-gray-500 truncate">
{user?.role === 'admin' ? 'Administrateur' : {user?.role === 'admin' ? 'Administrateur' :
user?.role === 'manager' ? 'Manager' : user?.role === 'manager' ? 'Manager' :
user?.role === 'directeur' ? 'Directeur' : 'Employé'} user?.role === 'directeur' ? 'Directeur' : 'Employé'}
</p> </p>
</div> </div>
</div> </div>