168 lines
9.2 KiB
TypeScript
168 lines
9.2 KiB
TypeScript
"use client";
|
|
import { useState, useEffect } from "react";
|
|
|
|
import { XCUQuantumBridge } from "../../components/xcuQuantumBridge";
|
|
|
|
export default function SupremeCommandPage() {
|
|
const [activeRooms, setActiveRooms] = useState<{
|
|
id: string,
|
|
status: string,
|
|
name: string,
|
|
type: string,
|
|
participants: number,
|
|
metrics?: { cpu: number, ram: number, threats: number }
|
|
}[]>([]);
|
|
const [glitch, setGlitch] = useState(false);
|
|
const [currentTime, setCurrentTime] = useState("");
|
|
const [realLatency, setRealLatency] = useState(0);
|
|
|
|
useEffect(() => {
|
|
let timeInterval: NodeJS.Timeout;
|
|
setTimeout(() => {
|
|
setCurrentTime(new Date().toLocaleTimeString('en-US', { hour12: false }));
|
|
timeInterval = setInterval(() => {
|
|
setCurrentTime(new Date().toLocaleTimeString('en-US', { hour12: false }));
|
|
}, 1000);
|
|
}, 0);
|
|
|
|
const fetchRooms = async () => {
|
|
try {
|
|
const startTime = performance.now();
|
|
const res = await fetch('/vc/api/xcu/rooms');
|
|
const endTime = performance.now();
|
|
const data = await res.json();
|
|
|
|
if (data.success) {
|
|
setGlitch(true);
|
|
setTimeout(() => setGlitch(false), 200);
|
|
setActiveRooms(data.rooms);
|
|
setRealLatency(Math.floor(endTime - startTime));
|
|
}
|
|
} catch(e) {
|
|
console.error("Gagal menarik data dari Omniversal API", e);
|
|
}
|
|
};
|
|
|
|
fetchRooms();
|
|
const interval = setInterval(fetchRooms, 3000);
|
|
|
|
return () => {
|
|
clearInterval(interval);
|
|
if (timeInterval) clearInterval(timeInterval);
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<div className="min-h-screen bg-[#050505] text-green-500 font-mono overflow-y-auto relative selection:bg-green-500 selection:text-black p-4 md:p-8">
|
|
{/* CRT Scanline Effect */}
|
|
<div className="absolute inset-0 pointer-events-none bg-[linear-gradient(rgba(18,16,16,0)_50%,rgba(0,0,0,0.25)_50%),linear-gradient(90deg,rgba(255,0,0,0.06),rgba(0,255,0,0.02),rgba(0,0,255,0.06))] bg-size-[100%_4px,3px_100%] z-50 mix-blend-screen opacity-30"></div>
|
|
|
|
<div className="max-w-7xl mx-auto relative z-10">
|
|
{/* Header */}
|
|
<header className="flex flex-col md:flex-row justify-between items-start md:items-end border-b border-green-500/30 pb-6 mb-12">
|
|
<div className="relative mb-4 md:mb-0">
|
|
<div className="absolute -inset-4 bg-green-500/10 blur-3xl rounded-full animate-pulse"></div>
|
|
<h1 className={`text-4xl md:text-7xl font-black uppercase tracking-[0.25em] text-transparent bg-clip-text bg-linear-to-r from-green-400 via-emerald-500 to-green-700 drop-shadow-[0_0_20px_rgba(34,197,94,0.4)] ${glitch ? 'translate-x-1' : ''}`}>SUPREME COMMAND</h1>
|
|
<div className="flex items-center gap-3 mt-3">
|
|
<div className="flex items-center gap-1.5 bg-green-500/10 border border-green-500/20 px-2 py-0.5 rounded shadow-[0_0_10px_rgba(0,255,0,0.1)]">
|
|
<span className="w-2 h-2 bg-green-500 rounded-full animate-ping"></span>
|
|
<span className="text-[10px] text-green-400 tracking-widest font-bold uppercase">System Active</span>
|
|
</div>
|
|
<span className="text-green-600/50 text-[9px] tracking-tighter uppercase font-medium">// Omniversal CCTV Matrix // Node-Alpha-01</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex gap-8 items-end">
|
|
<div className="hidden lg:block w-48">
|
|
<XCUQuantumBridge />
|
|
</div>
|
|
<div className="text-right">
|
|
<div className="text-3xl md:text-5xl font-black tracking-tighter text-white tabular-nums">{currentTime || "00:00:00"}</div>
|
|
<div className="flex flex-col items-end mt-2">
|
|
<span className="text-green-400/80 text-[10px] tracking-widest font-bold">ALPHA LATENCY: {realLatency}ms</span>
|
|
<div className="w-32 h-1 bg-green-900/50 rounded-full mt-1 overflow-hidden">
|
|
<div className="h-full bg-green-400 transition-all duration-300" style={{ width: `${Math.min(100, realLatency * 2)}%` }}></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
{/* Content Grid */}
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
{activeRooms.map((room) => (
|
|
<div key={room.id} className="relative group">
|
|
<div className="absolute -inset-1 bg-green-500/5 rounded-2xl blur opacity-0 group-hover:opacity-100 transition duration-500"></div>
|
|
<div className="relative border border-green-500/20 bg-[#0A0A0A] p-6 rounded-2xl shadow-[0_0_40px_rgba(0,0,0,0.5)] group-hover:border-green-400/50 transition-all duration-300 flex flex-col justify-between min-h-[260px]">
|
|
<div className="space-y-4">
|
|
<div className="flex justify-between items-start">
|
|
<div className="flex flex-col">
|
|
<span className="text-[10px] uppercase font-bold tracking-[0.2em] text-green-500/60 mb-1">Matrix ID</span>
|
|
<span className="text-xs font-mono text-white bg-green-500/5 border border-green-500/10 px-2 py-0.5 rounded">{room.id}</span>
|
|
</div>
|
|
<span className={`text-[10px] uppercase font-black tracking-widest px-3 py-1 rounded-full border shadow-[0_0_15px_rgba(0,0,0,0.2)] ${room.status === 'BROADCASTING' ? 'bg-red-500/10 text-red-400 border-red-500/20 animate-pulse' : 'bg-green-500/10 text-green-400 border-green-500/20'}`}>
|
|
{room.status}
|
|
</span>
|
|
</div>
|
|
|
|
<div>
|
|
<h2 className="text-2xl font-black text-white group-hover:text-green-400 transition-colors tracking-tight leading-none mb-2">{room.name}</h2>
|
|
<p className="text-green-700 text-[10px] uppercase tracking-[0.3em] font-bold">{room.type}</p>
|
|
</div>
|
|
|
|
{room.metrics && (
|
|
<div className="grid grid-cols-3 gap-2 pt-2 border-t border-green-500/10 mt-4">
|
|
<div className="flex flex-col">
|
|
<span className="text-[8px] text-green-700 uppercase">CPU Core</span>
|
|
<span className="text-xs text-white font-mono">{(room.metrics.cpu || 0).toFixed(1)}%</span>
|
|
</div>
|
|
<div className="flex flex-col">
|
|
<span className="text-[8px] text-green-700 uppercase">Neural RAM</span>
|
|
<span className="text-xs text-white font-mono">{(room.metrics.ram || 0).toFixed(1)}%</span>
|
|
</div>
|
|
<div className="flex flex-col">
|
|
<span className="text-[8px] text-green-700 uppercase">Threats</span>
|
|
<span className="text-xs text-red-500 font-mono">{(room.metrics.threats || 0).toLocaleString()}</span>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="flex justify-between items-end mt-8">
|
|
<div className="flex items-end gap-2">
|
|
<span className="text-4xl font-black text-white tracking-tighter leading-none">{room.participants}</span>
|
|
<span className="text-[9px] text-green-600 uppercase font-bold tracking-widest mb-1">Entities</span>
|
|
</div>
|
|
|
|
<button
|
|
onClick={() => window.open(`/vc/room/${room.id}`, '_blank')}
|
|
className="group/btn relative px-6 py-2 bg-green-500 text-black font-black text-[10px] uppercase tracking-widest rounded-lg transition-all hover:bg-white active:scale-95 shadow-[0_0_20px_rgba(34,197,94,0.3)]"
|
|
>
|
|
<span className="relative z-10">Infiltrate Matrix</span>
|
|
<div className="absolute inset-0 bg-white/20 scale-x-0 group-hover/btn:scale-x-100 transition-transform origin-left rounded-lg"></div>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Dashboard Footer/Status Bar */}
|
|
<footer className="mt-20 flex flex-col md:flex-row justify-between items-center gap-4 text-[9px] text-green-900 font-bold tracking-[0.4em] uppercase border-t border-green-500/10 pt-8 pb-12">
|
|
<div className="flex items-center gap-6">
|
|
<span>Encryption: Post-Quantum AES-XCU</span>
|
|
<span>Layer: eBPF/XDP Kernel-Bypass</span>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<span className="text-green-500 animate-pulse">●</span>
|
|
<span>All Neural Nodes Nominal</span>
|
|
</div>
|
|
<div className="hover:text-green-400 transition-colors cursor-pointer">
|
|
Secure Terminal 0.1.0-alpha
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|