Add persistent onion key backup and restore, improve startup resilience, and flesh out the major site verticals with richer navigation, search coverage, and operator documentation. Made-with: Cursor
145 lines
7.3 KiB
TypeScript
145 lines
7.3 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useEffect } from "react";
|
|
|
|
export default function AdminDashboard() {
|
|
const [btcPrice, setBtcPrice] = useState<string>("64,231.45");
|
|
const [traffic, setTraffic] = useState<number>(1240);
|
|
const [activeUsers, setActiveUsers] = useState<number>(42);
|
|
const [broadcast, setBroadcast] = useState("");
|
|
const [terminalLines, setTerminalLines] = useState<string[]>([]);
|
|
const [sessionToken, setSessionToken] = useState("");
|
|
|
|
useEffect(() => {
|
|
setSessionToken(Math.random().toString(36).slice(2, 15));
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const interval = setInterval(() => {
|
|
setBtcPrice((prev) => (parseFloat(prev.replace(',', '')) + (Math.random() - 0.5) * 10).toLocaleString(undefined, { minimumFractionDigits: 2 }));
|
|
setTraffic((prev) => prev + Math.floor(Math.random() * 5));
|
|
setActiveUsers((prev) => Math.max(10, prev + Math.floor(Math.random() * 3) - 1));
|
|
|
|
// Add random "Tor code" or system logs to terminal
|
|
const logs = [
|
|
`[TOR] New circuit established: ${Math.random().toString(16).slice(2, 10)}.onion`,
|
|
`[NGINX] 200 GET /market from 127.0.0.1`,
|
|
`[SHADOW] Broadcast packet sent to ${Math.floor(Math.random() * 1000)} nodes`,
|
|
`[SECURITY] DDoS attempt mitigated from 192.168.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`,
|
|
`[BITCOIN] Block ${Math.floor(Math.random() * 800000)} confirmed`
|
|
];
|
|
setTerminalLines(prev => [...prev.slice(-15), logs[Math.floor(Math.random() * logs.length)]]);
|
|
}, 2000);
|
|
return () => clearInterval(interval);
|
|
}, []);
|
|
|
|
const handleBroadcast = () => {
|
|
localStorage.setItem("shadow_broadcast", broadcast);
|
|
setTerminalLines(prev => [...prev, `[ADMIN] GLOBAL BROADCAST: ${broadcast}`]);
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-[#050000] text-[#00ff41] font-mono p-6 overflow-hidden flex flex-col">
|
|
{/* Top Bar */}
|
|
<header className="flex justify-between items-center border-b border-[#00ff41]/30 pb-4 mb-6">
|
|
<div className="flex items-center gap-4">
|
|
<div className="w-3 h-3 bg-red-600 rounded-full animate-ping" />
|
|
<h1 className="text-2xl font-black tracking-tighter uppercase text-white">Shadow Control Center</h1>
|
|
</div>
|
|
<div className="flex gap-8 text-[10px] uppercase tracking-widest">
|
|
<div>Uptime: 142:22:01</div>
|
|
<div className="text-green-500">Encrypted: AES-256-GCM</div>
|
|
</div>
|
|
</header>
|
|
|
|
<div className="grid grid-cols-12 gap-6 flex-1">
|
|
{/* Left Column: Stats & Broadcast */}
|
|
<div className="col-span-12 lg:col-span-4 space-y-6">
|
|
<div className="bg-black border border-[#00ff41]/20 p-6 shadow-[0_0_20px_rgba(0,255,65,0.05)]">
|
|
<h2 className="text-xs uppercase opacity-50 mb-4">Network Vitals</h2>
|
|
<div className="space-y-4">
|
|
<div className="flex justify-between items-end">
|
|
<span className="text-[10px] uppercase">BTC/USD</span>
|
|
<span className="text-2xl font-bold text-white">${btcPrice}</span>
|
|
</div>
|
|
<div className="flex justify-between items-end">
|
|
<span className="text-[10px] uppercase">Total Nodes</span>
|
|
<span className="text-2xl font-bold text-white">12,402</span>
|
|
</div>
|
|
<div className="flex justify-between items-end">
|
|
<span className="text-[10px] uppercase">Active Users</span>
|
|
<span className="text-2xl font-bold text-white">{activeUsers}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="bg-black border border-red-600/40 p-6 shadow-[0_0_20px_rgba(255,0,0,0.1)]">
|
|
<h2 className="text-xs uppercase text-red-600 mb-4 font-bold">Global Broadcast</h2>
|
|
<textarea
|
|
value={broadcast}
|
|
onChange={(e) => setBroadcast(e.target.value)}
|
|
className="w-full bg-[#111] border border-red-900 p-3 text-red-500 text-xs focus:outline-none mb-4 h-24 resize-none"
|
|
placeholder="Enter message..."
|
|
/>
|
|
<button
|
|
onClick={handleBroadcast}
|
|
className="w-full bg-red-900/90 py-2 text-xs font-bold uppercase text-red-100 transition-all hover:bg-red-800"
|
|
>
|
|
Execute Broadcast
|
|
</button>
|
|
</div>
|
|
|
|
<div className="bg-black border border-[#00ff41]/20 p-6 h-48 overflow-hidden relative">
|
|
<h2 className="text-xs uppercase opacity-50 mb-4">Node Map</h2>
|
|
<div className="absolute inset-0 opacity-20 pointer-events-none bg-[url('https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExNHJ6Z3R6Z3R6Z3R6Z3R6Z3R6Z3R6Z3R6Z3R6Z3R6Z3R6Z3R6Z3ZpZGUmc2lkPWUmdj0xJm5hbWU9Zw/3o7TKMGpxx8G3Xm8qA/giphy.gif')] bg-cover" />
|
|
<div className="relative z-10 text-[8px] space-y-1">
|
|
<div>US-EAST-1: ONLINE</div>
|
|
<div>EU-WEST-2: ONLINE</div>
|
|
<div>ASIA-SOUTH-1: ONLINE</div>
|
|
<div className="text-yellow-500">TOR-EXIT-04: LATENCY</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Middle Column: Terminal & Live Stream */}
|
|
<div className="col-span-12 lg:col-span-8 flex flex-col gap-6">
|
|
<div className="flex-1 bg-black border border-[#00ff41]/20 p-4 font-mono text-[10px] overflow-hidden flex flex-col">
|
|
<div className="flex justify-between items-center mb-2 border-b border-[#00ff41]/10 pb-2">
|
|
<span className="uppercase opacity-50">System Terminal</span>
|
|
<span className="text-green-500 animate-pulse">● LIVE</span>
|
|
</div>
|
|
<div className="flex-1 overflow-y-auto space-y-1 scrollbar-hide">
|
|
{terminalLines.map((line, i) => (
|
|
<div key={i} className={line.includes('[ADMIN]') ? 'text-red-500 font-bold' : ''}>
|
|
{line}
|
|
</div>
|
|
))}
|
|
<div className="animate-pulse">_</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="h-64 bg-black border border-[#00ff41]/20 relative overflow-hidden">
|
|
<div className="absolute top-2 left-2 z-20 bg-black/80 px-2 py-1 text-[8px] uppercase border border-[#00ff41]/20">
|
|
Live Feed: Node_05 (Red Room)
|
|
</div>
|
|
<div className="absolute inset-0 opacity-40 bg-[url('https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExNHJ6Z3R6Z3R6Z3R6Z3R6Z3R6Z3R6Z3R6Z3R6Z3R6Z3R6Z3R6Z3ZpZGUmc2lkPWUmdj0xJm5hbWU9Zw/oEI9uWUqnW3CeEnwL6/giphy.gif')] bg-cover" />
|
|
<div className="absolute inset-0 flex items-center justify-center">
|
|
<div className="text-center">
|
|
<div className="text-2xl font-black text-white/20 tracking-widest uppercase">No Signal</div>
|
|
<div className="text-[8px] uppercase opacity-20">Encrypted Stream #8821</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Bottom Bar */}
|
|
<footer className="mt-6 border-t border-[#00ff41]/30 pt-4 flex justify-between items-center text-[8px] uppercase tracking-widest opacity-50">
|
|
<div>Shadow Network OS v4.0.1-stable</div>
|
|
<div>Current Session: {sessionToken || "—"}</div>
|
|
<div className="text-red-500 font-bold">Warning: Unauthorized access is logged</div>
|
|
</footer>
|
|
</div>
|
|
);
|
|
}
|