pulse-guard / frontend /src /App.jsx
hemalathashetty
Deploy PulseGuard X self-healing control plane to Hugging Face Spaces
3cb0e2c
Raw
History Blame Contribute Delete
75 kB
import React, { useState, useEffect, useRef } from 'react';
import {
Activity,
ShieldAlert,
Terminal,
Settings,
TrendingUp,
Database,
Network,
Flame,
History,
Map,
Info,
RefreshCw,
Zap,
CheckCircle,
XCircle,
AlertTriangle,
LogOut,
ArrowRight,
Shield,
Lock,
Globe,
Server,
Award
} from 'lucide-react';
import {
AreaChart,
Area,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
BarChart,
Bar,
Legend
} from 'recharts';
// Dynamically resolve API and WebSocket endpoints to support network sharing and tunnels
const getBackendUrls = () => {
const protocol = window.location.protocol;
const hostname = window.location.hostname;
const port = window.location.port;
// Check if env variable is defined (e.g. on Vercel deployment)
const envApiUrl = import.meta.env.VITE_API_URL;
if (envApiUrl) {
return {
api: envApiUrl,
ws: envApiUrl.replace('http', 'ws') + '/ws'
};
}
// If accessed directly via Vite dev server port, use port 8000 for backend
if (port === '5173' || port === '5174') {
return {
api: `${protocol}//${hostname}:8000`,
ws: `${protocol === 'https:' ? 'wss:' : 'ws:'}//${hostname}:8000/ws`
};
} else {
// If accessed via Nginx gateway (port 8080) or public tunnel (port 80/443), use relative host/port
const host = window.location.host; // includes port if present (like :8080)
return {
api: `${protocol}//${host}`,
ws: `${protocol === 'https:' ? 'wss:' : 'ws:'}//${host}/ws`
};
}
};
const urls = getBackendUrls();
const API_URL = urls.api;
const WS_URL = urls.ws;
// Interactive Playground Widget for Marketing page
function InteractivePlayground() {
const [crashed, setCrashed] = useState(false);
const [rateLimit, setRateLimit] = useState(100);
const [cbState, setCbState] = useState("CLOSED");
useEffect(() => {
let t;
if (crashed) {
setCbState("OPEN");
setRateLimit(10);
} else {
setCbState("HALF_OPEN");
t = setTimeout(() => {
setCbState("CLOSED");
setRateLimit(100);
}, 3000);
}
return () => clearTimeout(t);
}, [crashed]);
return (
<div className="glass-panel p-6 rounded-xl border border-slate-800/80 shadow-2xl relative overflow-hidden">
<div className="absolute top-0 right-0 w-32 h-32 bg-emerald-500/5 rounded-full filter blur-xl" />
<h4 className="text-white font-bold text-sm tracking-wider uppercase mb-4 flex items-center gap-2 font-mono">
<Zap className="h-4 w-4 text-emerald-400" />
Interactive Resiliency Simulator
</h4>
<p className="text-slate-400 text-xs mb-6">
Simulate downstream failures to observe automatic circuit breaker state changes and rate limit clamping.
</p>
<div className="flex justify-between items-center py-6 relative">
<div className="flex gap-4 items-center w-full justify-around z-10">
<div className="text-center">
<div className="h-14 w-14 rounded-full border-2 border-emerald-500 bg-darkCard/80 flex items-center justify-center shadow-lg shadow-emerald-500/10">
<span className="text-xs font-mono font-bold text-white">Svc A</span>
</div>
<p className="text-[10px] text-slate-500 font-mono mt-2">Rate: {rateLimit} RPS</p>
</div>
<div className="w-8 h-0.5 bg-slate-800" />
<div className="text-center">
<div className={`h-14 w-14 rounded-full border-2 bg-darkCard/80 flex items-center justify-center shadow-lg transition-all ${cbState === 'CLOSED' ? 'border-emerald-500 shadow-emerald-500/10' : cbState === 'OPEN' ? 'border-red-500 shadow-red-500/10' : 'border-blue-400 shadow-blue-400/10'}`}>
<span className="text-xs font-mono font-bold text-white">Svc B</span>
</div>
<p className="text-[10px] text-slate-500 font-mono mt-2">CB: {cbState}</p>
</div>
<div className="w-8 h-0.5 bg-slate-800" />
<div className="text-center">
<div className={`h-14 w-14 rounded-full border-2 bg-darkCard/80 flex items-center justify-center shadow-lg transition-all ${crashed ? 'border-red-500 shadow-red-500/20' : 'border-emerald-500 shadow-emerald-500/10'}`}>
<span className="text-xs font-mono font-bold text-white">Svc C</span>
</div>
<p className="text-[10px] text-slate-500 font-mono mt-2">{crashed ? "CRASHED" : "HEALTHY"}</p>
</div>
</div>
</div>
<div className="flex gap-4 mt-4">
<button
onClick={() => setCrashed(!crashed)}
className={`w-full py-2.5 rounded-lg text-xs font-bold font-mono transition-all duration-300 ${crashed ? 'bg-emerald-500 text-slate-900 shadow-lg shadow-emerald-500/20 hover:bg-emerald-400' : 'bg-rose-500 text-white shadow-lg shadow-rose-500/20 hover:bg-rose-400'}`}
>
{crashed ? "Recover Service C" : "Simulate Service C Crash"}
</button>
</div>
</div>
);
}
export default function App() {
const [isLoggedIn, setIsLoggedIn] = useState(() => {
return localStorage.getItem('pulseguard_logged_in') === 'true';
});
const [activeTab, setActiveTab] = useState('landing');
const [connected, setConnected] = useState(false);
const [data, setData] = useState({
services: {
"service-a": { limit_capacity: 100, limit_rate: 100, circuit_state: "CLOSED", status: "HEALTHY", rps: 0, error_rate: 0, p50: 0, p95: 0, p99: 0, total_requests: 0 },
"service-b": { limit_capacity: 100, limit_rate: 100, circuit_state: "CLOSED", status: "HEALTHY", rps: 0, error_rate: 0, p50: 0, p95: 0, p99: 0, total_requests: 0 },
"service-c": { limit_capacity: 100, limit_rate: 100, circuit_state: "CLOSED", status: "HEALTHY", rps: 0, error_rate: 0, p50: 0, p95: 0, p99: 0, total_requests: 0 }
},
events: [],
audits: []
});
const [benchmarks, setBenchmarks] = useState([]);
const [benchmarkLoading, setBenchmarkLoading] = useState(false);
const [chaosState, setChaosState] = useState({
"service-a": { delay: 0, error_rate: 0, crash: false, cpu_load: 0, memory_load: 0, packet_loss: 0 },
"service-b": { delay: 0, error_rate: 0, crash: false, cpu_load: 0, memory_load: 0, packet_loss: 0 },
"service-c": { delay: 0, error_rate: 0, crash: false, cpu_load: 0, memory_load: 0, packet_loss: 0 }
});
const [generatorRps, setGeneratorRps] = useState(50);
const [history, setHistory] = useState([]); // Real-time charting history
const socketRef = useRef(null);
// Connect to websocket when logged in
useEffect(() => {
if (!isLoggedIn) return;
const connectWS = () => {
socketRef.current = new WebSocket(WS_URL);
socketRef.current.onopen = () => {
setConnected(true);
console.log('WebSocket Connected');
};
socketRef.current.onmessage = (event) => {
try {
const payload = JSON.parse(event.data);
setData(payload);
// Push to charting history
setHistory(prev => {
const newHistory = [...prev, {
time: new Date().toLocaleTimeString(),
"Service A Latency": (payload.services["service-a"]?.p95 || 0) * 1000,
"Service B Latency": (payload.services["service-b"]?.p95 || 0) * 1000,
"Service C Latency": (payload.services["service-c"]?.p95 || 0) * 1000,
"Service A RPS": payload.services["service-a"]?.rps || 0,
"Service B RPS": payload.services["service-b"]?.rps || 0,
"Service C RPS": payload.services["service-c"]?.rps || 0
}];
if (newHistory.length > 20) newHistory.shift();
return newHistory;
});
} catch (err) {
console.error('Error parsing websocket payload:', err);
}
};
socketRef.current.onclose = () => {
setConnected(false);
console.log('WebSocket Disconnected. Reconnecting...');
setTimeout(connectWS, 3000);
};
};
connectWS();
return () => {
if (socketRef.current) socketRef.current.close();
};
}, [isLoggedIn]);
// Fetch benchmarks and chaos configurations when logged in
const fetchBenchmarks = async () => {
try {
const res = await fetch(`${API_URL}/api/benchmarks`);
const body = await res.json();
setBenchmarks(body);
} catch (err) {
console.error(err);
}
};
const fetchChaosStatus = async () => {
try {
const res = await fetch(`${API_URL}/api/chaos/status`);
const body = await res.json();
setChaosState(body);
} catch (err) {
console.error(err);
}
};
useEffect(() => {
if (!isLoggedIn) return;
fetchBenchmarks();
fetchChaosStatus();
const interval = setInterval(() => {
fetchBenchmarks();
fetchChaosStatus();
}, 5000);
return () => clearInterval(interval);
}, [isLoggedIn]);
const triggerChaos = async (service, type, val) => {
const current = chaosState[service] || { delay: 0, error_rate: 0, crash: false, cpu_load: 0, memory_load: 0, packet_loss: 0 };
const payload = { ...current, [type]: val };
try {
await fetch(`${API_URL}/api/chaos/inject/${service}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
fetchChaosStatus();
} catch (err) {
console.error(err);
}
};
const clearChaos = async (service) => {
try {
await fetch(`${API_URL}/api/chaos/clear/${service}`, {
method: 'POST'
});
fetchChaosStatus();
} catch (err) {
console.error(err);
}
};
const updateGeneratorRps = async (rps) => {
setGeneratorRps(rps);
try {
await fetch(`${API_URL}/api/generator/rps?rps=${rps}`, {
method: 'POST'
});
} catch (err) {
console.error(err);
}
};
const runResilienceBenchmark = async (hasProtection) => {
setBenchmarkLoading(true);
try {
await fetch(`${API_URL}/api/benchmark/start?test_name=${hasProtection ? "With PulseGuard Protection" : "Without Protection"}&has_protection=${hasProtection}`, {
method: 'POST'
});
alert("Benchmark started! It will run in the background for 30s. Observe metrics live.");
setTimeout(() => {
fetchBenchmarks();
setBenchmarkLoading(false);
}, 28000);
} catch (err) {
console.error(err);
setBenchmarkLoading(false);
}
};
const handleLogin = () => {
setIsLoggedIn(true);
localStorage.setItem('pulseguard_logged_in', 'true');
};
const handleLogout = () => {
setIsLoggedIn(false);
localStorage.setItem('pulseguard_logged_in', 'false');
};
const getStatusColor = (status) => {
if (status === 'HEALTHY') return 'text-emerald-400';
if (status === 'DEGRADED') return 'text-amber-400';
if (status === 'CRITICAL') return 'text-red-400';
return 'text-blue-400';
};
const getStatusBg = (status) => {
if (status === 'HEALTHY') return 'glass-panel-glow-green border-emerald-500/20';
if (status === 'DEGRADED') return 'bg-amber-500/5 border-amber-500/20 shadow-glow-yellow';
if (status === 'CRITICAL') return 'glass-panel-glow-red border-red-500/20';
return 'glass-panel-glow-blue border-blue-500/20';
};
const getCircuitColor = (state) => {
if (state === 'CLOSED') return 'bg-emerald-500/20 text-emerald-400 border border-emerald-500/30';
if (state === 'OPEN') return 'bg-rose-500/20 text-rose-400 border border-rose-500/30';
return 'bg-blue-500/20 text-blue-400 border border-blue-500/30';
};
// 1. PUBLIC MARKETING LANDING PAGE
if (!isLoggedIn) {
return (
<div className="min-h-screen bg-[#06090D] text-slate-100 flex flex-col font-sans">
{/* Navbar */}
<header className="h-20 border-b border-slate-900 px-8 flex items-center justify-between bg-darkCard/30 backdrop-blur sticky top-0 z-50">
<div className="flex items-center gap-3">
<div className="h-9 w-9 rounded-lg bg-emerald-500 flex items-center justify-center shadow-lg shadow-emerald-500/20">
<Activity className="h-5 w-5 text-slate-900" />
</div>
<div>
<h1 className="font-bold text-lg tracking-wider text-white">PULSEGUARD X</h1>
<p className="text-[10px] text-slate-500 font-mono tracking-widest uppercase">Self-Healing Plane</p>
</div>
</div>
<nav className="hidden md:flex gap-8 text-sm font-medium text-slate-400">
<a href="#features" className="hover:text-white transition-colors">Features</a>
<a href="#simulator" className="hover:text-white transition-colors">Interactive Demo</a>
<a href="#pricing" className="hover:text-white transition-colors">Pricing</a>
<a href="https://localhost.run/docs/" target="_blank" rel="noreferrer" className="hover:text-white transition-colors">Docs</a>
</nav>
<button
onClick={handleLogin}
className="px-5 py-2.5 rounded-lg bg-emerald-500 text-slate-950 font-bold text-sm hover:bg-emerald-400 transition-all shadow-lg shadow-emerald-500/20 flex items-center gap-2"
>
Enter Cockpit
<ArrowRight className="h-4 w-4" />
</button>
</header>
{/* Hero Section */}
<section className="py-20 px-8 max-w-6xl mx-auto flex flex-col lg:flex-row items-center gap-12 flex-1">
<div className="flex-1 space-y-6 text-left">
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-emerald-500/10 border border-emerald-500/20 text-xs font-mono font-bold text-emerald-400 uppercase tracking-wider">
<Shield className="h-3 w-3" />
SOC2 Type II Compliant Autonomous Plane
</div>
<h2 className="text-4xl lg:text-6xl font-extrabold text-white leading-tight">
Self-Healing <span className="text-transparent bg-clip-text bg-gradient-to-r from-emerald-400 to-teal-300">Resiliency</span> for Microservices
</h2>
<p className="text-slate-400 text-base lg:text-lg leading-relaxed">
Stop cascading service failures in real time. PulseGuard X intercepts downstream bottlenecks, propagates upstream backpressure, manages token-bucket rate limits, and automatically heals degraded states.
</p>
<div className="flex flex-wrap gap-4 pt-2">
<button
onClick={handleLogin}
className="px-6 py-3 rounded-lg bg-emerald-500 text-slate-900 font-bold hover:bg-emerald-400 transition-all flex items-center gap-2 shadow-lg shadow-emerald-500/25"
>
Launch Live Platform
<ArrowRight className="h-4 w-4" />
</button>
<a
href="#simulator"
className="px-6 py-3 rounded-lg bg-slate-900 border border-slate-800 text-slate-200 font-bold hover:bg-slate-800 transition-all flex items-center justify-center"
>
Try Sandbox Demo
</a>
</div>
</div>
<div className="flex-1 w-full max-w-md lg:max-w-none">
<InteractivePlayground />
</div>
</section>
{/* Features Section */}
<section id="features" className="py-24 bg-darkCard/20 border-t border-slate-900/60 px-8">
<div className="max-w-6xl mx-auto space-y-12">
<div className="text-center max-w-2xl mx-auto space-y-3">
<h3 className="text-xs font-mono font-bold text-emerald-400 uppercase tracking-widest">Enterprise Architecture</h3>
<h2 className="text-2xl lg:text-3xl font-bold text-white">Engineered for Microservice Autonomy</h2>
<p className="text-slate-500 text-sm">
Built to protect complex, distributed call chains (A → B → C) without human operator latency.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
<div className="glass-panel p-8 rounded-xl border border-slate-800/80 hover:border-emerald-500/30 transition-all duration-300">
<div className="h-10 w-10 rounded-lg bg-emerald-500/10 flex items-center justify-center mb-6">
<Lock className="h-5 w-5 text-emerald-400" />
</div>
<h4 className="text-white font-bold text-base mb-3 font-mono">Token Bucket Lua Engine</h4>
<p className="text-slate-400 text-xs leading-relaxed">
Distributed, high-concurrency rate limiting executing atomic refill operations in Redis Lua. Prevents race conditions.
</p>
</div>
<div className="glass-panel p-8 rounded-xl border border-slate-800/80 hover:border-emerald-500/30 transition-all duration-300">
<div className="h-10 w-10 rounded-lg bg-emerald-500/10 flex items-center justify-center mb-6">
<ShieldAlert className="h-5 w-5 text-emerald-400" />
</div>
<h4 className="text-white font-bold text-base mb-3 font-mono">Cascading Backpressure</h4>
<p className="text-slate-400 text-xs leading-relaxed">
Automatic upstream limit clamps and custom HTTP backpressure header propagation to prevent cascading connection queue locks.
</p>
</div>
<div className="glass-panel p-8 rounded-xl border border-slate-800/80 hover:border-emerald-500/30 transition-all duration-300">
<div className="h-10 w-10 rounded-lg bg-emerald-500/10 flex items-center justify-center mb-6">
<RefreshCw className="h-5 w-5 text-emerald-400" />
</div>
<h4 className="text-white font-bold text-base mb-3 font-mono">Anti-Flapping Controls</h4>
<p className="text-slate-400 text-xs leading-relaxed">
Exponential Moving Average (EMA) latency monitoring and multi-tick validation prevent circuit breakers from flapping under transient spikes.
</p>
</div>
</div>
</div>
</section>
{/* Simulator CTA */}
<section id="simulator" className="py-16 px-8 max-w-4xl mx-auto text-center space-y-6">
<h2 className="text-2xl font-bold text-white">Experience Self-Healing Actions Live</h2>
<p className="text-slate-400 text-sm">
Launch the live cockpit to run traffic generators, inject real chaos CPU/RAM loads, and analyze live Prometheus and Grafana dashboards in real time.
</p>
<div className="pt-2">
<button
onClick={handleLogin}
className="px-6 py-3 rounded-lg bg-emerald-500 text-slate-900 font-bold hover:bg-emerald-400 transition-all shadow-lg shadow-emerald-500/20"
>
Enter Sandbox Cockpit
</button>
</div>
</section>
{/* Pricing Section */}
<section id="pricing" className="py-24 bg-darkCard/20 border-t border-slate-900/60 px-8">
<div className="max-w-5xl mx-auto space-y-12">
<div className="text-center max-w-2xl mx-auto space-y-3">
<h3 className="text-xs font-mono font-bold text-emerald-400 uppercase tracking-widest">SaaS Licensing</h3>
<h2 className="text-2xl lg:text-3xl font-bold text-white">Transparent Plans for Every Stack</h2>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{/* Free Tier */}
<div className="glass-panel p-8 rounded-xl border border-slate-800/80 flex flex-col justify-between">
<div>
<h4 className="text-slate-400 text-xs font-mono uppercase">Developer Sandbox</h4>
<p className="text-2xl font-extrabold text-white mt-2">$0</p>
<p className="text-[10px] text-slate-500 font-mono">Free Forever</p>
<ul className="mt-6 space-y-3 text-xs text-slate-400 font-mono">
<li className="flex items-center gap-2">✓ Service Chain: A → B → C</li>
<li className="flex items-center gap-2">✓ Real Redis Token Bucket</li>
<li className="flex items-center gap-2">✓ Live Chaos Injector</li>
</ul>
</div>
<button onClick={handleLogin} className="mt-8 w-full py-2 bg-slate-800 hover:bg-slate-700 text-slate-200 text-xs font-bold font-mono rounded">
Launch Sandbox
</button>
</div>
{/* Pro Tier */}
<div className="glass-panel p-8 rounded-xl border-2 border-emerald-500/30 flex flex-col justify-between relative shadow-lg shadow-emerald-500/5">
<div className="absolute -top-3.5 left-1/2 -translate-x-1/2 bg-emerald-500 text-slate-950 text-[10px] font-extrabold px-3 py-1 rounded-full uppercase tracking-wider">
Most Popular
</div>
<div>
<h4 className="text-emerald-400 text-xs font-mono uppercase">Production Pro</h4>
<p className="text-2xl font-extrabold text-white mt-2">$49<span className="text-xs font-mono text-slate-500">/mo</span></p>
<p className="text-[10px] text-slate-500 font-mono">Per cluster node</p>
<ul className="mt-6 space-y-3 text-xs text-slate-400 font-mono">
<li className="flex items-center gap-2 text-white">✓ Everything in Free</li>
<li className="flex items-center gap-2">✓ Persistent Postgres Logs</li>
<li className="flex items-center gap-2">✓ Dynamic SLO Overrides</li>
<li className="flex items-center gap-2">✓ Slack/OpsGenie Alerts</li>
</ul>
</div>
<button onClick={handleLogin} className="mt-8 w-full py-2 bg-emerald-500 hover:bg-emerald-400 text-slate-950 text-xs font-extrabold font-mono rounded shadow-lg shadow-emerald-500/10">
Upgrade to Pro
</button>
</div>
{/* Enterprise Tier */}
<div className="glass-panel p-8 rounded-xl border border-slate-800/80 flex flex-col justify-between">
<div>
<h4 className="text-slate-400 text-xs font-mono uppercase">Custom Enterprise</h4>
<p className="text-2xl font-extrabold text-white mt-2">Custom</p>
<p className="text-[10px] text-slate-500 font-mono">Custom SLA contract</p>
<ul className="mt-6 space-y-3 text-xs text-slate-400 font-mono">
<li className="flex items-center gap-2">✓ Unlimited Clusters</li>
<li className="flex items-center gap-2">✓ Custom Lua Scripts</li>
<li className="flex items-center gap-2">✓ 24/7 SRE Phone Support</li>
</ul>
</div>
<button onClick={handleLogin} className="mt-8 w-full py-2 bg-slate-800 hover:bg-slate-700 text-slate-200 text-xs font-bold font-mono rounded">
Contact Sales
</button>
</div>
</div>
</div>
</section>
{/* Footer */}
<footer className="border-t border-slate-900 bg-slate-950/40 py-12 px-8 mt-auto">
<div className="max-w-6xl mx-auto flex flex-col md:flex-row justify-between items-center gap-6">
<div className="flex items-center gap-2">
<Activity className="h-4 w-4 text-emerald-400" />
<span className="font-bold text-xs tracking-wider text-white uppercase">PulseGuard X</span>
</div>
<div className="flex gap-6 text-xs text-slate-500 font-mono">
<a href="#" className="hover:text-slate-300">Terms of Use</a>
<span></span>
<a href="#" className="hover:text-slate-300">Privacy Policy</a>
<span></span>
<a href="#" className="hover:text-slate-300">SOC2 Trust Report</a>
</div>
<div className="text-[10px] text-slate-600 font-mono">
© {new Date().getFullYear()} PulseGuard Inc. All rights reserved.
</div>
</div>
</footer>
</div>
);
}
// 2. DASHBOARD APPLICATION COCKPIT (AFTER LOGIN)
return (
<div className="flex h-screen bg-[#06090D] text-slate-100 overflow-hidden font-sans">
{/* Sidebar */}
<aside className="w-64 bg-darkCard border-r border-slate-900/60 flex flex-col justify-between shrink-0">
<div>
{/* Logo */}
<div className="p-6 border-b border-slate-900/60 flex items-center gap-3">
<div className="h-9 w-9 rounded-lg bg-emerald-500 flex items-center justify-center shadow-lg shadow-emerald-500/20">
<Activity className="h-5 w-5 text-slate-900" />
</div>
<div>
<h1 className="font-bold text-lg tracking-wider text-white">PULSEGUARD X</h1>
<p className="text-[10px] text-slate-500 font-mono tracking-widest uppercase">Self-Healing Plane</p>
</div>
</div>
{/* Navigation Links */}
<nav className="p-4 space-y-1">
<button
onClick={() => setActiveTab('landing')}
className={`w-full flex items-center gap-3 px-4 py-2.5 rounded-lg text-sm transition-all duration-150 ${activeTab === 'landing' ? 'bg-emerald-500/10 text-emerald-400 font-medium' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-800/40'}`}
>
<Info className="h-4 w-4" />
<span>Cockpit Overview</span>
</button>
<button
onClick={() => setActiveTab('dashboard')}
className={`w-full flex items-center gap-3 px-4 py-2.5 rounded-lg text-sm transition-all duration-150 ${activeTab === 'dashboard' ? 'bg-emerald-500/10 text-emerald-400 font-medium' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-800/40'}`}
>
<Activity className="h-4 w-4" />
<span>Reliability Dashboard</span>
</button>
<button
onClick={() => setActiveTab('topology')}
className={`w-full flex items-center gap-3 px-4 py-2.5 rounded-lg text-sm transition-all duration-150 ${activeTab === 'topology' ? 'bg-emerald-500/10 text-emerald-400 font-medium' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-800/40'}`}
>
<Map className="h-4 w-4" />
<span>Network Topology</span>
</button>
<button
onClick={() => setActiveTab('chaos')}
className={`w-full flex items-center gap-3 px-4 py-2.5 rounded-lg text-sm transition-all duration-150 ${activeTab === 'chaos' ? 'bg-emerald-500/10 text-emerald-400 font-medium' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-800/40'}`}
>
<Flame className="h-4 w-4" />
<span>Chaos Engineering</span>
</button>
<button
onClick={() => setActiveTab('control-plane')}
className={`w-full flex items-center gap-3 px-4 py-2.5 rounded-lg text-sm transition-all duration-150 ${activeTab === 'control-plane' ? 'bg-emerald-500/10 text-emerald-400 font-medium' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-800/40'}`}
>
<Terminal className="h-4 w-4" />
<span>Control Decisions</span>
</button>
<button
onClick={() => setActiveTab('timeline')}
className={`w-full flex items-center gap-3 px-4 py-2.5 rounded-lg text-sm transition-all duration-150 ${activeTab === 'timeline' ? 'bg-emerald-500/10 text-emerald-400 font-medium' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-800/40'}`}
>
<History className="h-4 w-4" />
<span>Reliability Timeline</span>
</button>
<button
onClick={() => setActiveTab('benchmarks')}
className={`w-full flex items-center gap-3 px-4 py-2.5 rounded-lg text-sm transition-all duration-150 ${activeTab === 'benchmarks' ? 'bg-emerald-500/10 text-emerald-400 font-medium' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-800/40'}`}
>
<TrendingUp className="h-4 w-4" />
<span>Resilience Benchmarks</span>
</button>
<button
onClick={() => setActiveTab('architecture')}
className={`w-full flex items-center gap-3 px-4 py-2.5 rounded-lg text-sm transition-all duration-150 ${activeTab === 'architecture' ? 'bg-emerald-500/10 text-emerald-400 font-medium' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-800/40'}`}
>
<Network className="h-4 w-4" />
<span>System Topology Map</span>
</button>
<button
onClick={() => setActiveTab('observability')}
className={`w-full flex items-center gap-3 px-4 py-2.5 rounded-lg text-sm transition-all duration-150 ${activeTab === 'observability' ? 'bg-emerald-500/10 text-emerald-400 font-medium' : 'text-slate-400 hover:text-slate-200 hover:bg-slate-800/40'}`}
>
<Database className="h-4 w-4" />
<span>Observability Hub</span>
</button>
</nav>
</div>
{/* Footer info */}
<div className="p-4 border-t border-slate-900/60 space-y-3 bg-slate-950/20">
<div className="flex items-center justify-between text-xs font-mono">
<span className="text-slate-500">Control Plane:</span>
<span className={`flex items-center gap-1.5 font-medium ${connected ? 'text-emerald-400' : 'text-rose-400 animate-pulse'}`}>
<span className={`h-1.5 w-1.5 rounded-full ${connected ? 'bg-emerald-400' : 'bg-rose-400'}`} />
{connected ? 'CONNECTED' : 'DISCONNECTED'}
</span>
</div>
<button
onClick={handleLogout}
className="w-full flex items-center justify-center gap-2 py-2 border border-slate-800 hover:bg-slate-800/50 rounded-lg text-xs font-mono text-slate-400 hover:text-white transition-all"
>
<LogOut className="h-3.5 w-3.5" />
Sign Out
</button>
<div className="text-[10px] text-slate-600 font-mono text-center">
PULSEGUARD v1.0.0
</div>
</div>
</aside>
{/* Main Content Area */}
<main className="flex-1 flex flex-col min-w-0 bg-[#06090D] overflow-y-auto">
{/* Header */}
<header className="h-16 border-b border-slate-900/60 flex items-center justify-between px-8 bg-darkCard/30 backdrop-blur shrink-0 z-10 sticky top-0">
<div className="flex items-center gap-4">
<h2 className="text-sm font-bold text-white uppercase tracking-wider font-mono">
{activeTab.replace('-', ' ')}
</h2>
</div>
<div className="flex items-center gap-4">
{/* Quick System Health Metric */}
<div className="flex items-center gap-6 text-xs text-slate-400 font-mono">
<div className="flex items-center gap-2">
<span>Active RPS:</span>
<span className="text-white font-semibold">
{((data.services["service-a"]?.rps || 0) + (data.services["service-b"]?.rps || 0) + (data.services["service-c"]?.rps || 0)).toFixed(1)}
</span>
</div>
<div className="flex items-center gap-2">
<span>Avg Latency (P95):</span>
<span className="text-white font-semibold">
{((((data.services["service-a"]?.p95 || 0) + (data.services["service-b"]?.p95 || 0) + (data.services["service-c"]?.p95 || 0)) / 3) * 1000).toFixed(0)}ms
</span>
</div>
</div>
</div>
</header>
{/* Tab Switchboard */}
<div className="flex-1 p-8">
{/* Landing Page (Cockpit Overview) */}
{activeTab === 'landing' && (
<div className="max-w-4xl mx-auto space-y-8">
<div className="bg-gradient-to-r from-emerald-500/10 via-teal-500/5 to-transparent border border-emerald-500/20 rounded-xl p-8 shadow-xl relative overflow-hidden">
<div className="absolute top-0 right-0 w-64 h-64 bg-emerald-500/5 rounded-full filter blur-3xl pointer-events-none" />
<h3 className="text-2xl font-bold text-white mb-2">PulseGuard X Reliability Control Plane</h3>
<p className="text-slate-400 text-sm max-w-2xl leading-relaxed mb-6">
You are logged into the active cluster node cockpit. PulseGuard X manages distributed token-bucket rate limits, circuit breakers, and cascading backpressure propagation across this service grid.
</p>
<div className="flex gap-4">
<button
onClick={() => setActiveTab('dashboard')}
className="px-5 py-2.5 rounded-lg bg-emerald-500 text-slate-900 font-semibold text-sm hover:bg-emerald-400 transition-all flex items-center gap-2 shadow-lg shadow-emerald-500/20"
>
<Zap className="h-4 w-4 fill-slate-900" />
Enter Dashboard
</button>
<button
onClick={() => setActiveTab('chaos')}
className="px-5 py-2.5 rounded-lg bg-slate-800 border border-slate-700 text-slate-200 font-semibold text-sm hover:bg-slate-700 transition-all"
>
Launch Chaos Testing
</button>
</div>
</div>
{/* Core Capabilities */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="glass-panel p-6 rounded-xl border border-slate-800/80">
<h4 className="text-white font-bold text-sm tracking-wider uppercase mb-4 flex items-center gap-2">
<CheckCircle className="h-4 w-4 text-emerald-400" />
Core Platform Capabilities
</h4>
<ul className="space-y-3 text-slate-400 text-sm font-mono">
<li className="flex gap-3"><span className="text-emerald-400">01.</span> Distributed Token Bucket Lua Rate Limiter</li>
<li className="flex gap-3"><span className="text-emerald-400">02.</span> Dynamic Latency & Error Rate Clamping</li>
<li className="flex gap-3"><span className="text-emerald-400">03.</span> Closed/Open/Half-Open Circuit Breaker States</li>
<li className="flex gap-3"><span className="text-emerald-400">04.</span> Real-time Cascading Backpressure Clamps</li>
<li className="flex gap-3"><span className="text-emerald-400">05.</span> Statistical Anomaly Detection & Flapping Protections</li>
</ul>
</div>
<div className="glass-panel p-6 rounded-xl border border-slate-800/80">
<h4 className="text-white font-bold text-sm tracking-wider uppercase mb-4 flex items-center gap-2">
<Settings className="h-4 w-4 text-emerald-400" />
Production Environment Stack
</h4>
<div className="grid grid-cols-2 gap-4 text-xs font-mono text-slate-500">
<div>
<p className="text-slate-300 font-semibold">Backend Service</p>
<p>FastAPI, AsyncIO, Uvicorn</p>
<p className="mt-2 text-slate-300 font-semibold">Distributed Cache</p>
<p>Redis Cluster (Lua Scripts)</p>
</div>
<div>
<p className="text-slate-300 font-semibold">Relational Database</p>
<p>PostgreSQL (SQLAlchemy)</p>
<p className="mt-2 text-slate-300 font-semibold">Telemetry & Scraping</p>
<p>Prometheus & Grafana</p>
</div>
</div>
</div>
</div>
{/* SLO & Compliance */}
<div className="glass-panel p-6 rounded-xl border border-slate-800/80">
<h4 className="text-white font-bold text-sm tracking-wider uppercase mb-4 flex items-center gap-2">
<ShieldAlert className="h-4 w-4 text-emerald-400" />
Service Level Objectives (SLO) & Security Compliance
</h4>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4 text-xs font-mono">
<div className="bg-slate-950/40 p-4 rounded-lg border border-slate-900/60">
<p className="text-slate-500">SYSTEM SLO TARGET</p>
<p className="text-emerald-400 font-bold text-sm mt-1">99.99% Availability</p>
<p className="text-[10px] text-slate-600 mt-2">Active threshold monitoring & self-healing active</p>
</div>
<div className="bg-slate-950/40 p-4 rounded-lg border border-slate-900/60">
<p className="text-slate-500">MUTUAL TLS (mTLS)</p>
<p className="text-emerald-400 font-bold text-sm mt-1">ENFORCED (100%)</p>
<p className="text-[10px] text-slate-600 mt-2">All downstream calls protected by mTLS encryption</p>
</div>
<div className="bg-slate-950/40 p-4 rounded-lg border border-slate-900/60">
<p className="text-slate-500">AUDIT COMPLIANCE</p>
<p className="text-emerald-400 font-bold text-sm mt-1">SOC2 TYPE II COMPLIANT</p>
<p className="text-[10px] text-slate-600 mt-2">Historical decision records stored in persistent SQL store</p>
</div>
</div>
</div>
</div>
)}
{/* Reliability Dashboard */}
{activeTab === 'dashboard' && (
<div className="space-y-8">
{/* Active Pipeline visualization */}
<div className="glass-panel p-8 rounded-xl border border-slate-800/80 shadow-md">
<h3 className="text-slate-400 font-bold text-xs uppercase tracking-wider mb-6 font-mono">Service-to-Service Chain</h3>
{/* SVG Live pipeline with particle animations */}
<div className="relative flex justify-between items-center py-8">
<svg className="absolute inset-0 w-full h-full pointer-events-none" style={{ minHeight: '120px' }}>
<defs>
<linearGradient id="grad-ab" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stopColor="#10B981" />
<stop offset="100%" stopColor={data.services["service-b"]?.status === 'CRITICAL' ? '#EF4444' : '#10B981'} />
</linearGradient>
<linearGradient id="grad-bc" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stopColor={data.services["service-b"]?.status === 'CRITICAL' ? '#EF4444' : '#10B981'} />
<stop offset="100%" stopColor={data.services["service-c"]?.status === 'CRITICAL' ? '#EF4444' : '#10B981'} />
</linearGradient>
</defs>
{/* Path Client -> A */}
<path id="path-client-a" d="M 50 60 L 220 60" stroke="#1D2433" strokeWidth="3" fill="none" strokeDasharray="5,5" />
{/* Path A -> B */}
<path id="path-a-b" d="M 320 60 L 520 60" stroke="url(#grad-ab)" strokeWidth="3" fill="none" />
{/* Path B -> C */}
<path id="path-b-c" d="M 620 60 L 820 60" stroke="url(#grad-bc)" strokeWidth="3" fill="none" />
{/* Animated Particles flowing. Speed depends on RPS. */}
{data.services["service-a"]?.rps > 0 && (
<circle r="4" fill="#10B981">
<animateMotion dur={`${Math.max(0.3, 4 / (data.services["service-a"].rps || 1))}s`} repeatCount="indefinite" path="M 50 60 L 220 60" />
</circle>
)}
{data.services["service-b"]?.rps > 0 && data.services["service-b"]?.circuit_state !== 'OPEN' && (
<circle r="4" fill={data.services["service-b"]?.status === 'CRITICAL' ? '#EF4444' : '#10B981'}>
<animateMotion dur={`${Math.max(0.3, 4 / (data.services["service-b"].rps || 1))}s`} repeatCount="indefinite" path="M 320 60 L 520 60" />
</circle>
)}
{data.services["service-c"]?.rps > 0 && data.services["service-c"]?.circuit_state !== 'OPEN' && (
<circle r="4" fill={data.services["service-c"]?.status === 'CRITICAL' ? '#EF4444' : '#10B981'}>
<animateMotion dur={`${Math.max(0.3, 4 / (data.services["service-c"].rps || 1))}s`} repeatCount="indefinite" path="M 620 60 L 820 60" />
</circle>
)}
</svg>
{/* Node: Client */}
<div className="z-10 bg-slate-900 border border-slate-800 rounded-lg p-3 text-center w-28 shadow-lg">
<p className="text-[10px] text-slate-500 font-mono uppercase font-semibold">Source</p>
<p className="text-sm font-bold text-white">Client / Gen</p>
<div className="mt-2 text-[10px] bg-slate-950 text-slate-400 py-1 rounded font-mono border border-slate-900">
RPS: {generatorRps}
</div>
</div>
{/* Node: Service A */}
<div className={`z-10 border rounded-lg p-4 text-center w-36 shadow-lg bg-darkCard transition-all ${getStatusBg(data.services["service-a"]?.status)}`}>
<p className="text-[10px] text-slate-500 font-mono uppercase font-semibold">Microservice A</p>
<p className="text-sm font-bold text-white">Ingress Proxy</p>
<div className="mt-2 space-y-1 text-left text-[10px] font-mono text-slate-400">
<div className="flex justify-between"><span>RPS:</span><span className="text-white">{data.services["service-a"]?.rps.toFixed(1)}</span></div>
<div className="flex justify-between"><span>Limit:</span><span className="text-emerald-400">{data.services["service-a"]?.limit_capacity} RPS</span></div>
<div className="flex justify-between"><span>P95:</span><span className="text-white">{((data.services["service-a"]?.p95 || 0) * 1000).toFixed(0)}ms</span></div>
</div>
</div>
{/* Node: Service B */}
<div className={`z-10 border rounded-lg p-4 text-center w-36 shadow-lg bg-darkCard transition-all ${getStatusBg(data.services["service-b"]?.status)}`}>
<p className="text-[10px] text-slate-500 font-mono uppercase font-semibold">Microservice B</p>
<p className="text-sm font-bold text-white">Auth / Routing</p>
<div className="mt-2 space-y-1 text-left text-[10px] font-mono text-slate-400">
<div className="flex justify-between"><span>RPS:</span><span className="text-white">{data.services["service-b"]?.rps.toFixed(1)}</span></div>
<div className="flex justify-between"><span>CB state:</span><span className="text-white">{data.services["service-b"]?.circuit_state}</span></div>
<div className="flex justify-between"><span>P95:</span><span className="text-white">{((data.services["service-b"]?.p95 || 0) * 1000).toFixed(0)}ms</span></div>
</div>
</div>
{/* Node: Service C */}
<div className={`z-10 border rounded-lg p-4 text-center w-36 shadow-lg bg-darkCard transition-all ${getStatusBg(data.services["service-c"]?.status)}`}>
<p className="text-[10px] text-slate-500 font-mono uppercase font-semibold">Microservice C</p>
<p className="text-sm font-bold text-white">Database Hop</p>
<div className="mt-2 space-y-1 text-left text-[10px] font-mono text-slate-400">
<div className="flex justify-between"><span>RPS:</span><span className="text-white">{data.services["service-c"]?.rps.toFixed(1)}</span></div>
<div className="flex justify-between"><span>CB state:</span><span className="text-white">{data.services["service-c"]?.circuit_state}</span></div>
<div className="flex justify-between"><span>P95:</span><span className="text-white">{((data.services["service-c"]?.p95 || 0) * 1000).toFixed(0)}ms</span></div>
</div>
</div>
</div>
</div>
{/* Grid of details for A, B, C */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{['service-a', 'service-b', 'service-c'].map((s) => {
const sData = data.services[s];
if (!sData) return null;
return (
<div key={s} className="glass-panel p-6 rounded-xl border border-slate-800/80 space-y-4 shadow-md">
<div className="flex justify-between items-center pb-2 border-b border-slate-900/60">
<span className="font-bold text-white uppercase text-xs font-mono tracking-wider">{s}</span>
<span className={`text-xs font-bold px-2.5 py-0.5 rounded-full ${getStatusColor(sData.status)} bg-slate-950 border border-slate-900/60`}>
{sData.status}
</span>
</div>
<div className="grid grid-cols-2 gap-4 text-xs font-mono text-slate-400">
<div>
<p>Current RPS</p>
<p className="text-white text-lg font-bold mt-1">{sData.rps.toFixed(1)}</p>
</div>
<div>
<p>Token Limit</p>
<p className="text-emerald-400 text-lg font-bold mt-1">{sData.limit_capacity} RPS</p>
</div>
<div>
<p>Error Rate</p>
<p className={`text-lg font-bold mt-1 ${sData.error_rate > 0 ? 'text-red-400' : 'text-slate-300'}`}>
{(sData.error_rate * 100).toFixed(1)}%
</p>
</div>
<div>
<p>P95 Latency</p>
<p className="text-white text-lg font-bold mt-1">{(sData.p95 * 1000).toFixed(0)}ms</p>
</div>
</div>
{/* Circuit Breaker Status Indicator */}
<div className="flex items-center justify-between bg-slate-950/40 p-3 rounded-lg border border-slate-900/60">
<span className="text-[10px] text-slate-500 font-mono uppercase font-semibold">Circuit Breaker:</span>
<span className={`text-[10px] font-bold px-2 py-0.5 rounded-full ${getCircuitColor(sData.circuit_state)}`}>
{sData.circuit_state}
</span>
</div>
</div>
);
})}
</div>
{/* Real-time latency chart */}
<div className="glass-panel p-6 rounded-xl border border-slate-800/80 shadow-md">
<h4 className="text-white font-bold text-xs uppercase tracking-wider mb-6 font-mono">Real-Time Latency Trends (P95 ms)</h4>
<div className="h-64">
{history.length === 0 ? (
<div className="h-full flex items-center justify-center text-slate-600 font-mono text-sm">
Collecting telemetry streams...
</div>
) : (
<ResponsiveContainer width="100%" height="100%">
<AreaChart data={history}>
<defs>
<linearGradient id="colA" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#10B981" stopOpacity={0.2}/>
<stop offset="95%" stopColor="#10B981" stopOpacity={0}/>
</linearGradient>
<linearGradient id="colB" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#3B82F6" stopOpacity={0.2}/>
<stop offset="95%" stopColor="#3B82F6" stopOpacity={0}/>
</linearGradient>
<linearGradient id="colC" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#F59E0B" stopOpacity={0.2}/>
<stop offset="95%" stopColor="#F59E0B" stopOpacity={0}/>
</linearGradient>
</defs>
<CartesianGrid stroke="#1D2433" strokeDasharray="3 3" />
<XAxis dataKey="time" stroke="#21262D" tick={{ fontSize: 10, fontFamily: 'JetBrains Mono' }} />
<YAxis stroke="#21262D" tick={{ fontSize: 10, fontFamily: 'JetBrains Mono' }} unit="ms" />
<Tooltip contentStyle={{ backgroundColor: '#0E121B', borderColor: '#1D2433', color: '#FFF', fontFamily: 'JetBrains Mono' }} />
<Legend wrapperStyle={{ fontSize: 11, fontFamily: 'Inter' }} />
<Area type="monotone" dataKey="Service A Latency" stroke="#10B981" fillOpacity={1} fill="url(#colA)" />
<Area type="monotone" dataKey="Service B Latency" stroke="#3B82F6" fillOpacity={1} fill="url(#colB)" />
<Area type="monotone" dataKey="Service C Latency" stroke="#F59E0B" fillOpacity={1} fill="url(#colC)" />
</AreaChart>
</ResponsiveContainer>
)}
</div>
</div>
</div>
)}
{/* Network Topology Map */}
{activeTab === 'topology' && (
<div className="glass-panel p-8 rounded-xl border border-slate-800/80 shadow-md">
<h3 className="text-slate-400 font-bold text-xs uppercase tracking-wider mb-6 font-mono">Interactive Service Map</h3>
<div className="h-[400px] bg-slate-950/40 border border-slate-900/60 rounded-lg flex items-center justify-center relative overflow-hidden">
<div className="absolute top-6 left-6 text-xs text-slate-500 font-mono space-y-1">
<p>● Green: Healthy operation</p>
<p>● Yellow: Latency threshold breached / degraded limit applied</p>
<p>● Red: Critical failures / circuit open</p>
</div>
<div className="flex gap-16 items-center">
{/* Service A */}
<div className="flex flex-col items-center">
<div className={`h-24 w-24 rounded-full border-2 flex flex-col items-center justify-center transition-all bg-darkCard ${data.services["service-a"]?.status === 'HEALTHY' ? 'border-emerald-500 shadow-lg shadow-emerald-500/20' : data.services["service-a"]?.status === 'DEGRADED' ? 'border-amber-500 shadow-lg shadow-amber-500/20' : 'border-red-500 shadow-lg shadow-red-500/20'}`}>
<span className="text-xs font-bold text-white font-mono">Service A</span>
<span className="text-[10px] text-slate-500 mt-1 font-mono">Limits: {data.services["service-a"]?.limit_capacity} RPS</span>
</div>
</div>
<div className="w-16 h-0.5 bg-slate-800" />
{/* Service B */}
<div className="flex flex-col items-center">
<div className={`h-24 w-24 rounded-full border-2 flex flex-col items-center justify-center transition-all bg-darkCard ${data.services["service-b"]?.status === 'HEALTHY' ? 'border-emerald-500 shadow-lg shadow-emerald-500/20' : data.services["service-b"]?.status === 'DEGRADED' ? 'border-amber-500 shadow-lg shadow-amber-500/20' : 'border-red-500 shadow-lg shadow-red-500/20'}`}>
<span className="text-xs font-bold text-white font-mono">Service B</span>
<span className="text-[10px] text-slate-500 mt-1 font-mono">{data.services["service-b"]?.circuit_state}</span>
</div>
</div>
<div className="w-16 h-0.5 bg-slate-800" />
{/* Service C */}
<div className="flex flex-col items-center">
<div className={`h-24 w-24 rounded-full border-2 flex flex-col items-center justify-center transition-all bg-darkCard ${data.services["service-c"]?.status === 'HEALTHY' ? 'border-emerald-500 shadow-lg shadow-emerald-500/20' : data.services["service-c"]?.status === 'DEGRADED' ? 'border-amber-500 shadow-lg shadow-amber-500/20' : 'border-red-500 shadow-lg shadow-red-500/20'}`}>
<span className="text-xs font-bold text-white font-mono">Service C</span>
<span className="text-[10px] text-slate-500 mt-1 font-mono">{data.services["service-c"]?.circuit_state}</span>
</div>
</div>
</div>
</div>
</div>
)}
{/* Chaos Engineering */}
{activeTab === 'chaos' && (
<div className="space-y-6">
<div className="glass-panel p-6 rounded-xl border border-slate-800/80 shadow-md">
<h3 className="text-white font-bold text-sm tracking-wider uppercase mb-4 font-mono">Service Traffic Injection Panel</h3>
<div className="flex gap-4 items-center bg-slate-950/40 p-4 rounded-lg border border-slate-900/60 mb-6">
<span className="text-xs text-slate-400 font-mono">Adjust Client Traffic Rate (RPS):</span>
<div className="flex flex-wrap gap-2">
{[10, 50, 100, 200, 500, 1000].map(val => (
<button
key={val}
onClick={() => updateGeneratorRps(val)}
className={`px-3 py-1.5 rounded text-xs font-mono font-bold transition-all ${generatorRps === val ? 'bg-emerald-500 text-slate-950 shadow-md shadow-emerald-500/10' : 'bg-slate-800 text-slate-400 hover:text-white'}`}
>
{val} RPS
</button>
))}
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{['service-b', 'service-c'].map(service => {
const status = chaosState[service] || {};
return (
<div key={service} className="bg-slate-900/40 border border-slate-800/60 rounded-xl p-6 space-y-4">
<div className="flex justify-between items-center pb-2 border-b border-slate-800/60">
<span className="text-white font-bold text-xs uppercase font-mono tracking-wider">{service} Injection</span>
<button
onClick={() => clearChaos(service)}
className="text-[10px] font-bold text-slate-900 bg-rose-400 hover:bg-rose-300 px-3 py-1 rounded uppercase tracking-wider font-mono"
>
Reset Service
</button>
</div>
<div className="flex flex-wrap gap-2 py-1 text-[10px] font-mono">
{status.crash && <span className="bg-red-500/10 text-red-400 border border-red-500/20 px-2 py-0.5 rounded">CRASHED</span>}
{status.delay > 0 && <span className="bg-amber-500/10 text-amber-400 border border-amber-500/20 px-2 py-0.5 rounded">DELAY: {status.delay}s</span>}
{status.error_rate > 0 && <span className="bg-orange-500/10 text-orange-400 border border-orange-500/20 px-2 py-0.5 rounded">ERRORS: {status.error_rate * 100}%</span>}
{status.cpu_load > 0 && <span className="bg-blue-500/10 text-blue-400 border border-blue-500/20 px-2 py-0.5 rounded">CPU: {status.cpu_load * 100}%</span>}
</div>
<div className="space-y-4 pt-2">
<div className="flex justify-between items-center">
<span className="text-xs text-slate-400 font-mono">Crash Service:</span>
<button
onClick={() => triggerChaos(service, 'crash', !status.crash)}
className={`px-4 py-1.5 rounded text-xs font-mono font-bold transition-all ${status.crash ? 'bg-red-500 text-white' : 'bg-slate-800 text-slate-400 hover:text-white'}`}
>
{status.crash ? "Crashed (Recover)" : "Inject Crash"}
</button>
</div>
<div className="space-y-1">
<div className="flex justify-between text-xs font-mono text-slate-400">
<span>Inject Delay (Latency):</span>
<span className="text-white">{status.delay || 0}s</span>
</div>
<input
type="range" min="0" max="3" step="0.1"
value={status.delay || 0}
onChange={(e) => triggerChaos(service, 'delay', parseFloat(e.target.value))}
className="w-full h-1 bg-slate-800 rounded-lg appearance-none cursor-pointer accent-emerald-500"
/>
</div>
<div className="space-y-1">
<div className="flex justify-between text-xs font-mono text-slate-400">
<span>Inject Errors (HTTP 500 rate):</span>
<span className="text-white">{((status.error_rate || 0) * 100).toFixed(0)}%</span>
</div>
<input
type="range" min="0" max="1" step="0.1"
value={status.error_rate || 0}
onChange={(e) => triggerChaos(service, 'error_rate', parseFloat(e.target.value))}
className="w-full h-1 bg-slate-800 rounded-lg appearance-none cursor-pointer accent-emerald-500"
/>
</div>
</div>
</div>
);
})}
</div>
</div>
</div>
)}
{/* Control Decisions */}
{activeTab === 'control-plane' && (
<div className="space-y-6 max-w-4xl mx-auto">
<div className="glass-panel p-6 rounded-xl border border-slate-800/80 shadow-md">
<h3 className="text-white font-bold text-sm tracking-wider uppercase mb-4 font-mono">Controller Decision Engine (Audit Logs)</h3>
<div className="overflow-x-auto">
<table className="w-full text-left border-collapse text-xs font-mono">
<thead>
<tr className="border-b border-slate-800/80 text-slate-500 uppercase tracking-wider">
<th className="pb-3 pl-2">Timestamp</th>
<th className="pb-3">Service</th>
<th className="pb-3">Action</th>
<th className="pb-3">Transition</th>
<th className="pb-3">Reason</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-800/60 text-slate-300">
{data.audits.length === 0 ? (
<tr>
<td colSpan="5" className="py-6 text-center text-slate-600">No decisions logs in database yet. Run traffic to trigger limits.</td>
</tr>
) : (
data.audits.map(a => (
<tr key={a.id} className="hover:bg-slate-800/20">
<td className="py-3 pl-2 text-slate-500">{new Date(a.timestamp).toLocaleTimeString()}</td>
<td className="py-3 font-semibold text-white">{a.service}</td>
<td className="py-3">
<span className="bg-slate-950/40 text-slate-300 border border-slate-800/80 px-2 py-0.5 rounded">
{a.action}
</span>
</td>
<td className="py-3 text-emerald-400">
{a.old_value} → {a.new_value}
</td>
<td className="py-3 text-slate-400 truncate max-w-xs">{a.reason}</td>
</tr>
))
)}
</tbody>
</table>
</div>
</div>
</div>
)}
{/* Reliability Timeline */}
{activeTab === 'timeline' && (
<div className="max-w-3xl mx-auto space-y-6">
<div className="glass-panel p-6 rounded-xl border border-slate-800/80 shadow-md">
<h3 className="text-white font-bold text-sm tracking-wider uppercase mb-6 font-mono">Real-Time Event Log</h3>
<div className="relative border-l border-slate-800 ml-3 space-y-6">
{data.events.length === 0 ? (
<p className="text-sm font-mono text-slate-600 pl-6">No events captured yet.</p>
) : (
data.events.map(e => (
<div key={e.id} className="relative pl-6">
<div className={`absolute -left-1.5 top-1.5 h-3 w-3 rounded-full border-2 bg-darkBg ${e.severity === 'CRITICAL' ? 'border-red-500' : e.severity === 'WARNING' ? 'border-amber-500' : 'border-emerald-400'}`} />
<div className="space-y-1">
<div className="flex items-center gap-3">
<span className="text-[10px] font-mono text-slate-500">{new Date(e.timestamp).toLocaleTimeString()}</span>
<span className={`text-[10px] font-mono font-bold uppercase ${e.severity === 'CRITICAL' ? 'text-red-400' : e.severity === 'WARNING' ? 'text-amber-400' : 'text-emerald-400'}`}>
{e.event_type}
</span>
<span className="bg-slate-900 border border-slate-800 text-slate-400 text-[10px] font-mono px-1.5 py-0.5 rounded">
{e.service}
</span>
</div>
<p className="text-xs text-slate-300 font-mono">{e.message}</p>
</div>
</div>
))
)}
</div>
</div>
</div>
)}
{/* System Architecture Map */}
{activeTab === 'architecture' && (
<div className="max-w-4xl mx-auto space-y-6">
<div className="glass-panel p-8 rounded-xl border border-slate-800/80 shadow-md">
<h3 className="text-white font-bold text-sm tracking-wider uppercase mb-6 font-mono">System Components Interconnect</h3>
<div className="grid grid-cols-3 gap-6 text-center text-xs font-mono">
{/* Left Column: Client */}
<div className="border border-slate-800/80 rounded-xl p-4 bg-slate-950/20 space-y-4">
<p className="text-slate-400 font-bold uppercase border-b border-slate-800 pb-2">Client Ingress</p>
<div className="bg-darkCard border border-darkBorder rounded-lg p-3">
<p className="text-white font-bold">Load Generator</p>
<p className="text-[10px] text-slate-500 mt-1">Generates simulated customer traffic</p>
</div>
</div>
{/* Mid Column: Backend Stack */}
<div className="border border-slate-800/80 rounded-xl p-4 bg-slate-950/20 space-y-4">
<p className="text-slate-400 font-bold uppercase border-b border-slate-800 pb-2">Service Grid</p>
<div className="bg-darkCard border border-darkBorder rounded-lg p-3">
<p className="text-white font-bold">FastAPI Container Chain</p>
<p className="text-[10px] text-slate-500 mt-1">Service A → B → C (Runs telemetry & rate check)</p>
</div>
<div className="bg-darkCard border border-darkBorder rounded-lg p-3">
<p className="text-white font-bold">Redis Cluster</p>
<p className="text-[10px] text-slate-500 mt-1">Executes token bucket Lua & handles buffers</p>
</div>
</div>
{/* Right Column: Reliability Controller */}
<div className="border border-slate-800/80 rounded-xl p-4 bg-slate-950/20 space-y-4">
<p className="text-slate-400 font-bold uppercase border-b border-slate-800 pb-2">Control Plane</p>
<div className="bg-darkCard border border-darkBorder rounded-lg p-3">
<p className="text-white font-bold">Reliability Controller</p>
<p className="text-[10px] text-slate-500 mt-1">Loops every 2s, executes self-healing overrides</p>
</div>
<div className="bg-darkCard border border-darkBorder rounded-lg p-3">
<p className="text-white font-bold">PostgreSQL DB</p>
<p className="text-[10px] text-slate-500 mt-1">Maintains event audit trails & benchmarks</p>
</div>
</div>
</div>
</div>
</div>
)}
{/* Resilience Benchmarks */}
{activeTab === 'benchmarks' && (
<div className="space-y-6 max-w-4xl mx-auto">
<div className="glass-panel p-6 rounded-xl border border-slate-800/80 shadow-md">
<h3 className="text-white font-bold text-sm tracking-wider uppercase mb-4 font-mono">Platform Resilience Benchmarks</h3>
<p className="text-slate-400 text-xs mb-6 max-w-2xl leading-relaxed">
Trigger automated runs simulating failure injection on Service C under heavy traffic.
Compare statistics between unprotected setups (flapping, cascading timeouts) and protected configurations (automated limits, fail-fast, backpressure).
</p>
<div className="flex gap-4 mb-8">
<button
disabled={benchmarkLoading}
onClick={() => runResilienceBenchmark(true)}
className="px-5 py-2.5 rounded-lg bg-emerald-500 text-slate-900 font-bold text-xs hover:bg-emerald-400 transition-all flex items-center gap-2"
>
<Zap className="h-4 w-4 fill-slate-900" />
{benchmarkLoading ? "Running..." : "Run Test (WITH PROTECTION)"}
</button>
<button
disabled={benchmarkLoading}
onClick={() => runResilienceBenchmark(false)}
className="px-5 py-2.5 rounded-lg bg-rose-500 text-white font-bold text-xs hover:bg-rose-400 transition-all flex items-center gap-2"
>
<Flame className="h-4 w-4" />
{benchmarkLoading ? "Running..." : "Run Test (NO PROTECTION)"}
</button>
</div>
{/* Benchmark results database table */}
<div className="space-y-6">
<h4 className="text-white font-bold text-xs uppercase tracking-wider font-mono">Historical Runs</h4>
{benchmarks.length === 0 ? (
<div className="text-slate-600 font-mono text-xs py-4 text-center border border-slate-800/60 rounded-lg">
No benchmark data. Trigger a run to generate reports.
</div>
) : (
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="bg-slate-950/40 p-4 border border-slate-800/60 rounded-lg h-64">
<p className="text-slate-400 font-bold text-[10px] uppercase font-mono mb-4">Availability / Success Rate (%)</p>
<ResponsiveContainer width="100%" height="90%">
<BarChart data={benchmarks}>
<CartesianGrid stroke="#1D2433" strokeDasharray="3 3" />
<XAxis dataKey="test_name" stroke="#21262D" tick={{ fontSize: 9, fontFamily: 'JetBrains Mono' }} />
<YAxis stroke="#21262D" tick={{ fontSize: 10, fontFamily: 'JetBrains Mono' }} />
<Tooltip contentStyle={{ backgroundColor: '#0E121B', borderColor: '#1D2433', color: '#FFF' }} />
<Bar dataKey="success_rate" fill="#10B981" />
</BarChart>
</ResponsiveContainer>
</div>
<div className="space-y-3 overflow-y-auto max-h-64 pr-2">
{benchmarks.map(b => (
<div key={b.id} className="bg-slate-900/60 border border-slate-800/60 rounded-lg p-4 font-mono text-[10px] space-y-1">
<div className="flex justify-between font-bold text-white">
<span>{b.test_name}</span>
<span className={b.has_protection ? "text-emerald-400" : "text-rose-400"}>
{b.has_protection ? "PROTECTED" : "UNPROTECTED"}
</span>
</div>
<p className="text-slate-500">{new Date(b.timestamp).toLocaleString()}</p>
<div className="grid grid-cols-3 gap-2 pt-2 text-slate-400">
<div>Success: <span className="text-white font-bold">{(b.success_rate * 100).toFixed(1)}%</span></div>
<div>P95 Latency: <span className="text-white font-bold">{(b.p95_latency * 1000).toFixed(0)}ms</span></div>
<div>Requests: <span className="text-white font-bold">{b.total_requests}</span></div>
</div>
</div>
))}
</div>
</div>
)}
</div>
</div>
</div>
)}
{/* Observability Hub */}
{activeTab === 'observability' && (
<div className="max-w-6xl mx-auto space-y-8">
{/* Prometheus embedded Frame */}
<div className="glass-panel p-6 rounded-xl border border-slate-800/80 shadow-md">
<div className="flex justify-between items-center mb-4">
<h3 className="text-white font-bold text-xs uppercase tracking-wider font-mono">Prometheus Query Panel</h3>
<a
href="/prometheus/" target="_blank" rel="noreferrer"
className="text-[10px] bg-slate-800 border border-slate-700 text-slate-300 px-3 py-1.5 rounded hover:text-white font-mono"
>
Open Fullscreen
</a>
</div>
<iframe
src="/prometheus/"
title="Prometheus Console"
className="w-full h-[350px] border border-slate-800/80 rounded-lg bg-slate-950"
/>
</div>
{/* Grafana embedded Frame */}
<div className="glass-panel p-6 rounded-xl border border-slate-800/80 shadow-md">
<div className="flex justify-between items-center mb-4">
<h3 className="text-white font-bold text-xs uppercase tracking-wider font-mono">Grafana Cockpit Dashboard</h3>
<a
href="/grafana/" target="_blank" rel="noreferrer"
className="text-[10px] bg-slate-800 border border-slate-700 text-slate-300 px-3 py-1.5 rounded hover:text-white font-mono"
>
Open Fullscreen (Credentials: admin/admin)
</a>
</div>
<iframe
src="/grafana/"
title="Grafana Dashboard"
className="w-full h-[550px] border border-slate-800/80 rounded-lg bg-slate-950"
/>
</div>
</div>
)}
</div>
</main>
</div>
);
}