70 lines
3.6 KiB
TypeScript
70 lines
3.6 KiB
TypeScript
// frontend/src/components/Layout/Navbar.tsx
|
|
|
|
import { Lock, LogOut, Volleyball } from 'lucide-react';
|
|
import { Link, useLocation } from 'react-router-dom';
|
|
import CourtIcon from '../../assets/court.svg?react';
|
|
|
|
interface NavbarProps {
|
|
title: string;
|
|
subtitle: string;
|
|
isAuthenticated: boolean;
|
|
onLogout: () => void;
|
|
}
|
|
|
|
export default function Navbar({ title, subtitle, isAuthenticated, onLogout }: NavbarProps) {
|
|
const location = useLocation();
|
|
|
|
return (
|
|
<nav className="bg-white dark:bg-zinc-900 border-b border-zinc-200 dark:border-zinc-800 px-4 py-3 flex items-center justify-between shadow-sm sticky top-0 z-50">
|
|
|
|
{/* Left: Logo & Main Navigation */}
|
|
<div className="flex items-center gap-6">
|
|
<Link to="/" className="flex items-center gap-2 shrink-0">
|
|
<div className="p-2 bg-orange-600 rounded-xl shadow-lg shadow-orange-600/20">
|
|
<Volleyball className="text-white" size={20} />
|
|
</div>
|
|
<div className="hidden lg:block">
|
|
<h1 className="text-lg font-black text-zinc-900 dark:text-white leading-none">VolleyManager</h1>
|
|
</div>
|
|
</Link>
|
|
<Link to="/courts" className="md:hidden p-2 text-zinc-600 dark:text-zinc-400 bg-zinc-100 hover:bg-zinc-300 dark:hover:bg-zinc-800 rounded-lg">
|
|
<CourtIcon width={20} height={20} />
|
|
</Link>
|
|
|
|
<div className="hidden md:flex items-center gap-1 bg-zinc-100 dark:bg-zinc-800 p-1 rounded-lg">
|
|
<Link to="/" className={`px-4 py-1.5 rounded-md text-xs font-black uppercase tracking-wider transition ${location.pathname === '/' ? 'bg-white dark:bg-zinc-700 shadow-sm text-orange-600' : 'text-zinc-500 hover:text-zinc-900 dark:hover:text-zinc-200'}`}>
|
|
Tournaments
|
|
</Link>
|
|
<Link to="/courts" className={`flex items-center gap-2 px-4 py-1.5 rounded-md text-xs font-black uppercase tracking-wider transition ${location.pathname === '/courts' ? 'bg-orange-600 text-white shadow-md' : 'text-zinc-500 hover:text-zinc-900 dark:hover:text-zinc-200'}`}>
|
|
Courts
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Center: Title (Responsive truncation) */}
|
|
<div className="absolute left-1/2 -translate-x-1/2 text-center hidden sm:block pointer-events-none">
|
|
<div className="font-black uppercase text-xs tracking-[0.2em] text-zinc-900 dark:text-white truncate max-w-37.5 md:max-w-62.5">
|
|
{title || 'Dashboard'}
|
|
</div>
|
|
{subtitle && (
|
|
<div className="text-[9px] font-bold text-zinc-400 uppercase tracking-widest mt-0.5">
|
|
{subtitle}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Right: Actions */}
|
|
<div className="flex items-center gap-3">
|
|
{isAuthenticated ? (
|
|
<button onClick={onLogout} className="p-2 text-zinc-400 hover:text-red-500 transition rounded-lg hover:bg-zinc-100 dark:hover:bg-zinc-800">
|
|
<LogOut size={20} />
|
|
</button>
|
|
) : (
|
|
<Link to="/login" className="flex items-center gap-2 px-4 py-2 bg-orange-50 dark:bg-orange-900/20 text-orange-600 dark:text-orange-400 rounded-lg text-xs font-black uppercase tracking-wider hover:bg-orange-100 transition">
|
|
<Lock size={14} /> Login
|
|
</Link>
|
|
)}
|
|
</div>
|
|
</nav>
|
|
);
|
|
} |