// App shell — scene switcher + top bar + command palette + console + toaster. import { useEffect } from "react"; import { useApp, scenarioById } from "./state/store"; import Landing from "./scenes/Landing"; import MissionControl from "./scenes/MissionControl"; import RunHistory from "./scenes/RunHistory"; import Wizard from "./scenes/Wizard"; import Settings from "./scenes/Settings"; import Login from "./scenes/Login"; import SsoCallback from "./scenes/SsoCallback"; import Chat from "./scenes/Chat"; import Agent from "./scenes/Agent"; import Hub from "./scenes/Hub"; import GeoAttendance from "./scenes/GeoAttendance"; import Explainer from "./scenes/Explainer"; import CommandBar from "./components/CommandBar"; import Toaster from "./components/Toaster"; import Console from "./components/Console"; import { Cmd, Home, Layers, HistoryIcon, Pulse, Refresh, Branch, Cog, User, Sun, Moon, Bot } from "./components/icons"; import { liveMeta } from "./data/scenarios"; export default function App() { const scene = useApp((s) => s.scene); const setScene = useApp((s) => s.setScene); const setCmdOpen = useApp((s) => s.setCmdOpen); const scenarioId = useApp((s) => s.scenarioId); const sc = scenarioById(scenarioId); const mode = useApp((s) => s.mode); const setMode = useApp((s) => s.setMode); const refreshLive = useApp((s) => s.refreshLive); const liveLoading = useApp((s) => s.liveLoading); const liveFetchedAt = useApp((s) => s.liveFetchedAt); const consoleOpen = useApp((s) => s.consoleOpen); const setConsoleOpen = useApp((s) => s.setConsoleOpen); const apiLogCount = useApp((s) => s.apiLog.length); const actor = useApp((s) => s.actor); const userEmail = useApp((s) => s.userEmail); const startPolling = useApp((s) => s.startPolling); const stopPolling = useApp((s) => s.stopPolling); const isAuthed = useApp((s) => s.isAuthed); // Auth guard and SSO callback detector useEffect(() => { if (typeof window !== "undefined" && window.location.hash.includes("access_token")) { setScene("sso-callback"); } else if (!isAuthed && scene !== "login" && scene !== "sso-callback") { setScene("login"); } }, [isAuthed, scene, setScene]); useEffect(() => { if (mode === "live") startPolling(); return () => stopPolling(); }, [mode, startPolling, stopPolling]); const liveAge = liveFetchedAt ? `${Math.max(0, Math.floor((Date.now() - liveFetchedAt) / 1000))}s ago` : null; return (
{scene !== "landing" && scene !== "login" && scene !== "sso-callback" && (
{sc && scene === "mission" && (
{sc.family.label} {sc.defName.slice(0, 40)} {sc.version} {sc.live ? ( live · {liveMeta.fetchedFrom?.replace("https://", "")} ) : ( blueprint )}
)}
{mode === "live" && ( )}
)}
{scene === "login" && } {scene === "sso-callback" && } {scene === "landing" && } {scene === "mission" && } {scene === "history" && } {scene === "studio" && } {scene === "chat" && } {scene === "agent" && } {scene === "hub-procurement" && } {scene === "hub-hr" && } {scene === "hub-it" && } {scene === "geo-attendance" && } {scene === "explainer" && } {scene === "settings" && }
); } function ThemeToggle() { const theme = useApp((s) => s.theme); const setTheme = useApp((s) => s.setTheme); const isDark = theme === "dark"; return ( ); }