xpeditis2.0/apps/frontend/src/components/admin/AdminPanelDropdown.tsx
2026-02-03 16:08:00 +01:00

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>
);
}