Files
edr-platform/apps/edr-passenger-web/backoffice/src/components/layout/Sidebar.tsx
2026-06-09 15:22:27 +03:00

192 lines
6.3 KiB
TypeScript

'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { useState } from 'react';
import {
LayoutDashboard,
Ticket,
Users,
Route,
DollarSign,
Bell,
BarChart3,
Settings,
LogOut,
ChevronLeft,
ChevronRight,
Train,
MapPin,
CreditCard,
Shield,
UserCheck,
Wallet,
Gift,
MessageSquare,
AlertTriangle,
FileText,
Briefcase,
Calendar,
Utensils,
Package,
Moon,
Sun,
Armchair,
Grid3x3
} from 'lucide-react';
import { useAuthStore } from '@/lib/auth-store';
import { cn } from '@/lib/utils';
import { useTheme } from '@/lib/theme-store';
const navigationSections = [
{
title: 'Overview',
items: [
{ name: 'Dashboard', href: '/dashboard', icon: LayoutDashboard },
]
},
{
title: 'Operations',
items: [
{ name: 'Bookings', href: '/bookings', icon: Ticket },
{ name: 'Passengers', href: '/passengers', icon: Users },
{ name: 'Tickets', href: '/tickets', icon: FileText },
]
},
{
title: 'Master Data',
items: [
{ name: 'Stations', href: '/stations', icon: MapPin },
{ name: 'Trains', href: '/trains', icon: Train },
{ name: 'Coaches', href: '/coaches', icon: Grid3x3 },
{ name: 'Seats', href: '/seats', icon: Armchair },
{ name: 'Classes', href: '/classes', icon: Settings },
{ name: 'Routes', href: '/routes', icon: Route },
{ name: 'Schedules', href: '/schedules', icon: Calendar },
]
},
{
title: 'Financial',
items: [
{ name: 'Pricing & Fares', href: '/pricing', icon: DollarSign },
{ name: 'Payments', href: '/payments', icon: CreditCard },
{ name: 'Promo Codes', href: '/promos', icon: Gift },
]
},
{
title: 'Customer Services',
items: [
{ name: 'Loyalty Program', href: '/loyalty', icon: Gift },
{ name: 'Support Center', href: '/support', icon: MessageSquare },
{ name: 'Notifications', href: '/notifications', icon: Bell },
{ name: 'Food & Dining', href: '/food', icon: Utensils },
]
},
{
title: 'Security & Compliance',
items: [
{ name: 'Fraud Detection', href: '/fraud', icon: Shield },
{ name: 'Verifayda Integration', href: '/verifayda', icon: UserCheck },
{ name: 'Audit Logs', href: '/audit', icon: AlertTriangle },
]
},
{
title: 'Analytics & Reports',
items: [
{ name: 'Reports', href: '/reports', icon: BarChart3 },
{ name: 'Operational Reports', href: '/operational-reports', icon: FileText },
]
},
{
title: 'System',
items: [
{ name: 'Agent Operations', href: '/agents', icon: Briefcase },
{ name: 'User Management', href: '/settings/users', icon: Users },
{ name: 'Settings', href: '/settings', icon: Settings },
]
}
];
export default function Sidebar() {
const pathname = usePathname();
const { user, logout } = useAuthStore();
const { isDark, toggleTheme } = useTheme();
const [isCollapsed, setIsCollapsed] = useState(false);
return (
<div className={cn(
'flex h-screen flex-col transition-all duration-300',
'bg-[rgb(20,113,76)] dark:bg-gradient-to-b dark:from-slate-900 dark:via-slate-800 dark:to-slate-900',
'border-r border-[rgb(16,90,61)] dark:border-slate-700/50',
isCollapsed ? 'w-16' : 'w-72'
)}>
{/* Header */}
<div className="flex h-16 items-center justify-between px-4 border-b border-[rgb(16,90,61)] dark:border-slate-700/50">
{!isCollapsed && (
<div className="flex items-center gap-3">
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-white/10 shadow-lg">
<Train className="h-6 w-6 text-white" />
</div>
<div>
<h1 className="text-lg font-bold text-white">EDR</h1>
<p className="text-xs text-white/70">Back-office Passenger Portal</p>
</div>
</div>
)}
<button
onClick={() => setIsCollapsed(!isCollapsed)}
className="rounded-lg p-1.5 text-white/70 hover:bg-white/10 hover:text-white dark:text-slate-400 dark:hover:bg-slate-700/50 dark:hover:text-white transition-colors"
>
{isCollapsed ? <ChevronRight className="h-4 w-4" /> : <ChevronLeft className="h-4 w-4" />}
</button>
</div>
{/* Navigation */}
<nav className="flex-1 overflow-y-auto px-3 py-4 space-y-6">
{navigationSections.map((section) => (
<div key={section.title}>
{!isCollapsed && (
<h3 className="mb-2 px-3 text-xs font-semibold uppercase tracking-wider text-white/60 dark:text-slate-400">
{section.title}
</h3>
)}
<div className="space-y-1">
{section.items.map((item) => {
// Special handling for Settings to avoid conflict with User Management
let isActive;
if (item.href === '/settings') {
// Settings is active only for exact match or non-users sub-routes
isActive = pathname === '/settings' ||
(pathname?.startsWith('/settings/') && !pathname.startsWith('/settings/users'));
} else {
// Standard matching for other items
isActive = pathname === item.href || pathname?.startsWith(item.href + '/');
}
return (
<Link
key={item.name}
href={item.href}
className={cn(
'flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-all duration-200',
'hover:bg-white/10 dark:hover:bg-slate-700/50',
isActive
? 'bg-white/20 text-white shadow-md hover:bg-white/25'
: 'text-white/80 hover:text-white dark:text-slate-300 dark:hover:text-white',
isCollapsed && 'justify-center'
)}
title={isCollapsed ? item.name : undefined}
>
<item.icon className="h-5 w-5 flex-shrink-0" />
{!isCollapsed && <span>{item.name}</span>}
</Link>
);
})}
</div>
</div>
))}
</nav>
</div>
);
}