Files
catalogue_frontend/src/components/NavigationHeader.jsx
2026-08-12 16:33:39 +05:30

189 lines
7.9 KiB
JavaScript

import React from 'react';
import { Link, useLocation, useNavigate } from 'react-router-dom';
import { Home, Store, BarChart3, HeartPulse, Wrench, ShoppingBag, AlertTriangle, UserCheck, ShieldCheck, LogOut, LayoutGrid } from 'lucide-react';
import { useAuth } from '../context/useAuth';
export function NavigationHeader({
title,
subtitle,
icon: TitleIcon,
health,
onResetHome,
children,
}) {
const location = useLocation();
const path = location.pathname;
const search = location.search;
const navigate = useNavigate();
const { user, role, logout } = useAuth();
const handleLogout = () => {
logout();
navigate('/login');
};
const getRoleBadge = () => {
if (role === 'admin') {
return (
<span className="inline-flex items-center gap-1 rounded-full bg-amber-500/15 border border-amber-500/30 px-2.5 py-0.5 text-[11px] font-bold text-amber-600">
<ShieldCheck className="h-3 w-3" /> Admin
</span>
);
}
return (
<span className="inline-flex items-center gap-1 rounded-full bg-blue-500/15 border border-blue-500/30 px-2.5 py-0.5 text-[11px] font-bold text-blue-600">
<UserCheck className="h-3 w-3" /> User
</span>
);
};
return (
<header className="sticky top-0 z-30 flex flex-col gap-3 border-b border-ink-900/10 bg-paper-50/95 px-6 py-3.5 backdrop-blur-md transition-all shadow-xs">
<div className="flex items-center justify-between gap-4 flex-wrap">
{/* Left Section: Home/Back Button + Page Title */}
<div className="flex items-center gap-3">
<Link
to={role === 'admin' ? '/' : '/user'}
onClick={() => {
if (onResetHome) onResetHome();
}}
title={role === 'admin' ? 'Navigate to Catalog' : 'Navigate to User Workspace'}
className="group flex items-center gap-2 rounded-full bg-gradient-to-r from-amber-500 to-amber-600 hover:from-amber-600 hover:to-amber-700 text-white px-4 py-2 text-xs font-semibold shadow-sm transition-all duration-200 active:scale-95 hover:shadow-md"
>
<Home className="h-4 w-4 transition-transform group-hover:-translate-x-0.5" />
<span>{role === 'admin' ? 'Home / Catalog' : 'Home / Workspace'}</span>
</Link>
{title && (
<div className="flex items-center gap-2.5 border-l border-ink-900/15 pl-4 py-0.5">
{TitleIcon && (
<div className="flex h-7 w-7 items-center justify-center rounded-lg bg-ink-900/5 text-ink-900">
<TitleIcon className="h-4 w-4" />
</div>
)}
<div>
<h1 className="font-display text-sm font-bold text-ink-950 flex items-center gap-1.5">
{title}
</h1>
{subtitle && <p className="text-[11px] text-slate-400 font-normal leading-tight">{subtitle}</p>}
</div>
</div>
)}
</div>
{/* Right Section: System Health + Role-Based Nav Tabs + Logout Button */}
<div className="flex items-center gap-3">
{health && health.status !== 'ok' && (
<span className="flex items-center gap-1.5 rounded-full bg-maroon-100 px-3 py-1 text-xs font-medium text-maroon-600">
<AlertTriangle className="h-3.5 w-3.5" />
{!health.database && !health.ollama
? 'DB & Ollama offline'
: !health.database
? 'Database offline'
: 'Ollama offline'}
</span>
)}
{/* User Role Profile Badge */}
<div className="flex items-center gap-2 rounded-full border border-slate-200 bg-white px-3 py-1.5 text-xs shadow-2xs">
<span className="font-bold text-slate-800">{user?.display_name || user?.username || 'Guest'}</span>
{getRoleBadge()}
</div>
{/* Role-tailored Navigation Tabs */}
<nav className="flex items-center gap-1 rounded-full bg-ink-100/90 p-1 text-xs font-medium backdrop-blur">
{/* Catalog tab ONLY visible to Admin role */}
{role === 'admin' && (
<Link
to="/"
onClick={() => {
if (onResetHome) onResetHome();
}}
className={`flex items-center gap-1.5 rounded-full px-3.5 py-1.5 transition-all ${
path === '/' ? 'bg-ink-950 text-paper-100 shadow-sm font-semibold' : 'text-slate-600 hover:text-ink-950 hover:bg-white/60'
}`}
>
<ShoppingBag className="h-3.5 w-3.5" /> Catalog
</Link>
)}
{/* User Upload tab */}
<Link
to="/user"
className={`flex items-center gap-1.5 rounded-full px-3.5 py-1.5 transition-all ${
path === '/user' && !search.includes('tab=cards') ? 'bg-ink-950 text-paper-100 shadow-sm font-semibold' : 'text-slate-600 hover:text-ink-950 hover:bg-white/60'
}`}
>
<UserCheck className="h-3.5 w-3.5 text-blue-400" /> User Upload
</Link>
{/* Product Cards tab for User role */}
<Link
to="/user?tab=cards"
className={`flex items-center gap-1.5 rounded-full px-3.5 py-1.5 transition-all ${
path === '/user' && search.includes('tab=cards') ? 'bg-amber-500 text-slate-950 font-bold shadow-sm' : 'text-slate-600 hover:text-ink-950 hover:bg-white/60'
}`}
>
<LayoutGrid className="h-3.5 w-3.5 text-amber-600" /> Product Cards
</Link>
{/* Stores tab */}
<Link
to="/stores"
className={`flex items-center gap-1.5 rounded-full px-3.5 py-1.5 transition-all ${
path === '/stores' ? 'bg-ink-950 text-paper-100 shadow-sm font-semibold' : 'text-slate-600 hover:text-ink-950 hover:bg-white/60'
}`}
>
<Store className="h-3.5 w-3.5 text-emerald-400" /> Stores
</Link>
{/* Analytics tab */}
<Link
to="/analytics"
className={`flex items-center gap-1.5 rounded-full px-3.5 py-1.5 transition-all ${
path === '/analytics' ? 'bg-ink-950 text-paper-100 shadow-sm font-semibold' : 'text-slate-600 hover:text-ink-950 hover:bg-white/60'
}`}
>
<BarChart3 className="h-3.5 w-3.5" /> Analytics
</Link>
{/* Nutrition tab */}
<Link
to="/nutrition-analytics"
className={`flex items-center gap-1.5 rounded-full px-3.5 py-1.5 transition-all ${
path === '/nutrition-analytics' ? 'bg-ink-950 text-paper-100 shadow-sm font-semibold' : 'text-slate-600 hover:text-ink-950 hover:bg-white/60'
}`}
>
<HeartPulse className="h-3.5 w-3.5" /> Nutrition
</Link>
{/* Admin Panel tab ONLY visible to Admin role */}
{role === 'admin' && (
<Link
to="/admin"
className={`flex items-center gap-1.5 rounded-full px-3.5 py-1.5 transition-all ${
path === '/admin' ? 'bg-ink-950 text-paper-100 shadow-sm font-semibold' : 'text-slate-600 hover:text-ink-950 hover:bg-white/60'
}`}
>
<Wrench className="h-3.5 w-3.5 text-amber-400" /> Admin
</Link>
)}
</nav>
{/* Top Right Logout Button */}
<button
onClick={handleLogout}
title="Logout to Login Page"
className="flex items-center gap-1.5 rounded-full bg-rose-600 hover:bg-rose-700 text-white px-3.5 py-1.5 text-xs font-semibold shadow-xs transition-all active:scale-95 cursor-pointer"
>
<LogOut className="h-3.5 w-3.5" />
<span>Logout</span>
</button>
</div>
</div>
{children}
</header>
);
}