136 lines
3.9 KiB
TypeScript
136 lines
3.9 KiB
TypeScript
'use client';
|
||
|
||
import { useState, useRef, useEffect } from 'react';
|
||
import Link from 'next/link';
|
||
import { usePathname } from 'next/navigation';
|
||
|
||
interface AdminMenuItem {
|
||
name: string;
|
||
href: string;
|
||
icon: string;
|
||
description: string;
|
||
}
|
||
|
||
const adminMenuItems: AdminMenuItem[] = [
|
||
{
|
||
name: 'Users',
|
||
href: '/dashboard/admin/users',
|
||
icon: '👥',
|
||
description: 'Manage users and permissions',
|
||
},
|
||
{
|
||
name: 'Organizations',
|
||
href: '/dashboard/admin/organizations',
|
||
icon: '🏢',
|
||
description: 'Manage organizations and companies',
|
||
},
|
||
{
|
||
name: 'Bookings',
|
||
href: '/dashboard/admin/bookings',
|
||
icon: '📦',
|
||
description: 'View and manage all bookings',
|
||
},
|
||
{
|
||
name: 'Documents',
|
||
href: '/dashboard/admin/documents',
|
||
icon: '📄',
|
||
description: 'Manage organization documents',
|
||
},
|
||
{
|
||
name: 'CSV Rates',
|
||
href: '/dashboard/admin/csv-rates',
|
||
icon: '📊',
|
||
description: 'Upload and manage CSV rates',
|
||
},
|
||
];
|
||
|
||
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'
|
||
}`}
|
||
>
|
||
<span className="mr-3 text-xl">⚙️</span>
|
||
<span className="flex-1 text-left">Admin Panel</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);
|
||
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' : ''
|
||
}`}
|
||
>
|
||
<span className="text-2xl mr-3 mt-0.5">{item.icon}</span>
|
||
<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>
|
||
);
|
||
}
|