|
1 | | -export default function App() { |
| 1 | +import { useState } from 'react'; |
| 2 | +import type { CSSProperties } from 'react'; |
| 3 | +import { Topbar, type Health } from '@/shell/Topbar'; |
| 4 | +import { Statusbar, type ConnectionState, type VmSeqState } from '@/shell/Statusbar'; |
| 5 | +import { SessionsRail } from '@/shell/SessionsRail'; |
| 6 | +import { FlowStrip } from '@/shell/FlowStrip'; |
| 7 | +import { useUiHints } from '@/state/useUiHints'; |
| 8 | +import { useSessionList } from '@/state/useSessionList'; |
| 9 | +import { useApprovalsQueue } from '@/state/useApprovalsQueue'; |
| 10 | +import { useAgentDefinitions } from '@/state/useAgentDefinitions'; |
| 11 | +import { useSessionFull } from '@/state/useSessionFull'; |
| 12 | + |
| 13 | +const UI_VERSION = 'v2.0.0-rc1'; |
| 14 | +const RUNTIME_VERSION_FALLBACK = 'unknown'; |
| 15 | + |
| 16 | +const shellStyle: CSSProperties = { |
| 17 | + display: 'grid', |
| 18 | + gridTemplateRows: 'auto auto 1fr auto', |
| 19 | + height: '100vh', |
| 20 | + background: 'var(--bg-page)', |
| 21 | + color: 'var(--ink-1)', |
| 22 | + fontFamily: 'var(--ff-sans)', |
| 23 | +}; |
| 24 | + |
| 25 | +const paneStyle: CSSProperties = { |
| 26 | + display: 'grid', |
| 27 | + gridTemplateColumns: '220px 1fr 340px', |
| 28 | + minHeight: 0, |
| 29 | +}; |
| 30 | + |
| 31 | +const canvasEmptyStyle: CSSProperties = { |
| 32 | + display: 'flex', |
| 33 | + alignItems: 'center', |
| 34 | + justifyContent: 'center', |
| 35 | + background: 'var(--bg-elev)', |
| 36 | + borderRight: '1px solid var(--hair)', |
| 37 | + padding: 32, |
| 38 | +}; |
| 39 | + |
| 40 | +const monitorRailPlaceholder: CSSProperties = { |
| 41 | + background: 'var(--bg-page)', |
| 42 | + borderLeft: '1px solid var(--hair)', |
| 43 | + padding: 16, |
| 44 | + fontSize: 11, |
| 45 | + color: 'var(--ink-3)', |
| 46 | +}; |
| 47 | + |
| 48 | +export function App() { |
| 49 | + const [activeSid, setActiveSid] = useState<string | null>(null); |
| 50 | + |
| 51 | + const uiHints = useUiHints(); |
| 52 | + const sessionList = useSessionList(); |
| 53 | + const approvals = useApprovalsQueue(); |
| 54 | + const agents = useAgentDefinitions(); |
| 55 | + const sessionFull = useSessionFull(activeSid); |
| 56 | + |
| 57 | + const brandName = uiHints.data?.brand_name ?? 'ASR'; |
| 58 | + const envName = uiHints.data?.environments?.[0] ?? 'dev'; |
| 59 | + const appName = 'runtime'; |
| 60 | + |
| 61 | + const health: Health = |
| 62 | + sessionList.error || approvals.error || agents.isError |
| 63 | + ? 'down' |
| 64 | + : 'ok'; |
| 65 | + |
| 66 | + const connection: ConnectionState = |
| 67 | + sessionList.error || (sessionFull.error && activeSid !== null) |
| 68 | + ? 'disconnected' |
| 69 | + : 'connected'; |
| 70 | + |
| 71 | + const vmSeqState: VmSeqState = 'in-sync'; |
| 72 | + const vmSeq = sessionFull.state.vmSeq; |
| 73 | + |
2 | 74 | return ( |
3 | | - <div style={{ padding: 'var(--s-6)' }}> |
4 | | - <h1 style={{ |
5 | | - fontSize: 'var(--t-display)', |
6 | | - fontWeight: 500, |
7 | | - letterSpacing: '-0.018em', |
8 | | - color: 'var(--ink-1)', |
9 | | - marginBottom: 'var(--s-3)', |
10 | | - }}> |
11 | | - ASR Operator Console |
12 | | - </h1> |
13 | | - <p style={{ |
14 | | - fontSize: 'var(--t-body)', |
15 | | - color: 'var(--ink-3)', |
16 | | - fontFamily: 'var(--ff-mono)', |
17 | | - }}> |
18 | | - v2.0.0-rc1 · scaffold + design tokens · components land in tasks 16-20 |
19 | | - </p> |
20 | | - <div style={{ |
21 | | - marginTop: 'var(--s-5)', |
22 | | - padding: 'var(--s-4)', |
23 | | - background: 'var(--bg-elev)', |
24 | | - boxShadow: 'var(--elev-1)', |
25 | | - color: 'var(--ink-2)', |
26 | | - }}> |
27 | | - Token preview: warm cream <code style={{ fontFamily: 'var(--ff-mono)' }}>#FBFAF6</code> page, |
28 | | - accent <span style={{ color: 'var(--acc)' }}>navy #2A4365</span>, |
29 | | - deep ink <span style={{ color: 'var(--ink-1)', fontWeight: 600 }}>#15110A</span>. |
| 75 | + <div style={shellStyle}> |
| 76 | + <Topbar |
| 77 | + brandName={brandName} |
| 78 | + appName={appName} |
| 79 | + envName={envName} |
| 80 | + health={health} |
| 81 | + approvalsCount={approvals.count} |
| 82 | + onSearch={() => {/* Phase 6: open search overlay */}} |
| 83 | + onNew={() => {/* Phase 6: open NewSessionModal */}} |
| 84 | + onApprovalsClick={() => {/* Phase 6: open approvals view */}} |
| 85 | + /> |
| 86 | + <FlowStrip |
| 87 | + agents={agents.data?.list ?? []} |
| 88 | + activeAgent={null} |
| 89 | + graphVersion={`v${agents.data?.list.length ?? 0}`} |
| 90 | + /> |
| 91 | + <div style={paneStyle}> |
| 92 | + <SessionsRail |
| 93 | + sessions={sessionList.sessions} |
| 94 | + activeSid={activeSid} |
| 95 | + onSelect={setActiveSid} |
| 96 | + /> |
| 97 | + <div style={canvasEmptyStyle}> |
| 98 | + <span style={{ fontSize: 13, color: 'var(--ink-3)' }}> |
| 99 | + Select a session from the rail or create a new one. |
| 100 | + </span> |
| 101 | + </div> |
| 102 | + <div style={monitorRailPlaceholder}> |
| 103 | + Ambient monitors (Phase 5) |
| 104 | + </div> |
30 | 105 | </div> |
| 106 | + <Statusbar |
| 107 | + connection={connection} |
| 108 | + sseEventCount={sessionFull.state.events.length} |
| 109 | + vmSeq={vmSeq} |
| 110 | + vmSeqState={vmSeqState} |
| 111 | + runtimeVersion={RUNTIME_VERSION_FALLBACK} |
| 112 | + uiVersion={UI_VERSION} |
| 113 | + /> |
31 | 114 | </div> |
32 | 115 | ); |
33 | 116 | } |
0 commit comments