import React from "react"; import {useEffect, useMemo, useState} from "react"; import "./styles/theme.css"; import TopBar from "./components/TopBar"; import ComputerCard from "./components/ComputerCard"; import ComputerDetailsModal from "./components/ComputerDetailsModal"; import AIAssistantDrawer from "./components/AIAssistantDrawer"; export default function App() { const [stats, setStats] = useState(null); const [computers, setComputers] = useState([]); const [loading, setLoading] = useState(true); const [lastUpdated, setLastUpdated] = useState(null); const [query, setQuery] = useState(""); const [status, setStatus] = useState(""); const [selectedComputer, setSelectedComputer] = useState(null); const [aiOpen, setAiOpen] = useState(false); const [aiScope, setAiScope] = useState(null); const [selectedEnv, setSelectedEnv] = useState("default"); async function refresh() { try { setLoading(true); const [s, c] = await Promise.all([ fetch("/api/stats").then((r) => r.json()), fetch("/api/computers", { headers: {"X-Env": selectedEnv}, }).then((r) => r.json()), ]); setStats(s); setComputers(Array.isArray(c) ? c : []); setLastUpdated(new Date().toISOString()); } catch (e) { console.error("refresh error", e); } finally { setLoading(false); } } useEffect(() => { refresh(); }, [selectedEnv]); const filtered = useMemo(() => { const q = query.trim().toLowerCase(); return (computers || []) .filter((c) => (status ? c.status === status : true)) .filter((c) => { if (!q) return true; const hay = [c.name, c.user, c.ip, c.os, c.status].filter(Boolean).join(" ").toLowerCase(); return hay.includes(q); }); }, [computers, query, status]); return (
setAiOpen(true)} onRefresh={refresh} lastUpdated={lastUpdated} onEnvChange={(env) => setSelectedEnv(env)} selectedEnv={selectedEnv} /> {/* STATS */}
Total Computers
{computers.length}
Monitored Systems
Sysmon Events (24h)
{stats?.total_sysmon_events ?? "—"}
Security Events
Network Connections (24h)
{stats?.total_network_connections ?? "—"}
Captured Connections
{/* FILTERS */}
Filters
{loading ? "Refreshing…" : `${filtered.length} shown`}
setQuery(e.target.value)} placeholder="Search by name / user / ip / os…" />
{/* COMPUTERS */}
Connected Computers
{filtered.length} computers
{filtered.map((c) => ( { setSelectedComputer(pc); setAiScope(pc.name); }} /> ))} {filtered.length === 0 && (
No computers match filter.
)}
{/* DETAILS MODAL */} setSelectedComputer(null)} onAskAI={(name) => { setAiScope(name); setAiOpen(true); }} /> {/* AI DRAWER */} setAiOpen(false)} computers={computers} scope={aiScope} setScope={setAiScope} />
); }