// Sidebar + Topbar — wired to real user data
const { useState: _us, useEffect: _ue } = React;
function Sidebar({ mode, setMode, route, setRoute, me }) {
const [mobileOpen, setMobileOpen] = _us(false);
// Close drawer when route changes (auto-dismiss after nav)
_ue(() => { setMobileOpen(false); }, [route, mode]);
// Close drawer when window resized to desktop
_ue(() => {
const onResize = () => { if (window.innerWidth > 900) setMobileOpen(false); };
window.addEventListener('resize', onResize);
return () => window.removeEventListener('resize', onResize);
}, []);
// Listen for mobile menu open events (dispatched by Topbar hamburger)
_ue(() => {
const open = () => setMobileOpen(true);
window.addEventListener('hdr:open-menu', open);
return () => window.removeEventListener('hdr:open-menu', open);
}, []);
const userNav = [
{ key: 'overview', label: 'Overview', icon: },
{ key: 'playground',label: 'Playground',icon: },
{ key: 'agents', label: 'My Agents', icon: },
{ key: 'skills', label: 'My Skills', icon: },
{ key: 'keys', label: 'API Keys', icon: },
{ key: 'billing', label: 'Billing', icon: },
{ key: 'logs', label: 'Logs', icon: },
{ key: 'docs', label: 'Docs', icon: },
];
const adminNav = [
{ key: 'overview', label: 'Overview', icon: },
{ key: 'analytics', label: 'Analytics', icon: },
{ key: 'users', label: 'Users', icon: },
{ key: 'alllogs', label: 'All Logs', icon: },
{ key: 'models', label: 'Models', icon: },
{ key: 'skills', label: 'Skills', icon: },
{ key: 'tools', label: 'Tools', icon: },
{ key: 'settings', label: 'Settings', icon: },
];
const nav = mode === 'admin' ? adminNav : userNav;
const logout = async () => {
await window.HDR_API.logout();
location.href = '/';
};
const initials = (me?.name || me?.email || 'U').split(/\s+/).map(p => p[0]).filter(Boolean).slice(0,2).join('').toUpperCase();
return (
<>
{/* Backdrop — appears behind drawer */}
setMobileOpen(false)}/>
>
);
}
// Hamburger button — rendered separately inside Topbar
function MobileMenuBtn({ onClick }) {
return (
);
}
window.MobileMenuBtn = MobileMenuBtn;
function Topbar({ mode, route, theme, setTheme, me }) {
const titles = {
user: {
overview: 'Overview', playground: 'Playground', agents: 'My Agents',
skills: 'My Skills', keys: 'API Keys', billing: 'Billing', logs: 'Logs', docs: 'Docs',
},
admin: {
overview: 'Admin Overview', analytics: 'Analytics', users: 'Users',
alllogs: 'All Logs', models: 'Models', skills: 'Skills',
tools: 'Tools', settings: 'Settings',
},
};
const [pulse, setPulse] = _us(null);
// Admin: live pulse polling for "X req/min"
_ue(() => {
if (mode !== 'admin') return;
const tick = async () => {
try { const p = await window.HDR_API.adminPulse(); setPulse(p.summary); } catch {}
};
tick();
const id = setInterval(tick, 15000);
return () => clearInterval(id);
}, [mode]);
return (
{mode === 'admin' ? 'Admin' : 'Dashboard'}
/
{titles[mode][route] || ''}
{mode === 'admin' ? (
{pulse ? `Live · ${pulse.reqs_60min || 0} req/h` : 'Live'}
) : (
{window.HDR_UTIL.rupees(me?.wallet_paise || 0)}
)}
);
}
window.Sidebar = Sidebar;
window.Topbar = Topbar;