krishna_sales/src/screens/ConsoleLayout.tsx

78 lines
2.7 KiB
TypeScript

import { useEffect } from 'react';
import { NavLink, Navigate, Outlet, useNavigate } from 'react-router-dom';
import { LogOut } from 'lucide-react';
import { cn } from '../lib/cn';
import { useAuth } from '../auth/context';
import { onAuthErrorAll, orderBookingClient } from '../api/clients';
import { APP_ID } from '../api/config';
import { Button } from '../components/buttons';
import { SCREENS } from './tabs';
/** Auth-guarded shell: navy top bar + tab nav + routed <Outlet>. */
export function ConsoleLayout() {
const { authed, logout } = useAuth();
const navigate = useNavigate();
const user = orderBookingClient.currentUser();
// A 401 from any workflow client bounces back to login.
useEffect(() => {
onAuthErrorAll(() => {
logout();
navigate('/login', { replace: true });
});
}, [logout, navigate]);
if (!authed) return <Navigate to="/login" replace />;
return (
<div className="min-h-screen bg-app flex flex-col">
<header className="sticky top-0 z-10 shrink-0 flex items-center justify-between gap-3 px-6 h-[60px] bg-navy-grad border-b border-border-navy">
<div className="flex flex-col">
<span className="text-md font-extrabold text-on-navy tracking-[-0.01em] leading-none">Krishna Sales</span>
<span className="text-2xs text-on-navy-muted">Field Sales · Sandbox {APP_ID}</span>
</div>
<nav className="flex items-center gap-1 h-full">
{SCREENS.map((t) => {
const Icon = t.icon;
return (
<NavLink
key={t.key}
to={`/${t.key}`}
className={({ isActive }) =>
cn(
'flex items-center gap-1.5 no-underline font-sans text-sm font-medium px-3 py-1.5 rounded-md transition-all duration-150',
isActive ? 'bg-white/10 text-white' : 'text-on-navy-muted hover:text-white hover:bg-white/5',
)
}
>
<Icon size={16} />
{t.label}
</NavLink>
);
})}
</nav>
<div className="flex items-center gap-3">
{user?.name && <span className="text-sm text-on-navy hidden sm:inline">{user.name}</span>}
<Button
variant="secondary"
size="sm"
iconLeft={<LogOut size={14} />}
onClick={() => {
logout();
navigate('/login', { replace: true });
}}
>
Sign out
</Button>
</div>
</header>
<main className="flex-1 overflow-y-auto p-6">
<div className="max-w-[1240px] w-full mx-auto flex flex-col gap-5">
<Outlet />
</div>
</main>
</div>
);
}