import React, { useEffect, useState } from 'react'; import { NavLink, Outlet, useLocation } from 'react-router-dom'; import { useNavigation } from '../context/NavigationContext'; import atkLogo from '../assets/atk-logo-notscuffed.png'; const animationStyles = ` @keyframes pulse-medium-white { 0%, 100% { background-color: rgba(255,255,255,0.1); } 50% { background-color: rgba(255,255,255,0.3); } } .animate-pulse-medium-white { animation: pulse-medium-white 1.8s infinite; } `; function Layout() { const { highlightedNavLink, setHighlightedNavLink } = useNavigation(); const location = useLocation(); const [serverOnline, setServerOnline] = useState(false); const [datagenServerOnline, setDatagenServerOnline] = useState(false); // Check for server on port 8003 useEffect(() => { const checkServerStatus = async () => { try { const baseUrl = window.location.hostname === '127.0.0.1' || window.location.hostname === 'localhost' ? 'http://127.0.0.1:8003' : `${window.location.origin}/llm`; const response = await fetch(`${baseUrl}/health`, { method: 'GET', headers: { 'Content-Type': 'application/json' } }); const isOnline = response.ok; setServerOnline(isOnline); // Auto-highlight chat button when server comes online (but not if user is already on chat page) if (isOnline && location.pathname !== '/chat') { setHighlightedNavLink('/chat'); } else if (!isOnline && highlightedNavLink === '/chat') { // Remove highlight when server goes offline setHighlightedNavLink(null); } } catch (error) { setServerOnline(false); // Remove highlight when server is unreachable if (highlightedNavLink === '/chat') { setHighlightedNavLink(null); } } }; // Initial check checkServerStatus(); // Poll every 5 seconds const interval = setInterval(checkServerStatus, 5000); return () => clearInterval(interval); }, [location.pathname, highlightedNavLink, setHighlightedNavLink]); // Check for datagen inference server on port 8082 useEffect(() => { const checkDatagenServerStatus = async () => { try { // Try OpenAI-compatible endpoint const response = await fetch('http://127.0.0.1:8082/v1/models', { method: 'GET', headers: { 'Content-Type': 'application/json' } }); setDatagenServerOnline(response.ok); } catch (error) { setDatagenServerOnline(false); } }; // Initial check checkDatagenServerStatus(); // Poll every 5 seconds const interval = setInterval(checkDatagenServerStatus, 5000); return () => clearInterval(interval); }, []); const navLinkClass = (path) => ({ isActive }) => { const base = 'px-4 py-2 rounded hover:bg-gray-700 transition-colors'; const active = isActive ? 'bg-blue-600 text-white font-bold' : 'text-gray-300'; const pulse = highlightedNavLink === path && !isActive ? 'animate-pulse-medium-white' : ''; return `${base} ${active} ${pulse}`; }; return (
{/* Child routes will render here */}
); } export default Layout;