import React, { useEffect, useState, useRef } from 'react'; import { useAuth } from '../context/AuthContext'; import { Network, Server, Cpu, Database, Activity, ArrowRight, Zap, GitBranch, MessageSquare, TrendingUp, RefreshCw } from 'lucide-react'; const API_BASE = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000/api'; // Animated counter hook function useCountUp(target: number, duration = 1200) { const [val, setVal] = useState(0); const prev = useRef(0); useEffect(() => { if (target === 0) { setVal(0); return; } const start = prev.current; const diff = target - start; const startTime = performance.now(); const tick = (now: number) => { const t = Math.min((now - startTime) / duration, 1); const ease = 1 - Math.pow(1 - t, 3); setVal(Math.round(start + diff * ease)); if (t < 1) requestAnimationFrame(tick); else prev.current = target; }; requestAnimationFrame(tick); }, [target]); return val; } const StatCounter: React.FC<{ value: number | string; label: string; suffix?: string }> = ({ value, label, suffix = '' }) => { const numVal = typeof value === 'number' ? value : parseInt(String(value)) || 0; const animated = useCountUp(numVal); return (
{typeof value === 'number' ? animated : value}{suffix}
{label}
); }; const Home: React.FC = () => { const { token, logout, user } = useAuth(); const [health, setHealth] = useState(null); const [stats, setStats] = useState(null); const [myStats, setMyStats] = useState(null); const [loading, setLoading] = useState(true); const [lastRefresh, setLastRefresh] = useState(new Date()); const fetchData = async () => { setLoading(true); try { const [healthRes, statsRes, myStatsRes] = await Promise.all([ fetch(`${API_BASE}/system/health`), fetch(`${API_BASE}/system/stats`, { headers: { Authorization: `Bearer ${token}` } }), fetch(`${API_BASE}/system/my-stats`, { headers: { Authorization: `Bearer ${token}` } }).catch(() => null), ]); if (statsRes.status === 401) { logout(); return; } if (healthRes.ok) setHealth(await healthRes.json()); if (statsRes.ok) setStats(await statsRes.json()); if (myStatsRes?.ok) setMyStats(await myStatsRes.json()); } catch (err) { console.error('Failed to fetch system data', err); } finally { setLoading(false); setLastRefresh(new Date()); } }; useEffect(() => { fetchData(); const interval = setInterval(fetchData, 30000); return () => clearInterval(interval); }, [token]); const isOnline = (v: boolean | undefined) => v === true; const systemOk = health ? (isOnline(health.neo4j_connected) && isOnline(health.redis_connected)) : false; return (
{/* ── Hero ─────────────────────────────────────── */}
CORTEX PLATFORM

Agentic Knowledge
Intelligence

Production-grade knowledge graph · Real-time extraction · Multi-hop reasoning

{loading ? 'CHECKING...' : systemOk ? 'SYSTEM OPERATIONAL' : 'SYSTEM DEGRADED'}
{[ { label: 'NEO4J', ok: isOnline(health?.neo4j_connected) }, { label: 'REDIS', ok: isOnline(health?.redis_connected) }, { label: `${health?.workers_active ?? 0} WORKERS`, ok: true, neutral: true }, { label: 'API', ok: true }, ].map(s => (
{s.label} {s.neutral ? 'ACTIVE' : s.ok ? 'CONNECTED' : 'OFFLINE'}
))}
{/* ── Platform Metrics ─────────────────────────── */}
PLATFORM METRICS
{stats?.ontology_version ?? '—'}
ONTOLOGY VER
{/* ── Main Grid ────────────────────────────────── */}
{/* Quick Actions */}
QUICK ACTIONS
{[ { href: '/process', icon: , label: 'INGEST DOCUMENTS', desc: 'Upload PDFs, text, or crawl URLs' }, { href: '/interact', icon: , label: 'QUERY KNOWLEDGE', desc: 'Ask questions across the graph' }, { href: '/simulate', icon: , label: 'EXPLORE NODES', desc: 'Interactive D3 force visualization' }, { href: '/ontology', icon: , label: 'MANAGE ONTOLOGY', desc: 'Edit schema & run AI refinement' }, { href: '/insights', icon: ,label: 'INSIGHTS', desc: 'Quality metrics & AI reports' }, ].map(a => ( {a.icon}
{a.label}
{a.desc}
))}
{/* Right column: My Activity + Feature cards */}
{/* User Activity */}
MY ACTIVITY {user && @{user.username}}
{myStats?.conversation_count ?? '—'}
CONVERSATIONS
{myStats?.message_count ?? '—'}
QUERIES SENT
{myStats?.last_active ? new Date(myStats.last_active).toLocaleDateString() : '—'}
LAST ACTIVE
{!myStats && (
Start querying the graph to build your activity history.
)}
{/* Graph intelligence card */}
KNOWLEDGE GRAPH
Neo4j-powered semantic knowledge graph. Multi-hop reasoning, entity enrichment, and community detection built in.
{['Entities', 'Relationships', 'Communities', 'Graph Export'].map(tag => ( {tag} ))}
{/* ── Feature Showcase ─────────────────────────── */}
PLATFORM CAPABILITIES
{[ { icon: , title: 'DOCUMENT INGESTION', desc: 'Ingest PDFs, text files, Markdown, and web URLs. Celery workers extract entities and relationships into the knowledge graph automatically via LLM pipelines.', color: '#2563eb', }, { icon: , title: 'GRAPH INTELLIGENCE', desc: 'Neo4j-powered knowledge graph with rich entity relationships. Query across documents globally or per-source with full ontology control.', color: '#7c3aed', }, { icon: , title: 'AGENTIC LOGIC', desc: 'Multi-step ReACT reasoning agent that searches the graph, retrieves relevant chunks, and streams answers with confidence scoring in real time.', color: '#059669', }, { icon: , title: 'LLM-AS-JUDGE', desc: 'Inline faithfulness evaluation using heuristic scoring. Detects hallucination risk, context precision, and answer quality on every response.', color: '#d97706', }, { icon: , title: 'LIVE SIMULATION', desc: 'Interactive D3 force graph with color-coded entity types, physics controls, fullscreen mode, PNG export, and node detail modals.', color: '#dc2626', }, { icon: , title: 'ONTOLOGY DRIFT', desc: 'Automated schema drift detection that spots when new data no longer fits the current ontology. Propose and approve schema expansions.', color: '#0891b2', }, ].map(f => (
{f.icon}
{f.title}
{f.desc}
))}
{/* Footer bar */}
CORTEX_PLATFORM Last refreshed: {lastRefresh.toLocaleTimeString()} v{health ? '1.0' : '—'} · Neo4j + Redis + Celery
); }; export default Home;