Refactor UI modules and harden run/API behavior
This commit is contained in:
78
ui/src/layouts/MainLayout.tsx
Normal file
78
ui/src/layouts/MainLayout.tsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { NavLink, Outlet, useLocation } from 'react-router-dom';
|
||||
import { LayoutDashboard, Settings, Activity, History } from 'lucide-react';
|
||||
|
||||
const MainLayout: React.FC = () => {
|
||||
const [isServerOnline, setIsServerOnline] = useState(false);
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
// Basic ping to check if our API is running
|
||||
fetch('/api/health')
|
||||
.then((res) => {
|
||||
if (res.ok) setIsServerOnline(true);
|
||||
})
|
||||
.catch(() => setIsServerOnline(false));
|
||||
|
||||
// Optional: add a polling interval
|
||||
const interval = setInterval(() => {
|
||||
fetch('/api/health')
|
||||
.then((res) => setIsServerOnline(res.ok))
|
||||
.catch(() => setIsServerOnline(false));
|
||||
}, 10000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
const getPageTitle = (pathname: string) => {
|
||||
switch (pathname) {
|
||||
case '/': return 'Dashboard Overview';
|
||||
case '/settings': return 'Definitions & Policies';
|
||||
case '/history': return 'Run History';
|
||||
default: return 'AI Ops';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div id="root">
|
||||
<aside className="sidebar">
|
||||
<div className="sidebar-header">
|
||||
<h1>AI Ops Control</h1>
|
||||
<p>Topology & Telemetry</p>
|
||||
</div>
|
||||
<nav className="sidebar-nav">
|
||||
<NavLink to="/" className={({ isActive }) => `nav-item ${isActive ? 'active' : ''}`}>
|
||||
<LayoutDashboard /> Dashboard
|
||||
</NavLink>
|
||||
<NavLink to="/history" className={({ isActive }) => `nav-item ${isActive ? 'active' : ''}`}>
|
||||
<History /> History
|
||||
</NavLink>
|
||||
<NavLink to="/settings" className={({ isActive }) => `nav-item ${isActive ? 'active' : ''}`}>
|
||||
<Settings /> Policies & Limits
|
||||
</NavLink>
|
||||
</nav>
|
||||
<div className="sidebar-footer">
|
||||
<div className={`status-dot ${isServerOnline ? 'online' : 'offline'}`} />
|
||||
{isServerOnline ? 'Server Online' : 'Connecting...'}
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main className="main-content">
|
||||
<header className="top-bar">
|
||||
<h2 className="page-title">{getPageTitle(location.pathname)}</h2>
|
||||
<div>
|
||||
<div className="badge neutral flex items-center gap-2">
|
||||
<Activity size={14} /> Agent Ready
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div className="content-scroll animate-fade-in" key={location.pathname}>
|
||||
<Outlet />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MainLayout;
|
||||
Reference in New Issue
Block a user