/** * TrafficVision Dashboard — main layout. * * Layout (desktop): * ┌─────────────────────────────┬──────────────────┐ * │ Video feed (large) │ Stats cards │ * │ │ Class breakdown │ * │ │ Alerts panel │ * ├─────────────────────────────┴──────────────────┤ * │ Vehicle count chart │ Speed distribution │ * ├────────────────────────────────────────────────┤ * │ Track overlay (full width) │ * └────────────────────────────────────────────────┘ */ import { useState, useEffect, useCallback } from 'react' import { useMetricsStream } from './hooks/useWebSocket' import VideoFeed from './components/VideoFeed' import StatsCards from './components/StatsCards' import VehicleCountChart from './components/VehicleCountChart' import SpeedDistribution from './components/SpeedDistribution' import ClassBreakdown from './components/ClassBreakdown' import AlertsPanel from './components/AlertsPanel' import TrafficFlowMap from './components/TrafficFlowMap' import PipelineControl from './components/PipelineControl' const API = '/api' function useHealth() { const [gpu, setGpu] = useState(null) // null = unknown, true/false once fetched useEffect(() => { fetch(`${API}/health`) .then(r => r.ok ? r.json() : null) .then(data => { if (data) setGpu(data.gpu ?? false) }) .catch(() => setGpu(false)) }, []) return gpu } function usePipelineStatus() { const [status, setStatus] = useState(null) const refresh = useCallback(async () => { try { const res = await fetch(`${API}/pipeline/status`) if (res.ok) setStatus(await res.json()) } catch { /* backend not up yet */ } }, []) // Poll every 3 s useEffect(() => { refresh() const id = setInterval(refresh, 3000) return () => clearInterval(id) }, [refresh]) return { status, refresh } } export default function App() { const { status, refresh } = usePipelineStatus() const { connected, metrics } = useMetricsStream(true) const { latest, history, alerts } = metrics const gpu = useHealth() const pipelineRunning = status?.running ?? false return (
{/* Header */}
TrafficVision
Real-Time Traffic Analytics
{connected ? 'Metrics connected' : 'Metrics disconnected'}
{/* Pipeline control bar */} {/* KPI cards */} {/* Video + sidebar */}
{/* Charts row */}
{/* Track overlay */}
) }