import React, { useState, useEffect } from 'react'; import { NavLink } from 'react-router-dom'; import { Menu, X, Search, Activity, LayoutDashboard, Terminal, Settings, LogOut, Server, Archive, Package, Network, ChevronDown, ChevronRight, HardDrive, Boxes, UserPlus } from 'lucide-react'; import './Layout.css'; interface LayoutProps { children: React.ReactNode; onLogout: () => void; onSearch: (q: string) => void; } const Layout: React.FC = ({ children, onLogout, onSearch }) => { const [sidebarOpen, setSidebarOpen] = useState(true); const [search, setSearch] = useState(''); const [systemActive, setSystemActive] = useState(false); const handleSearchSubmit = (e: React.FormEvent) => { e.preventDefault(); onSearch(search); }; useEffect(() => { const onStats = (e: Event) => { const stats = (e as CustomEvent).detail; setSystemActive(stats.deployed_deckies > 0); }; window.addEventListener('decnet:stats', onStats); return () => window.removeEventListener('decnet:stats', onStats); }, []); return (
{/* Sidebar */} {/* Main Content Area */}
{/* Topbar */}
setSearch(e.target.value)} />
SYSTEM: {systemActive ? 'ACTIVE' : 'INACTIVE'}
{/* Dynamic Content */}
{children}
); }; interface NavItemProps { to: string; icon: React.ReactNode; label: string; open: boolean; indent?: boolean; } const NavItem: React.FC = ({ to, icon, label, open, indent }) => ( `nav-item ${isActive ? 'active' : ''} ${indent ? 'nav-subitem' : ''}`} end={to === '/'} > {icon} {open && {label}} ); interface NavGroupProps { label: string; icon: React.ReactNode; open: boolean; children: React.ReactNode; } const NavGroup: React.FC = ({ label, icon, open, children }) => { const [expanded, setExpanded] = useState(true); return (
{expanded &&
{children}
}
); }; export default Layout;