138 lines
4.1 KiB
TypeScript
138 lines
4.1 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useRef, useEffect } from 'react';
|
|
import Link from 'next/link';
|
|
import { usePathname } from 'next/navigation';
|
|
import { Users, Building2, Package, FileText, BarChart3, Settings, type LucideIcon } from 'lucide-react';
|
|
|
|
interface AdminMenuItem {
|
|
name: string;
|
|
href: string;
|
|
icon: LucideIcon;
|
|
description: string;
|
|
}
|
|
|
|
const adminMenuItems: AdminMenuItem[] = [
|
|
{
|
|
name: 'Utilisateurs',
|
|
href: '/dashboard/admin/users',
|
|
icon: Users,
|
|
description: 'Gérer les utilisateurs et les permissions',
|
|
},
|
|
{
|
|
name: 'Organisations',
|
|
href: '/dashboard/admin/organizations',
|
|
icon: Building2,
|
|
description: 'Gérer les organisations et entreprises',
|
|
},
|
|
{
|
|
name: 'Réservations',
|
|
href: '/dashboard/admin/bookings',
|
|
icon: Package,
|
|
description: 'Consulter et gérer toutes les réservations',
|
|
},
|
|
{
|
|
name: 'Documents',
|
|
href: '/dashboard/admin/documents',
|
|
icon: FileText,
|
|
description: 'Gérer les documents des organisations',
|
|
},
|
|
{
|
|
name: 'Tarifs CSV',
|
|
href: '/dashboard/admin/csv-rates',
|
|
icon: BarChart3,
|
|
description: 'Importer et gérer les tarifs CSV',
|
|
},
|
|
];
|
|
|
|
export default function AdminPanelDropdown() {
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
const pathname = usePathname();
|
|
|
|
// Close dropdown when clicking outside
|
|
useEffect(() => {
|
|
function handleClickOutside(event: MouseEvent) {
|
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
|
|
setIsOpen(false);
|
|
}
|
|
}
|
|
|
|
if (isOpen) {
|
|
document.addEventListener('mousedown', handleClickOutside);
|
|
}
|
|
|
|
return () => {
|
|
document.removeEventListener('mousedown', handleClickOutside);
|
|
};
|
|
}, [isOpen]);
|
|
|
|
// Close dropdown when route changes
|
|
useEffect(() => {
|
|
setIsOpen(false);
|
|
}, [pathname]);
|
|
|
|
const isActiveRoute = adminMenuItems.some(item => pathname.startsWith(item.href));
|
|
|
|
return (
|
|
<div className="relative" ref={dropdownRef}>
|
|
{/* Trigger Button */}
|
|
<button
|
|
onClick={() => setIsOpen(!isOpen)}
|
|
className={`flex items-center w-full px-4 py-3 text-sm font-medium rounded-lg transition-colors ${
|
|
isActiveRoute
|
|
? 'bg-blue-50 text-blue-700'
|
|
: 'text-gray-700 hover:bg-gray-100'
|
|
}`}
|
|
>
|
|
<Settings className="mr-3 h-5 w-5" />
|
|
<span className="flex-1 text-left">Administration</span>
|
|
<svg
|
|
className={`w-4 h-4 transition-transform ${isOpen ? 'rotate-180' : ''}`}
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M19 9l-7 7-7-7"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
|
|
{/* Dropdown Menu */}
|
|
{isOpen && (
|
|
<div className="absolute left-0 right-0 mt-2 bg-white rounded-lg shadow-lg border border-gray-200 z-50 overflow-hidden">
|
|
<div className="py-2">
|
|
{adminMenuItems.map(item => {
|
|
const isActive = pathname.startsWith(item.href);
|
|
const IconComponent = item.icon;
|
|
return (
|
|
<Link
|
|
key={item.name}
|
|
href={item.href}
|
|
className={`flex items-start px-4 py-3 hover:bg-gray-50 transition-colors ${
|
|
isActive ? 'bg-blue-50' : ''
|
|
}`}
|
|
>
|
|
<IconComponent className="h-5 w-5 mr-3 mt-0.5 text-gray-500" />
|
|
<div className="flex-1">
|
|
<div className={`text-sm font-medium ${isActive ? 'text-blue-700' : 'text-gray-900'}`}>
|
|
{item.name}
|
|
</div>
|
|
<div className="text-xs text-gray-500 mt-0.5">
|
|
{item.description}
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|