81 lines
3.0 KiB
TypeScript
81 lines
3.0 KiB
TypeScript
'use client'
|
||
|
||
import Link from 'next/link'
|
||
import { usePathname } from 'next/navigation'
|
||
|
||
interface AdminSidebarProps {
|
||
userName?: string
|
||
}
|
||
|
||
export default function AdminSidebar({ userName }: AdminSidebarProps) {
|
||
const pathname = usePathname()
|
||
|
||
const isActive = (href: string) => {
|
||
// Exact match for dashboard
|
||
if (href === '/admin') {
|
||
return pathname === '/admin' || pathname === '/admin/analytics'
|
||
}
|
||
// For other routes, check if pathname starts with href
|
||
return pathname.startsWith(href)
|
||
}
|
||
|
||
const menuItems = [
|
||
{ href: '/admin', label: '📊 Dashboard', icon: '📊' },
|
||
{ href: '/admin/users', label: '👥 Users', icon: '👥' },
|
||
{ href: '/admin/webinars', label: '📹 Webinars', icon: '📹' },
|
||
{ href: '/admin/registrations', label: '📝 Registrations', icon: '📝' },
|
||
{ href: '/admin/contact-messages', label: '📧 Messages', icon: '📧' },
|
||
{ href: '/admin/setup', label: '⚙️ Setup', icon: '⚙️' },
|
||
]
|
||
|
||
return (
|
||
<aside className="w-64 bg-white dark:bg-slate-800 border-r border-gray-200 dark:border-slate-700 h-screen sticky top-0 overflow-y-auto shadow-sm">
|
||
<div className="p-6 border-b border-gray-200 dark:border-slate-700">
|
||
<div className="mb-8">
|
||
<div className="flex items-center gap-3 mb-3">
|
||
<div className="h-10 w-10 rounded-lg bg-gradient-to-br from-primary to-primary-dark text-white flex items-center justify-center font-bold text-lg">
|
||
⚙️
|
||
</div>
|
||
<h2 className="text-xl font-bold text-gray-900 dark:text-white">Admin</h2>
|
||
</div>
|
||
{userName && (
|
||
<p className="text-xs text-gray-600 dark:text-gray-400 font-medium">
|
||
👤 {userName}
|
||
</p>
|
||
)}
|
||
</div>
|
||
|
||
<nav className="space-y-1">
|
||
{menuItems.map((item) => {
|
||
const active = isActive(item.href);
|
||
return (
|
||
<Link
|
||
key={item.href}
|
||
href={item.href}
|
||
className={`flex items-center gap-3 px-4 py-2.5 rounded-lg transition-all duration-200 font-medium text-sm ${
|
||
active
|
||
? 'bg-primary text-white shadow-md'
|
||
: 'text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-slate-700'
|
||
}`}
|
||
>
|
||
<span className="text-base">{item.icon}</span>
|
||
<span>{item.label.split(' ')[1]}</span>
|
||
</Link>
|
||
);
|
||
})}
|
||
</nav>
|
||
</div>
|
||
|
||
<div className="absolute bottom-0 left-0 right-0 p-6 border-t border-gray-200 dark:border-slate-700 bg-gray-50 dark:bg-slate-800/50 backdrop-blur-sm">
|
||
<Link
|
||
href="/"
|
||
className="flex items-center justify-center gap-2 text-sm font-semibold text-gray-700 dark:text-gray-300 hover:text-primary transition-colors py-2"
|
||
>
|
||
<span>←</span>
|
||
<span>Back to Site</span>
|
||
</Link>
|
||
</div>
|
||
</aside>
|
||
)
|
||
}
|