100 lines
3.4 KiB
TypeScript
100 lines
3.4 KiB
TypeScript
'use client'
|
|
|
|
import Link from 'next/link'
|
|
import { usePathname } from 'next/navigation'
|
|
import {
|
|
LayoutDashboard,
|
|
Car,
|
|
Calendar,
|
|
Users,
|
|
Tag,
|
|
UserPlus,
|
|
BarChart2,
|
|
CreditCard,
|
|
Settings,
|
|
LogOut,
|
|
} from 'lucide-react'
|
|
import { useClerk, useUser } from '@clerk/nextjs'
|
|
|
|
const NAV_ITEMS = [
|
|
{ href: '/dashboard', label: 'Dashboard', icon: LayoutDashboard, exact: true },
|
|
{ href: '/dashboard/fleet', label: 'Fleet', icon: Car },
|
|
{ href: '/dashboard/reservations', label: 'Reservations', icon: Calendar },
|
|
{ href: '/dashboard/customers', label: 'Customers', icon: Users },
|
|
{ href: '/dashboard/offers', label: 'Offers', icon: Tag },
|
|
{ href: '/dashboard/team', label: 'Team', icon: UserPlus },
|
|
{ href: '/dashboard/reports', label: 'Reports', icon: BarChart2 },
|
|
{ href: '/dashboard/billing', label: 'Billing', icon: CreditCard },
|
|
{ href: '/dashboard/settings', label: 'Settings', icon: Settings },
|
|
]
|
|
|
|
export default function Sidebar() {
|
|
const pathname = usePathname()
|
|
const { signOut } = useClerk()
|
|
const { user } = useUser()
|
|
|
|
const isActive = (item: typeof NAV_ITEMS[0]) => {
|
|
if (item.exact) return pathname === item.href
|
|
return pathname.startsWith(item.href)
|
|
}
|
|
|
|
return (
|
|
<aside className="fixed inset-y-0 left-0 w-64 bg-slate-900 flex flex-col z-40">
|
|
{/* Logo */}
|
|
<div className="flex items-center gap-3 px-6 py-5 border-b border-slate-800">
|
|
<div className="w-8 h-8 bg-blue-500 rounded-lg flex items-center justify-center">
|
|
<Car className="w-4 h-4 text-white" />
|
|
</div>
|
|
<span className="font-bold text-white text-sm tracking-wide">RentalDriveGo</span>
|
|
</div>
|
|
|
|
{/* Navigation */}
|
|
<nav className="flex-1 px-3 py-4 space-y-0.5 overflow-y-auto">
|
|
{NAV_ITEMS.map((item) => {
|
|
const Icon = item.icon
|
|
const active = isActive(item)
|
|
return (
|
|
<Link
|
|
key={item.href}
|
|
href={item.href}
|
|
className={[
|
|
'flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors',
|
|
active
|
|
? 'bg-blue-600 text-white'
|
|
: 'text-slate-400 hover:text-white hover:bg-slate-800',
|
|
].join(' ')}
|
|
>
|
|
<Icon className="w-4 h-4 flex-shrink-0" />
|
|
{item.label}
|
|
</Link>
|
|
)
|
|
})}
|
|
</nav>
|
|
|
|
{/* User menu */}
|
|
<div className="px-3 py-4 border-t border-slate-800">
|
|
<div className="flex items-center gap-3 px-3 py-2 rounded-lg">
|
|
<div className="w-8 h-8 rounded-full bg-blue-500 flex items-center justify-center text-white text-xs font-semibold flex-shrink-0">
|
|
{user?.firstName?.[0]?.toUpperCase() ?? 'U'}
|
|
</div>
|
|
<div className="flex-1 min-w-0">
|
|
<p className="text-sm font-medium text-white truncate">
|
|
{user?.firstName} {user?.lastName}
|
|
</p>
|
|
<p className="text-xs text-slate-400 truncate">
|
|
{user?.primaryEmailAddress?.emailAddress}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<button
|
|
onClick={() => signOut()}
|
|
className="mt-2 w-full flex items-center gap-3 px-3 py-2 text-sm text-slate-400 hover:text-white hover:bg-slate-800 rounded-lg transition-colors"
|
|
>
|
|
<LogOut className="w-4 h-4" />
|
|
Sign out
|
|
</button>
|
|
</div>
|
|
</aside>
|
|
)
|
|
}
|