Files
ai_ops/ui/src/layouts/MainLayout.tsx

79 lines
2.9 KiB
TypeScript

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;