import { useState, useMemo } from 'react';
import { Outlet, useNavigate, useLocation } from 'react-router';
import { LayoutDashboard, ShieldCheck, Building, Activity } from 'lucide-react';
import {
AppShell,
Sidebar,
TopBar,
} from '@cameleer/design-system';
import { useAuth } from '../auth/useAuth';
import { useScopes } from '../auth/useScopes';
import { useOrgStore } from '../auth/useOrganization';
import cameleerLogo from '@cameleer/design-system/assets/cameleer3-logo.svg';
function CameleerLogo() {
return (
);
}
export function Layout() {
const navigate = useNavigate();
const location = useLocation();
const { logout } = useAuth();
const scopes = useScopes();
const { username } = useOrgStore();
const [collapsed, setCollapsed] = useState(false);
const breadcrumb = useMemo(() => {
if (location.pathname.startsWith('/admin')) return [{ label: 'Admin' }, { label: 'Tenants' }];
if (location.pathname.startsWith('/license')) return [{ label: 'License' }];
return [{ label: 'Dashboard' }];
}, [location.pathname]);
const sidebar = (
setCollapsed(c => !c)}>
}
title="Cameleer SaaS"
onClick={() => navigate('/')}
/>
{/* Dashboard */}
}
label="Dashboard"
open={false}
active={location.pathname === '/' || location.pathname === ''}
onToggle={() => navigate('/')}
>
{null}
{/* License */}
}
label="License"
open={false}
active={location.pathname.startsWith('/license')}
onToggle={() => navigate('/license')}
>
{null}
{/* Platform Admin section */}
{scopes.has('platform:admin') && (
}
label="Platform"
open={false}
active={location.pathname.startsWith('/admin')}
onToggle={() => navigate('/admin/tenants')}
>
{null}
)}
{/* Link to the server observability dashboard */}
}
label="Open Server Dashboard"
onClick={() => window.open('/server/', '_blank', 'noopener')}
/>
);
return (
{/*
* TopBar always renders status filters, time range pills, auto-refresh, and
* command palette search via useGlobalFilters() / useCommandPalette(). Both
* hooks throw if their providers are absent, so GlobalFilterProvider and
* CommandPaletteProvider cannot be removed from main.tsx without crashing the
* app. The TopBar API has no props to suppress these server-oriented controls.
* Hiding them on platform pages would require a DS change.
*/}
);
}