Spaces:
Sleeping
Sleeping
File size: 2,173 Bytes
75c7554 1fac18a 75c7554 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | import { Routes, Route, NavLink, useLocation } from 'react-router-dom'
import { useEffect, useState } from 'react'
import { LayoutDashboard, PlayCircle, BarChart3, Zap } from 'lucide-react'
import Dashboard from './pages/Dashboard'
import RunEpisode from './pages/RunEpisode'
import Evaluate from './pages/Evaluate'
import { getHealth } from './api/client'
const NAV = [
{ to: '/', label: 'Dashboard', icon: LayoutDashboard },
{ to: '/run', label: 'Run Episode', icon: PlayCircle },
{ to: '/evaluate', label: 'Evaluate', icon: BarChart3 },
]
export default function App() {
const [online, setOnline] = useState(null)
const location = useLocation()
useEffect(() => {
getHealth()
.then(() => setOnline(true))
.catch(() => setOnline(false))
}, [location.pathname])
return (
<div className="layout">
{/* ── Sidebar ── */}
<aside className="sidebar">
<div className="brand">
<div className="brand-icon">⚡</div>
<div>
<div className="brand-title">PowerGrid</div>
<div className="brand-sub">RL PLATFORM</div>
</div>
</div>
<nav className="nav">
<div className="nav-label">Navigation</div>
{NAV.map(({ to, label, icon: Icon }) => (
<NavLink
key={to}
to={to}
end={to === '/'}
className={({ isActive }) => `nav-item${isActive ? ' active' : ''}`}
>
<Icon size={17} />
{label}
</NavLink>
))}
</nav>
<div className="sidebar-footer">
<span className={`status-dot${online === false ? ' offline' : ''}`} />
{online === null ? 'Connecting…' : online ? 'Backend online' : 'Backend offline'}
</div>
</aside>
{/* ── Main ── */}
<main className="main">
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/run" element={<RunEpisode />} />
<Route path="/evaluate" element={<Evaluate />} />
</Routes>
</main>
</div>
)
}
|