227 lines
9.2 KiB
React
227 lines
9.2 KiB
React
/* Hallmark · pre-emit critique: P5 H5 E5 S5 R5 V5 */
|
|
/* Hallmark · redesign: Navbar · studied-DNA: https://inihaus.de · nav: N1b Architectural Masthead */
|
|
import React from 'react';
|
|
import { Calendar, User, LogOut, Sparkles, Plus, Layers, Settings, Edit3, Home, CalendarDays, TableProperties, Sun, Moon, Monitor } from 'lucide-react';
|
|
|
|
export default function Navbar({
|
|
branding,
|
|
user,
|
|
activeTab,
|
|
onChangeTab,
|
|
themeMode,
|
|
onChangeThemeMode,
|
|
onLogout,
|
|
onOpenAuth,
|
|
onOpenCreateEvent,
|
|
onOpenTemplates,
|
|
onOpenProfile,
|
|
onOpenAdmin,
|
|
pwaInstallPrompt,
|
|
onInstallPwa
|
|
}) {
|
|
const primaryColor = branding?.primary_color || 'var(--brand-primary)';
|
|
|
|
const cycleTheme = () => {
|
|
if (themeMode === 'dark') onChangeThemeMode('light');
|
|
else if (themeMode === 'light') onChangeThemeMode('auto');
|
|
else onChangeThemeMode('dark');
|
|
};
|
|
|
|
return (
|
|
<header className="bg-surface border-b border-grid sticky top-0 z-40">
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between gap-4">
|
|
{/* Brand Section */}
|
|
<div className="flex items-center space-x-3 shrink-0">
|
|
<div
|
|
onClick={() => onChangeTab('home')}
|
|
style={{ backgroundColor: primaryColor }}
|
|
className="w-8 h-8 rounded-sm flex items-center justify-center text-white font-bold cursor-pointer shadow-sm"
|
|
>
|
|
{branding?.logo_url ? (
|
|
<img src={branding.logo_url} alt="Logo" className="w-4 h-4 object-contain" />
|
|
) : (
|
|
<Calendar className="w-4 h-4" />
|
|
)}
|
|
</div>
|
|
<div onClick={() => onChangeTab('home')} className="cursor-pointer">
|
|
<h1 className="font-serif text-base font-bold tracking-tight text-main leading-none">
|
|
{branding?.app_name || "Schichtplaner"}
|
|
</h1>
|
|
<div className="text-[10px] font-mono text-muted mt-1 uppercase tracking-wider flex items-center gap-1.5">
|
|
{user ? (
|
|
<span className="text-emerald-500 font-semibold">[ {user.display_name || user.username} ]</span>
|
|
) : (
|
|
<span className="text-amber-500 font-semibold">[ GAST-MODUS ]</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Center Navigation Tabs (Clean Hallmark N1b Style) */}
|
|
<nav className="hidden md:flex items-center gap-2">
|
|
<button
|
|
onClick={() => onChangeTab('home')}
|
|
className={`px-3 py-1.5 rounded-sm text-xs font-mono transition flex items-center gap-1.5 border ${
|
|
activeTab === 'home'
|
|
? 'bg-surface-hover text-main font-bold border-grid'
|
|
: 'text-muted hover:text-main border-transparent'
|
|
}`}
|
|
>
|
|
<Home className="w-3.5 h-3.5" /> Startseite
|
|
</button>
|
|
|
|
<button
|
|
onClick={() => onChangeTab('calendar')}
|
|
className={`px-3 py-1.5 rounded-sm text-xs font-mono transition flex items-center gap-1.5 border ${
|
|
activeTab === 'calendar'
|
|
? 'bg-surface-hover text-main font-bold border-grid'
|
|
: 'text-muted hover:text-main border-transparent'
|
|
}`}
|
|
>
|
|
<CalendarDays className="w-3.5 h-3.5" /> Kalender
|
|
</button>
|
|
|
|
{(user?.is_admin_user || user?.is_staff || user?.is_superuser) && (
|
|
<button
|
|
onClick={() => onChangeTab('admin')}
|
|
className={`px-3 py-1.5 rounded-sm text-xs font-mono transition flex items-center gap-1.5 border ${
|
|
activeTab === 'admin'
|
|
? 'bg-surface-hover text-main font-bold border-grid'
|
|
: 'text-muted hover:text-main border-transparent'
|
|
}`}
|
|
>
|
|
<Settings className="w-3.5 h-3.5 text-indigo-400" /> Admin
|
|
</button>
|
|
)}
|
|
</nav>
|
|
|
|
{/* Right Action Controls */}
|
|
<div className="flex items-center space-x-2">
|
|
{/* Theme Mode Button */}
|
|
<button
|
|
onClick={cycleTheme}
|
|
className="h-8 px-2.5 rounded-sm text-xs font-mono bg-subtle hover:bg-surface-hover text-main border border-grid transition flex items-center gap-1.5"
|
|
title={`Design-Modus: ${themeMode.toUpperCase()}`}
|
|
>
|
|
{themeMode === 'dark' ? (
|
|
<>
|
|
<Moon className="w-3.5 h-3.5 text-indigo-400" />
|
|
<span className="hidden lg:inline text-[11px] font-bold">DARK</span>
|
|
</>
|
|
) : themeMode === 'light' ? (
|
|
<>
|
|
<Sun className="w-3.5 h-3.5 text-amber-500" />
|
|
<span className="hidden lg:inline text-[11px] font-bold">LIGHT</span>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Monitor className="w-3.5 h-3.5 text-blue-500" />
|
|
<span className="hidden lg:inline text-[11px] font-bold">AUTO</span>
|
|
</>
|
|
)}
|
|
</button>
|
|
|
|
{pwaInstallPrompt && (
|
|
<button
|
|
onClick={onInstallPwa}
|
|
className="h-8 px-2.5 rounded-sm text-xs font-mono bg-emerald-500/10 text-emerald-500 border border-emerald-500/20 hover:bg-emerald-500/20 transition flex items-center gap-1"
|
|
>
|
|
<Sparkles className="w-3 h-3" /> PWA
|
|
</button>
|
|
)}
|
|
|
|
{user ? (
|
|
<>
|
|
<button
|
|
onClick={onOpenCreateEvent}
|
|
style={{ backgroundColor: primaryColor }}
|
|
className="h-8 px-3 rounded-sm text-xs font-mono font-bold text-white transition flex items-center gap-1 shadow-sm hover:brightness-110"
|
|
>
|
|
<Plus className="w-3.5 h-3.5" /> Event
|
|
</button>
|
|
|
|
<button
|
|
onClick={onOpenTemplates}
|
|
className="h-8 px-2.5 rounded-sm text-xs font-mono bg-subtle hover:bg-surface-hover text-main border border-grid transition hidden sm:flex items-center gap-1"
|
|
title="Vorlagen"
|
|
>
|
|
<Layers className="w-3.5 h-3.5 text-muted" /> Vorlagen
|
|
</button>
|
|
|
|
<button
|
|
onClick={onOpenProfile}
|
|
className="h-8 px-2.5 rounded-sm text-xs font-mono bg-subtle hover:bg-surface-hover text-main border border-grid transition flex items-center gap-1"
|
|
title="Profil & Namen ändern"
|
|
>
|
|
<Edit3 className="w-3.5 h-3.5 text-amber-500" /> Profil
|
|
</button>
|
|
|
|
{(user.is_admin_user || user.is_staff || user.is_superuser) && (
|
|
<button
|
|
onClick={() => onChangeTab('admin')}
|
|
className={`h-8 px-2.5 rounded-sm text-xs font-mono transition flex items-center gap-1 border ${
|
|
activeTab === 'admin'
|
|
? 'bg-indigo-500/20 text-indigo-300 border-indigo-500/40 font-bold'
|
|
: 'bg-indigo-500/10 hover:bg-indigo-500/20 text-indigo-400 border-indigo-500/30'
|
|
}`}
|
|
title="Admin-Zentrale"
|
|
>
|
|
<Settings className="w-3.5 h-3.5" /> Admin
|
|
</button>
|
|
)}
|
|
|
|
<div className="h-4 w-px bg-grid mx-1"></div>
|
|
|
|
<button
|
|
onClick={onLogout}
|
|
className="h-8 w-8 rounded-sm text-muted hover:text-red-500 hover:bg-red-500/10 border border-transparent hover:border-red-500/20 transition flex items-center justify-center"
|
|
title="Abmelden"
|
|
>
|
|
<LogOut className="w-3.5 h-3.5" />
|
|
</button>
|
|
</>
|
|
) : (
|
|
<button
|
|
onClick={onOpenAuth}
|
|
style={{ backgroundColor: primaryColor }}
|
|
className="h-8 px-3.5 rounded-sm text-xs font-mono font-bold text-white transition hover:brightness-110 flex items-center gap-1.5 shadow-sm"
|
|
>
|
|
<User className="w-3.5 h-3.5" /> Anmelden
|
|
</button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mobile Navigation */}
|
|
<div className="flex md:hidden items-center justify-around border-t border-grid py-2 bg-subtle text-xs font-mono">
|
|
<button
|
|
onClick={() => onChangeTab('home')}
|
|
className={`flex items-center gap-1 px-3 py-1.5 rounded-sm border ${
|
|
activeTab === 'home' ? 'text-main font-bold bg-surface border-grid' : 'text-muted border-transparent'
|
|
}`}
|
|
>
|
|
<Home className="w-3.5 h-3.5" /> Start
|
|
</button>
|
|
|
|
<button
|
|
onClick={() => onChangeTab('calendar')}
|
|
className={`flex items-center gap-1 px-3 py-1.5 rounded-sm border ${
|
|
activeTab === 'calendar' ? 'text-main font-bold bg-surface border-grid' : 'text-muted border-transparent'
|
|
}`}
|
|
>
|
|
<CalendarDays className="w-3.5 h-3.5" /> Termine
|
|
</button>
|
|
|
|
<button
|
|
onClick={() => onChangeTab('schedule')}
|
|
className={`flex items-center gap-1 px-3 py-1.5 rounded-sm border ${
|
|
activeTab === 'schedule' ? 'text-main font-bold bg-surface border-grid' : 'text-muted border-transparent'
|
|
}`}
|
|
>
|
|
<TableProperties className="w-3.5 h-3.5" /> Schichtplan
|
|
</button>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|