/* Shell.jsx — sidebar + topbar layout */ const NAV_ITEMS = [ { id: "overview", label: "Огляд", icon: "◉", group: "main" }, { id: "stops", label: "Зупинки", icon: "📍", group: "main", badge: "1 247" }, { id: "routes", label: "Маршрути", icon: "🛤", group: "main", badge: "42" }, { id: "monitoring", label: "Моніторинг", icon: "📡", group: "main", badgeKind: "bad", badge: "3" }, { id: "analytics", label: "Аналітика", icon: "📊", group: "main" }, { id: "history", label: "Історія змін",icon: "🕓", group: "ops" }, { id: "settings", label: "Налаштування",icon: "⚙", group: "ops" }, ]; const ROLE_LABEL = { admin: "Адміністратор", engineer: "Інженер мережі", dispatcher: "Диспетчер" }; function Sidebar({ active, onNav, user, onLogout }) { const caps = user?.capabilities || {}; const main = NAV_ITEMS.filter(n => n.group === "main"); const ops = NAV_ITEMS.filter(n => n.group === "ops").filter(item => { if (item.id === "settings") return !!caps.settings_write; return true; }); const display = user?.actor || user?.name || "?"; const initials = display.split(/[ @.]/).filter(Boolean).map(w => w[0]).join("").slice(0, 2).toUpperCase() || "?"; return ( ); } function AutoRefreshToggle() { const api = window.passengerApi; const [enabled, setEnabled] = React.useState(api ? api.getAutoRefresh() : true); const onClick = () => { const next = !enabled; setEnabled(next); api && api.setAutoRefresh(next); }; return ( ); } function Topbar({ title, subtitle, actions, user }) { return (
{title}
{subtitle &&
{subtitle}
}
🏙 Київ — основний
{actions}
); } Object.assign(window, { Sidebar, Topbar, AutoRefreshToggle });