[TSM.ID].[11031972] PXE : Platform X Ecosystem I [118 Module -LIVE-]

This commit is contained in:
TSM.ID
2026-05-25 03:50:05 +07:00
commit e820143b3c
673 changed files with 101320 additions and 0 deletions
@@ -0,0 +1,207 @@
"use client";
import { useState } from "react";
import Link from "next/link";
export default function DokumentasiPage() {
const [activeTab, setActiveTab] = useState<'anatomi' | 'roadmap' | 'mindmap'>('anatomi');
const [activeNode, setActiveNode] = useState<string | null>(null);
const roadmapData = [
{ id: 'v1', time: 'Masa Lalu (Genesis)', title: 'Monolithic Era', desc: 'Sistem tunggal SSR yang berat dan rentan tumbang. Penuh ketergantungan pada satu database.' },
{ id: 'v2', time: 'Q1 2026', title: 'Microservices Split', desc: 'Pemecahan paksa tulang punggung. IAM, XCU Ultra, dan Chat WebSocket berdiri di server masing-masing.' },
{ id: 'v3', time: 'Q2 2026', title: 'Breakout Multiverse', desc: 'Kemampuan membelah dimensi kamar VC tanpa jeda loading, ditambah Quantum Record untuk privasi absolut.' },
{ id: 'v4', time: 'Q3 2026', title: 'Omniversal & Temporal', desc: 'Ekspansi jaringan. 1 Aliran Video ke VPS dibelah menggunakan TEE-Muxer FFmpeg ke YouTube, TikTok, dan Twitter secara simultan. In-Memory Scheduler untuk chat.' },
{ id: 'v5', time: 'Masa Depan (Quantum Leap)', title: 'AI Hologram Host', desc: 'Integrasi avatar 3D kecerdasan buatan sebagai moderator otomatis dalam kamar yang menganalisa sentimen emosi partisipan.' }
];
const anatomyData = [
{ id: 'otak', icon: '🧠', name: 'Otak (Brain)', tech: 'PostgreSQL & Redis', detail: 'Matriks logika absolut. Mengingat miliaran token JWT dan mencatat setiap detak nadi transaksi penagihan tanpa kesalahan.' },
{ id: 'jantung', icon: '🫀', name: 'Jantung (Heart)', tech: 'XCU eBPF Engine', detail: 'Mesin pemompa video. Menerima tetesan data dari peramban dan memancarkannya ke ribuan layar dengan latensi di bawah 50ms.' },
{ id: 'syaraf', icon: '⚡', name: 'Syaraf (Nerves)', tech: 'Node.js WebSockets', detail: 'Jaringan listrik real-time. Membawa sinyal chat, peringatan gempa UI, dan komando Temporal Scheduler dalam kecepatan cahaya.' },
{ id: 'nadi', icon: '🩸', name: 'Nadi (Pulse)', tech: 'Next.js API', detail: 'Sirkulasi darah. Meneruskan data autentikasi dari Otak ke Kulit dengan pengamanan SSL dan Enkripsi End-to-End.' },
{ id: 'tulang', icon: '🦴', name: 'Tulang (Bones)', tech: 'Microservices', detail: 'Kerangka baja. Memastikan jika aplikasi Chat lumpuh, aplikasi Video Conference tetap hidup tanpa gangguan.' },
{ id: 'kulit', icon: '🖐️', name: 'Kulit (Skin)', tech: 'Tailwind CSS', detail: 'Sensasi sentuhan antarmuka kelas dunia. Responsif, dinamis, dan diwarnai dengan gradien neon masa depan.' },
{ id: 'ruh', icon: '🌌', name: 'Ruh (Soul)', tech: 'Zero-Downtime Philosophy', detail: 'Kesadaran platform bahwa server harus ringan. Mengorbankan browser klien untuk bekerja keras (Client-Side Rendering) demi stabilitas abadi.' }
];
return (
<div className="min-h-screen bg-[#050b14] p-6 md:p-12 text-[#e9edef] font-sans">
<div className="max-w-6xl mx-auto space-y-8">
{/* HEADER */}
<div className="flex items-center justify-between border-b border-gray-800 pb-4">
<h1 className="text-3xl font-black text-brand drop-shadow-[0_0_15px_rgba(0,255,136,0.5)]">KITAB SUCI JUMPA.ID</h1>
<Link href="/supreme-admin/about" className="px-4 py-2 bg-gray-800 hover:bg-gray-700 rounded-lg font-bold transition-colors">
Kembali ke Version Engine
</Link>
</div>
{/* TAB NAVIGATION */}
<div className="flex gap-4 border-b border-gray-800 pb-2">
<button
onClick={() => setActiveTab('anatomi')}
className={`px-6 py-3 font-bold rounded-t-xl transition-all ${activeTab === 'anatomi' ? 'bg-brand text-black' : 'text-gray-500 hover:text-white'}`}
>
Anatomi Biologis
</button>
<button
onClick={() => setActiveTab('mindmap')}
className={`px-6 py-3 font-bold rounded-t-xl transition-all ${activeTab === 'mindmap' ? 'bg-blue-500 text-white shadow-[0_-5px_20px_rgba(59,130,246,0.3)]' : 'text-gray-500 hover:text-white'}`}
>
Interactive Mindmap
</button>
<button
onClick={() => setActiveTab('roadmap')}
className={`px-6 py-3 font-bold rounded-t-xl transition-all ${activeTab === 'roadmap' ? 'bg-purple-500 text-white shadow-[0_-5px_20px_rgba(168,85,247,0.3)]' : 'text-gray-500 hover:text-white'}`}
>
Ultra Roadmap
</button>
</div>
{/* CONTENT AREA */}
<div className="bg-[#0b141a] border border-gray-800 rounded-b-2xl rounded-tr-2xl p-8 min-h-[60vh] shadow-2xl relative overflow-hidden">
{/* TAB 1: ANATOMI */}
{activeTab === 'anatomi' && (
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 animate-in fade-in slide-in-from-bottom-4 duration-500">
<div className="space-y-4">
<h2 className="text-2xl font-bold text-brand mb-6">Struktur Kehidupan Platform</h2>
{anatomyData.map((item) => (
<div
key={item.id}
onMouseEnter={() => setActiveNode(item.id)}
className={`p-4 rounded-xl border cursor-pointer transition-all duration-300 ${activeNode === item.id ? 'bg-gray-800 border-brand scale-105 z-10 relative shadow-2xl' : 'bg-transparent border-gray-800 hover:border-gray-600'}`}
>
<div className="flex items-center gap-4">
<span className="text-4xl">{item.icon}</span>
<div>
<h3 className="text-lg font-bold text-white">{item.name}</h3>
<p className="text-sm font-mono text-brand">{item.tech}</p>
</div>
</div>
</div>
))}
</div>
<div className="flex items-center justify-center p-8">
{activeNode ? (
<div className="bg-[#111b21] border border-brand p-8 rounded-3xl shadow-[0_0_50px_rgba(0,255,136,0.1)] animate-in zoom-in duration-300">
<span className="text-7xl block mb-6 text-center">{anatomyData.find(a => a.id === activeNode)?.icon}</span>
<h3 className="text-2xl font-bold text-white mb-2 text-center">{anatomyData.find(a => a.id === activeNode)?.name}</h3>
<p className="text-center text-brand font-mono text-sm mb-6">{anatomyData.find(a => a.id === activeNode)?.tech}</p>
<p className="text-gray-400 text-lg leading-relaxed text-center">
{anatomyData.find(a => a.id === activeNode)?.detail}
</p>
</div>
) : (
<div className="text-center text-gray-600">
<svg className="w-24 h-24 mx-auto mb-4 opacity-20" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-4h2v2h-2zm0-2h2V7h-2z"/></svg>
<p>Arahkan kursor ke salah satu elemen di sebelah kiri untuk melihat detail jiwa.</p>
</div>
)}
</div>
</div>
)}
{/* TAB 2: INTERACTIVE MINDMAP */}
{activeTab === 'mindmap' && (
<div className="animate-in fade-in slide-in-from-bottom-4 duration-500 h-[600px] flex items-center justify-center relative bg-gradient-to-br from-[#050B14] via-[#0A192F] to-[#00ff88]/10">
<div className="absolute inset-0 bg-blue-900/5 mix-blend-overlay"></div>
{/* Custom CSS Mindmap Tree */}
<div className="relative z-10 flex flex-col items-center">
{/* Node Pusat */}
<div className="bg-blue-600 text-white px-8 py-4 rounded-2xl font-black text-2xl shadow-[0_0_30px_rgba(37,99,235,0.6)] z-20 hover:scale-110 transition-transform cursor-crosshair">
JUMPA.ID OMNIVERSE
</div>
{/* Garis Vertikal */}
<div className="w-1 h-12 bg-blue-500/50"></div>
{/* Cabang Horizontal */}
<div className="w-[800px] h-1 bg-blue-500/50 flex justify-between relative">
<div className="absolute -top-1 -left-1 w-3 h-3 bg-blue-400 rounded-full"></div>
<div className="absolute -top-1 left-1/2 -translate-x-1/2 w-3 h-3 bg-blue-400 rounded-full"></div>
<div className="absolute -top-1 -right-1 w-3 h-3 bg-blue-400 rounded-full"></div>
</div>
{/* 3 Pilar */}
<div className="flex w-[800px] justify-between">
{/* Pilar 1: IAM */}
<div className="flex flex-col items-center">
<div className="w-1 h-8 bg-blue-500/50"></div>
<div className="bg-[#111b21] border-2 border-emerald-500 text-emerald-400 px-6 py-3 rounded-xl font-bold shadow-[0_0_15px_rgba(16,185,129,0.3)] hover:-translate-y-2 transition-transform cursor-pointer">
IAM (Identity Access)
</div>
<div className="w-1 h-8 bg-emerald-500/30"></div>
<div className="flex flex-col gap-3">
<div className="bg-gray-800 text-gray-300 text-sm px-4 py-2 rounded-lg border border-gray-700">Master Owner Dashboard</div>
<div className="bg-gray-800 text-gray-300 text-sm px-4 py-2 rounded-lg border border-gray-700">Tenant Management</div>
<div className="bg-gray-800 text-gray-300 text-sm px-4 py-2 rounded-lg border border-gray-700">Ultra Billing Engine</div>
</div>
</div>
{/* Pilar 2: VC */}
<div className="flex flex-col items-center">
<div className="w-1 h-8 bg-blue-500/50"></div>
<div className="bg-[#111b21] border-2 border-red-500 text-red-400 px-6 py-3 rounded-xl font-bold shadow-[0_0_15px_rgba(239,68,68,0.3)] hover:-translate-y-2 transition-transform cursor-pointer">
XCU Ultra Engine
</div>
<div className="w-1 h-8 bg-red-500/30"></div>
<div className="flex flex-col gap-3">
<div className="bg-gray-800 text-gray-300 text-sm px-4 py-2 rounded-lg border border-gray-700">Webinar / Podcast Mode</div>
<div className="bg-gray-800 text-gray-300 text-sm px-4 py-2 rounded-lg border border-gray-700">Breakout Multiverse</div>
<div className="bg-gray-800 text-gray-300 text-sm px-4 py-2 rounded-lg border border-gray-700">Quantum Local Record</div>
</div>
</div>
{/* Pilar 3: CHAT */}
<div className="flex flex-col items-center">
<div className="w-1 h-8 bg-blue-500/50"></div>
<div className="bg-[#111b21] border-2 border-purple-500 text-purple-400 px-6 py-3 rounded-xl font-bold shadow-[0_0_15px_rgba(168,85,247,0.3)] hover:-translate-y-2 transition-transform cursor-pointer">
WebSocket Chat
</div>
<div className="w-1 h-8 bg-purple-500/30"></div>
<div className="flex flex-col gap-3">
<div className="bg-gray-800 text-gray-300 text-sm px-4 py-2 rounded-lg border border-gray-700">Temporal Scheduler</div>
<div className="bg-gray-800 text-gray-300 text-sm px-4 py-2 rounded-lg border border-gray-700">TEE-Muxer Omniversal</div>
<div className="bg-gray-800 text-gray-300 text-sm px-4 py-2 rounded-lg border border-gray-700">End-to-End Encryption</div>
</div>
</div>
</div>
</div>
</div>
)}
{/* TAB 3: ULTRA ROADMAP */}
{activeTab === 'roadmap' && (
<div className="animate-in fade-in slide-in-from-bottom-4 duration-500 relative py-12">
<div className="absolute left-1/2 -translate-x-1/2 top-0 bottom-0 w-1 bg-linear-to-b from-gray-800 via-purple-500 to-var(--color-brand)"></div>
<div className="space-y-12">
{roadmapData.map((node, index) => (
<div key={node.id} className={`flex items-center w-full ${index % 2 === 0 ? 'justify-start' : 'justify-end'} relative`}>
{/* Lingkaran Garis Waktu */}
<div className="absolute left-1/2 -translate-x-1/2 w-6 h-6 rounded-full bg-[#111b21] border-4 border-purple-500 z-10 flex items-center justify-center">
<div className="w-2 h-2 bg-white rounded-full"></div>
</div>
<div className={`w-5/12 ${index % 2 === 0 ? 'pr-12 text-right' : 'pl-12 text-left'}`}>
<div className="bg-[#111b21] p-6 rounded-2xl border border-gray-700 hover:border-purple-500 transition-colors shadow-xl group">
<span className="text-purple-400 font-mono text-sm block mb-2">{node.time}</span>
<h3 className="text-2xl font-bold text-white mb-2 group-hover:text-purple-300 transition-colors">{node.title}</h3>
<p className="text-gray-400 leading-relaxed text-sm">{node.desc}</p>
</div>
</div>
</div>
))}
</div>
</div>
)}
</div>
</div>
</div>
);
}
+144
View File
@@ -0,0 +1,144 @@
"use client";
import { useState } from "react";
import Link from "next/link";
export default function AboutPage() {
const [platformName, setPlatformName] = useState("JUMPA.ID");
const version = "v4.2.0-ULTRA";
const handleSave = () => {
alert("SYSTEM INJECTION SUCCESS: Platform identity propagated to all nodes.");
};
return (
<div className="min-h-screen bg-[#050b14] p-6 md:p-12 text-white font-sans selection:bg-amber-500/30">
<div className="max-w-5xl mx-auto space-y-12">
{/* HEADER */}
<div className="flex flex-col md:flex-row md:items-center justify-between gap-6 border-b border-white/5 pb-8">
<div className="space-y-1">
<div className="flex items-center gap-3">
<div className="w-8 h-8 bg-purple-600 rounded-lg flex items-center justify-center shadow-[0_0_15px_rgba(168,85,247,0.5)]">
<svg className="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
</div>
<h1 className="text-3xl font-black tracking-tighter uppercase">System Anatomy</h1>
</div>
<p className="text-gray-500 text-sm font-medium">Core engine specifications and multiverse lineage.</p>
</div>
<div className="flex items-center gap-4">
<Link href="/supreme-admin" className="px-5 py-2.5 glass-panel border border-white/10 hover:bg-white/5 rounded-xl font-bold transition-all text-xs uppercase tracking-widest">
Dashboard
</Link>
<span className="px-4 py-2 bg-amber-500/10 text-amber-500 text-[10px] font-black tracking-[0.2em] rounded-full border border-amber-500/20 uppercase">
{version}
</span>
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-10">
{/* LEFT COL: WHITE LABEL */}
<div className="lg:col-span-2 space-y-8">
<div className="glass-panel p-8 rounded-[2rem] border border-white/10 relative overflow-hidden group">
<div className="absolute top-0 left-0 w-2 h-full bg-blue-500"></div>
<h2 className="text-xl font-black text-blue-400 mb-6 flex items-center gap-2">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01"></path></svg>
Identity Morphing (White Label)
</h2>
<p className="text-gray-400 text-sm mb-8 leading-relaxed">
Injeksi identitas global. Mengubah parameter ini akan mendistorsi branding JUMPA.ID di seluruh layer (IAM, XCU, XTM) secara simultan.
</p>
<div className="space-y-6">
<div>
<label className="block text-gray-500 text-[10px] font-black mb-3 uppercase tracking-[0.2em]">Master Platform Alias</label>
<div className="flex gap-4">
<input
type="text"
value={platformName}
onChange={(e) => setPlatformName(e.target.value)}
className="flex-1 bg-white/5 text-white px-5 py-4 rounded-2xl border border-white/10 outline-none focus:border-blue-500/50 transition-all font-mono text-sm"
placeholder="e.g. ULTRA_MEET"
/>
<button onClick={handleSave} className="px-8 py-4 bg-blue-600 hover:bg-blue-500 text-white rounded-2xl font-black transition-all shadow-[0_0_20px_rgba(37,99,235,0.3)] active:scale-95 text-xs uppercase tracking-widest">
INJECT
</button>
</div>
</div>
</div>
</div>
{/* TECH STACK VISUAL */}
<div className="glass-panel p-8 rounded-[2rem] border border-white/10 bg-white/[0.02]">
<h2 className="text-sm font-black text-gray-500 mb-6 uppercase tracking-[0.2em]">Quantum Stack Integrity</h2>
<div className="grid grid-cols-2 sm:grid-cols-4 gap-4">
{[
{ label: 'ENGINE', val: 'XCU RUST', color: 'text-orange-400' },
{ label: 'ORCHESTRA', val: 'NEXT.JS 15', color: 'text-white' },
{ label: 'DATABASE', val: 'POSTGRES', color: 'text-blue-400' },
{ label: 'TRANSPORT', val: 'QUIC/H3', color: 'text-emerald-400' }
].map((t, i) => (
<div key={i} className="p-4 rounded-2xl bg-white/5 border border-white/5 text-center">
<div className="text-[8px] font-black text-gray-600 mb-1">{t.label}</div>
<div className={`text-[10px] font-bold ${t.color}`}>{t.val}</div>
</div>
))}
</div>
</div>
</div>
{/* RIGHT COL: CHANGELOG */}
<div className="space-y-6">
<div className="glass-panel p-8 rounded-[2rem] border border-white/10 relative overflow-hidden h-full">
<div className="absolute top-0 left-0 w-2 h-full bg-purple-500"></div>
<h2 className="text-lg font-black text-purple-400 mb-8 uppercase tracking-widest">Evolution Logs</h2>
<div className="space-y-10 relative before:absolute before:left-[7px] before:top-2 before:bottom-2 before:w-[2px] before:bg-white/5">
{[
{
v: 'V.4.2',
t: 'QUANTUM BILLING',
d: 'Mei 2026',
c: 'bg-purple-500',
items: ['Xendit Live Integration', '101 Module Matrix', 'Auto-Pilot v2.0']
},
{
v: 'V.4.0',
t: 'OMNIVERSAL CORE',
d: 'April 2026',
c: 'bg-emerald-500',
items: ['eBPF Kernel Bypass', 'MoQ Transport', 'Deep-Twin AI']
},
{
v: 'V.3.0',
t: 'BONE SEPARATION',
d: 'Maret 2026',
c: 'bg-gray-700',
items: ['Microservices Split', 'Multi-Tenant IAM', 'Rust SFU Alpha']
}
].map((log, i) => (
<div key={i} className="relative pl-8">
<div className={`absolute left-0 top-1.5 w-4 h-4 rounded-full ${log.c} shadow-[0_0_15px_rgba(168,85,247,0.3)] z-10 border-4 border-[#050b14]`}></div>
<div className="text-[10px] font-black text-gray-500 mb-1">{log.d} {log.v}</div>
<h3 className="text-sm font-black text-white mb-3 tracking-tight">{log.t}</h3>
<ul className="space-y-2">
{log.items.map((item, idx) => (
<li key={idx} className="text-[10px] text-gray-500 flex items-center gap-2">
<span className="w-1 h-1 bg-gray-700 rounded-full"></span>
{item}
</li>
))}
</ul>
</div>
))}
</div>
</div>
</div>
</div>
</div>
</div>
);
}
@@ -0,0 +1,258 @@
"use client";
import { useEffect, useState } from "react";
import Link from "next/link";
interface Pkg {
id: string;
name: string;
price: string;
features: string;
isActive: boolean;
}
interface Tenant {
id: string;
name: string;
licenseNumber?: string;
packageId?: string;
isActive: boolean;
createdAt: string;
}
import { useDictionary } from "@/lib/dictionary";
import { useOmni } from "@/components/OmniSyncProvider";
export default function BillingManagementPage() {
const { t } = useDictionary();
const { currency, setCurrency, formatCurrency, locale, setLocale, theme, setTheme } = useOmni();
const [packages, setPackages] = useState<Pkg[]>([]);
const [tenants, setTenants] = useState<Tenant[]>([]);
const [loading, setLoading] = useState(true);
const [stats, setStats] = useState({ totalRevenue: 150000000, activeTenants: 0, growth: "+12.5%" });
useEffect(() => {
(async () => {
try {
const [pkgResp, eyeResp] = await Promise.all([
fetch("/api/superadmin/packages"),
fetch("/api/superadmin/supreme-dashboard")
]);
const pkgData = await pkgResp.json();
const eyeData = await eyeResp.json();
setPackages(pkgData.packages || []);
setTenants(eyeData.matrix || []);
// Calculate stats
const activeCount = (eyeData.matrix || []).filter((t: Tenant) => t.isActive).length;
setStats(prev => ({ ...prev, activeTenants: activeCount }));
} catch (_e) {
console.error("Failed to load billing data");
} finally {
setLoading(false);
}
})();
}, []);
const handleKillSwitch = async (id: string, name: string) => {
if (!confirm(`ACTIVATE KILL-SWITCH: Deactivate [${name}] immediately?`)) return;
try {
const res = await fetch('/api/superadmin/tenants', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'update', id, isActive: false })
});
if (res.ok) {
setTenants(prev => prev.map(t => t.id === id ? { ...t, isActive: false } : t));
}
} catch (_e) {}
};
const handleReactivate = async (id: string) => {
try {
const res = await fetch('/api/superadmin/tenants', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'update', id, isActive: true })
});
if (res.ok) {
setTenants(prev => prev.map(t => t.id === id ? { ...t, isActive: true } : t));
}
} catch (_e) {}
};
if (loading) return <div className="min-h-screen bg-[#050b14] flex items-center justify-center text-white font-mono animate-pulse">SYNCHRONIZING BILLING MATRIX...</div>;
return (
<div className="min-h-screen bg-[#050b14] p-6 md:p-12 text-white overflow-x-hidden relative">
{/* BACKGROUND DECORATION */}
<div className="absolute top-0 right-0 w-[500px] h-[500px] bg-blue-500/10 rounded-full blur-[150px] -z-10"></div>
<div className="absolute bottom-0 left-0 w-[500px] h-[500px] bg-purple-500/10 rounded-full blur-[150px] -z-10"></div>
<div className="max-w-7xl mx-auto space-y-10">
{/* HEADER */}
<div className="flex flex-col md:flex-row md:items-center justify-between gap-6">
<div className="space-y-2">
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-amber-500 rounded-lg flex items-center justify-center shadow-[0_0_20px_rgba(245,158,11,0.4)]">
<svg className="w-6 h-6 text-black" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
</div>
<h1 className="text-4xl font-black tracking-tighter bg-linear-to-r from-amber-400 to-amber-600 bg-clip-text text-transparent">XCU {t('Billing.title')}</h1>
</div>
<p className="text-gray-400 font-medium">Quantum Revenue & Subscription Orchestration Node.</p>
</div>
<div className="flex items-center gap-2">
{/* SETTINGS MATRIX */}
<div className="flex items-center gap-2 p-1.5 glass-panel rounded-xl border-white/5 bg-black/20">
<button onClick={() => setLocale(locale === 'id' ? 'en' : 'id')} className="px-3 py-1.5 rounded-lg bg-white/5 hover:bg-white/10 text-[10px] font-black uppercase tracking-widest border border-white/5 transition-all">
{locale === 'id' ? 'ID 🇮🇩' : 'EN 🇺🇸'}
</button>
<button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')} className="p-1.5 rounded-lg bg-white/5 hover:bg-white/10 border border-white/5 transition-all text-amber-500">
{theme === 'dark' ? (
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"><path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"></path></svg>
) : (
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"><path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"></path></svg>
)}
</button>
<select value={currency} onChange={(e) => setCurrency(e.target.value as any)} className="bg-transparent text-[10px] font-black uppercase tracking-widest border-none focus:ring-0 cursor-pointer text-emerald-500">
<option value="Rp" className="bg-[#050b14]">IDR</option>
<option value="USD" className="bg-[#050b14]">USD</option>
<option value="Crypto" className="bg-[#050b14]">XCU</option>
</select>
</div>
<Link href="/supreme-admin" className="px-6 py-3 glass-panel border border-white/10 hover:border-white/20 rounded-2xl font-bold transition-all hover:bg-white/5 flex items-center gap-2">
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path></svg>
{t('Common.home')}
</Link>
</div>
</div>
{/* STATS GRID */}
<div className="grid grid-cols-1 sm:grid-cols-3 gap-6">
{[
{ label: "ESTIMATED REVENUE", value: formatCurrency(stats.totalRevenue), color: "text-emerald-400", sub: "Calculated Real-time" },
{ label: "ACTIVE TENANTS", value: stats.activeTenants.toString(), color: "text-blue-400", sub: stats.growth + " this month" },
{ label: "SYSTEM UPTIME", value: "99.999%", color: "text-purple-400", sub: "0ms Latency Logic" }
].map((s, i) => (
<div key={i} className="glass-panel p-6 rounded-3xl border border-white/5 bg-white/2 overflow-hidden relative group">
<div className="absolute inset-0 bg-linear-to-br from-white/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity"></div>
<div className="text-[10px] font-black text-gray-500 tracking-[0.2em] mb-2">{s.label}</div>
<div className={`text-3xl font-black ${s.color} tracking-tight`}>{s.value}</div>
<div className="text-[10px] text-gray-500 mt-2">{s.sub}</div>
</div>
))}
</div>
{/* ACTIVE PACKAGES */}
<div className="space-y-6">
<h2 className="text-xl font-black tracking-widest text-gray-400 border-l-4 border-amber-500 pl-4">LIVE SUBSCRIPTION PLANS</h2>
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-6">
{packages.map(pkg => {
const numericPrice = parseInt(pkg.price.replace(/[^0-9]/g, '') || '0');
return (
<div key={pkg.id} className="glass-panel p-8 rounded-[2rem] border border-white/10 relative overflow-hidden group hover:border-amber-500/50 transition-all">
<div className="absolute -top-10 -right-10 w-32 h-32 bg-amber-500/5 rounded-full blur-3xl group-hover:bg-amber-500/10 transition-colors"></div>
<h3 className="text-xl font-extrabold text-white mb-1">{pkg.name}</h3>
<div className="text-2xl font-black text-amber-500 mb-6">{numericPrice === 0 ? 'PARTNER FREE' : formatCurrency(numericPrice)}</div>
<div className="space-y-3 mb-8">
{JSON.parse(pkg.features || '[]').slice(0, 3).map((f: string, idx: number) => (
<div key={idx} className="flex items-center gap-2 text-xs text-gray-400">
<svg className="w-4 h-4 text-emerald-500" fill="currentColor" viewBox="0 0 20 20"><path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd"></path></svg>
{f.replace(/\./g, ' ').split(' ').slice(-1)[0].toUpperCase()}
</div>
))}
{JSON.parse(pkg.features || '[]').length > 3 && (
<div className="text-[10px] text-gray-600 font-bold">+{JSON.parse(pkg.features || '[]').length - 3} MORE CAPABILITIES</div>
)}
</div>
<div className="pt-4 border-t border-white/5">
<div className="text-[10px] font-bold text-gray-500 uppercase tracking-widest">Status: <span className="text-emerald-500">PROVISIONED</span></div>
</div>
</div>
)})}
</div>
</div>
{/* TENANT TABLE */}
<div className="space-y-6">
<h2 className="text-xl font-black tracking-widest text-gray-400 border-l-4 border-blue-500 pl-4">TENANT SUBSCRIPTION REGISTRY</h2>
<div className="glass-panel rounded-[2rem] border border-white/5 overflow-hidden">
<table className="w-full text-left">
<thead>
<tr className="bg-white/5 text-[10px] font-black text-gray-400 uppercase tracking-[0.2em]">
<th className="px-8 py-6">Identity</th>
<th className="px-8 py-6">License Number</th>
<th className="px-8 py-6">Provision Date</th>
<th className="px-8 py-6">Status</th>
<th className="px-8 py-6 text-right">Emergency Control</th>
</tr>
</thead>
<tbody className="divide-y divide-white/5">
{tenants.map(t => (
<tr key={t.id} className="hover:bg-white/[0.02] transition-colors group">
<td className="px-8 py-6">
<div className="text-sm font-bold text-white">{t.name}</div>
<div className="text-[10px] text-gray-500 font-mono mt-1">UID: {t.id.substring(0, 8)}...</div>
</td>
<td className="px-8 py-6">
<span className="text-[10px] font-mono bg-blue-500/10 text-blue-400 px-3 py-1 rounded-full border border-blue-500/20">
{t.licenseNumber || "N/A"}
</span>
</td>
<td className="px-8 py-6 text-xs text-gray-400 font-mono">
{new Date(t.createdAt).toLocaleDateString()}
</td>
<td className="px-8 py-6">
{t.isActive ? (
<div className="flex items-center gap-2 text-[10px] font-black text-emerald-400 uppercase tracking-widest">
<div className="w-2 h-2 bg-emerald-500 rounded-full animate-pulse shadow-[0_0_10px_rgba(16,185,129,0.5)]"></div>
ACTIVE
</div>
) : (
<div className="flex items-center gap-2 text-[10px] font-black text-red-500 uppercase tracking-widest">
<div className="w-2 h-2 bg-red-500 rounded-full"></div>
SUSPENDED
</div>
)}
</td>
<td className="px-8 py-6 text-right">
{t.isActive ? (
<button
onClick={() => handleKillSwitch(t.id, t.name)}
className="text-[10px] font-black text-red-500 border border-red-500/30 px-4 py-2 rounded-xl hover:bg-red-500 hover:text-white transition-all shadow-[0_0_10px_rgba(239,68,68,0)] hover:shadow-[0_0_15px_rgba(239,68,68,0.5)] uppercase tracking-widest"
>
Kill Switch
</button>
) : (
<button
onClick={() => handleReactivate(t.id)}
className="text-[10px] font-black text-emerald-500 border border-emerald-500/30 px-4 py-2 rounded-xl hover:bg-emerald-500 hover:text-white transition-all uppercase tracking-widest"
>
Restore Access
</button>
)}
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
{/* FOOTER WATERMARK */}
<div className="mt-20 text-center pb-10">
<div className="text-[10px] font-black text-gray-700 tracking-[0.5em] uppercase">JUMPA.ID ULTRA BILLING SYSTEM V2.4</div>
<div className="text-[8px] text-gray-800 mt-2 font-mono">ENCRYPTED QUANTUM HANDSHAKE: SUCCESS</div>
</div>
</div>
);
}
@@ -0,0 +1,132 @@
"use client";
import { useEffect, useState } from "react";
import Link from "next/link";
export default function MindmapPage() {
const [mounted, setMounted] = useState(false);
useEffect(() => {
queueMicrotask(() => setMounted(true));
}, []);
if (!mounted) return null;
return (
<div className="min-h-screen bg-[#0a101d] text-white p-8 relative overflow-hidden font-sans">
{/* Background Matrix Effect */}
<div className="absolute inset-0 pointer-events-none opacity-20">
<div className="absolute inset-0 bg-[linear-gradient(rgba(10,16,29,0)_50%,rgba(0,0,0,0.5)_50%),linear-gradient(90deg,rgba(0,255,136,0.03),rgba(168,85,247,0.03),rgba(59,130,246,0.03))] bg-size-[100%_4px,4px_100%] z-0 mix-blend-screen"></div>
</div>
<header className="relative z-10 flex justify-between items-center mb-12 border-b border-white/10 pb-6">
<div>
<h1 className="text-4xl font-black tracking-tight bg-clip-text text-transparent bg-linear-to-r from-blue-400 via-purple-500 to-green-400">
JUMPA.ID ULTRA MINDMAP
</h1>
<p className="text-gray-400 mt-2 tracking-wide text-sm">Interactive Architecture Diagram (SaaS Ecosystem)</p>
</div>
<Link href="/supreme-admin" className="px-6 py-2 bg-white/5 hover:bg-white/10 border border-white/20 rounded-full font-bold transition-all flex items-center gap-2">
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path></svg>
Kembali ke Dashboard
</Link>
</header>
{/* SVG Mindmap Canvas */}
<div className="relative z-10 w-full h-[75vh] bg-[#111827] rounded-3xl border border-gray-800 shadow-[0_0_50px_rgba(0,0,0,0.5)] overflow-hidden flex items-center justify-center p-10">
{/* Connection Lines */}
<svg className="absolute inset-0 w-full h-full pointer-events-none" style={{ zIndex: 0 }}>
<defs>
<linearGradient id="line-iam-vc" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor="#a855f7" />
<stop offset="100%" stopColor="#3b82f6" />
</linearGradient>
<linearGradient id="line-iam-chat" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor="#a855f7" />
<stop offset="100%" stopColor="#10b981" />
</linearGradient>
</defs>
{/* Line: IAM -> VC */}
<path d="M 500 200 Q 750 200 750 400" fill="none" stroke="url(#line-iam-vc)" strokeWidth="3" strokeDasharray="10,10" className="animate-[dash_20s_linear_infinite]" />
{/* Line: IAM -> Chat */}
<path d="M 500 200 Q 250 200 250 400" fill="none" stroke="url(#line-iam-chat)" strokeWidth="3" strokeDasharray="10,10" className="animate-[dash_20s_linear_infinite_reverse]" />
{/* Line: Chat <-> VC */}
<path d="M 250 400 Q 500 600 750 400" fill="none" stroke="#4b5563" strokeWidth="2" strokeDasharray="5,5" className="animate-[dash_10s_linear_infinite]" />
</svg>
<div className="relative w-full h-full max-w-5xl" style={{ zIndex: 1 }}>
{/* Node: IAM */}
<div className="absolute top-[10%] left-1/2 -translate-x-1/2 group">
<div className="w-64 bg-purple-900/30 backdrop-blur-md border-2 border-purple-500 rounded-2xl p-6 shadow-[0_0_30px_rgba(168,85,247,0.3)] group-hover:scale-105 transition-transform cursor-pointer">
<div className="flex items-center gap-3 mb-3">
<div className="w-10 h-10 bg-purple-500 rounded-lg flex items-center justify-center shadow-lg">
<svg className="w-6 h-6 text-white" fill="currentColor" viewBox="0 0 24 24"><path d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 10.99h7c-.53 4.12-3.28 7.79-7 8.94V12H5V6.3l7-3.11v8.8z"/></svg>
</div>
<h3 className="text-xl font-bold text-purple-400">JUMPA IAM</h3>
</div>
<p className="text-xs text-purple-200">Identity & Access Management. Pusat Otorisasi Zero-Trust & Billing.</p>
<ul className="mt-4 text-[10px] space-y-1 text-purple-300 font-mono">
<li> QR Code Login</li>
<li> Billing Management</li>
<li> White-Label Versioning</li>
<li> Token Issuer (PostgreSQL)</li>
</ul>
</div>
</div>
{/* Node: Chat */}
<div className="absolute top-[50%] left-[10%] group">
<div className="w-64 bg-emerald-900/30 backdrop-blur-md border-2 border-emerald-500 rounded-2xl p-6 shadow-[0_0_30px_rgba(16,185,129,0.3)] group-hover:scale-105 transition-transform cursor-pointer">
<div className="flex items-center gap-3 mb-3">
<div className="w-10 h-10 bg-emerald-500 rounded-lg flex items-center justify-center shadow-lg">
<svg className="w-6 h-6 text-white" fill="currentColor" viewBox="0 0 24 24"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/></svg>
</div>
<h3 className="text-xl font-bold text-emerald-400">JUMPA CHAT</h3>
</div>
<p className="text-xs text-emerald-200">WebSocket Server (Node.js/Socket.io). Sistem Komunikasi Persistent.</p>
<ul className="mt-4 text-[10px] space-y-1 text-emerald-300 font-mono">
<li> Omni-Brain AI Interceptor</li>
<li> The Vault (DRM Storage)</li>
<li> End-to-End Encryption</li>
<li> FFmpeg Multi-Stream Engine</li>
</ul>
</div>
</div>
{/* Node: VC */}
<div className="absolute top-[50%] right-[10%] group">
<div className="w-64 bg-blue-900/30 backdrop-blur-md border-2 border-blue-500 rounded-2xl p-6 shadow-[0_0_30px_rgba(59,130,246,0.3)] group-hover:scale-105 transition-transform cursor-pointer">
<div className="flex items-center gap-3 mb-3">
<div className="w-10 h-10 bg-blue-500 rounded-lg flex items-center justify-center shadow-lg">
<svg className="w-6 h-6 text-white" fill="currentColor" viewBox="0 0 24 24"><path d="M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z"/></svg>
</div>
<h3 className="text-xl font-bold text-blue-400">JUMPA VC</h3>
</div>
<p className="text-xs text-blue-200">XCU Ultra eBPF Engine. Konferensi Video Ultra-Low Latency AV1.</p>
<ul className="mt-4 text-[10px] space-y-1 text-blue-300 font-mono">
<li> AI Deep-Twin Surrogate</li>
<li> Breakout Matrix</li>
<li> Supreme Eye (Multiverse CCTV)</li>
<li> TTE Live Canvas</li>
</ul>
</div>
</div>
</div>
</div>
<style dangerouslySetInnerHTML={{__html: `
@keyframes dash {
to {
stroke-dashoffset: -100;
}
}
`}} />
</div>
);
}
+875
View File
@@ -0,0 +1,875 @@
"use client";
import { useEffect, useState, useCallback } from "react";
import { useRouter } from "next/navigation";
interface Feature {
key: string;
name: string;
module?: string;
}
interface Package {
id: string;
name: string;
price: string;
features: string;
}
interface Tenant {
id: string;
name: string;
licenseNumber: string;
licenses?: string | Record<string, string>;
package?: {
id: string;
name: string;
features: string;
};
byokEnabled?: boolean;
byokKey?: string;
users?: any[];
}
interface User {
email: string;
role: string;
}
export default function SupremeAdminDashboard() {
const [data, setData] = useState<User | null>(null);
const [tenants, setTenants] = useState<Tenant[]>([]);
const [packages, setPackages] = useState<Package[]>([]);
const [systemFeatures, setSystemFeatures] = useState<Feature[]>([]);
const [loading, setLoading] = useState(true);
const router = useRouter();
const handleLogout = async () => {
try {
await fetch('/api/auth/logout', { method: 'POST' });
window.location.href = '/';
} catch (e) {
console.error("Logout failed", e);
window.location.href = '/';
}
};
// Modal States
const [showPackageModal, setShowPackageModal] = useState(false);
const [showTenantModal, setShowTenantModal] = useState(false);
const [selectedTenant, setSelectedTenant] = useState<Tenant | null>(null);
// Quantum Toast System
const [toast, setToast] = useState<{message: string, type: 'success' | 'error'} | null>(null);
const showToast = (message: string, type: 'success' | 'error' = 'success') => {
setToast({ message, type });
setTimeout(() => setToast(null), 4000);
};
const [tenantLicenses, setTenantLicenses] = useState<Record<string, string>>({});
const [byokEnabled, setByokEnabled] = useState(false);
const [byokKey, setByokKey] = useState("");
// Form States
const [editingPkgId, setEditingPkgId] = useState<string | null>(null);
const [newPkgName, setNewPkgName] = useState("");
const [newPkgPrice, setNewPkgPrice] = useState("");
const [selectedFeatures, setSelectedFeatures] = useState<string[]>([]);
const [searchQuery, setSearchQuery] = useState("");
// XCU Engine State
const [xcuNodes, setXcuNodes] = useState<any[]>([]);
const [xcuLoading, setXcuLoading] = useState(false);
// Security Tier Modal
const [tierModal, setTierModal] = useState<{tenantId: string; tenantName: string; currentTier: string} | null>(null);
const [tierSwitching, setTierSwitching] = useState(false);
const [selectedTier, setSelectedTier] = useState('STANDARD');
const TIER_CONFIG: Record<string, {label:string; desc:string; color:string; bg:string; border:string; icon:string}> = {
STANDARD: { label: "Let's Encrypt", desc: 'Sertifikat global, dipercaya semua browser. Auto-renew 90 hari.', color: 'text-emerald-400', bg: 'bg-emerald-500/10', border: 'border-emerald-500/20', icon: '🌐' },
SOVEREIGN: { label: 'Private CA (X)', desc: 'RSA-4096, 30 tahun. Offline-ready, tidak bergantung internet global.', color: 'text-cyan-400', bg: 'bg-cyan-500/10', border: 'border-cyan-500/20', icon: '🛡️' },
CLIENT_CA: { label: 'Client CA (Upload)', desc: 'Tenant upload CA mereka sendiri (BSSN/Komdigi/Militer/BIN).', color: 'text-amber-400', bg: 'bg-amber-500/10', border: 'border-amber-500/20', icon: '🏛️' },
};
const fetchXcuStatus = useCallback(async () => {
setXcuLoading(true);
try {
const resp = await fetch('/api/superadmin/xcu-tls-switch');
const data = await resp.json();
setXcuNodes(data.nodes || []);
} catch (_e) {
console.error('XCU fetch failed', _e);
} finally {
setXcuLoading(false);
}
}, []);
const fetchData = useCallback(async () => {
try {
const [pkgResp, eyeResp] = await Promise.all([
fetch("/api/superadmin/packages"),
fetch("/api/superadmin/supreme-dashboard")
]);
const pkgData = await pkgResp.json();
const eyeData = await eyeResp.json();
if (eyeData.error) {
router.push("/");
return;
}
setPackages(pkgData.packages || []);
setTenants(eyeData.matrix || []);
setSystemFeatures(pkgData.systemFeatures || []);
setData(eyeData.user || { email: "Supreme Admin", role: "superadmin" });
} catch (_e) {
console.error(_e);
} finally {
setLoading(false);
}
}, [router]);
useEffect(() => {
fetchData();
// Live polling XCU Engine status every 5s
const pollXcu = async () => {
try {
const resp = await fetch('/api/superadmin/xcu-tls-switch');
if (resp.ok) {
const data = await resp.json();
if (data.nodes) setXcuNodes(data.nodes);
}
} catch {}
setXcuLoading(false);
};
pollXcu();
const xcuInterval = setInterval(pollXcu, 5000);
return () => clearInterval(xcuInterval);
}, [fetchData]);
const handleSavePackage = async (e?: React.FormEvent | React.MouseEvent) => {
if (e) e.preventDefault();
try {
const resp = await fetch("/api/superadmin/packages", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
action: editingPkgId ? "update" : "create",
id: editingPkgId,
name: newPkgName,
price: newPkgPrice,
features: selectedFeatures
})
});
if (resp.ok) {
setShowPackageModal(false);
setEditingPkgId(null);
fetchData();
showToast(editingPkgId ? "Paket berhasil diperbarui." : "Paket berhasil dibuat.");
} else {
const errorData = await resp.json();
showToast(errorData.error || "Gagal menyimpan paket.", "error");
}
} catch (_e) {
showToast("Error menyimpan paket. Periksa koneksi Anda.", "error");
}
};
const handleDeletePackage = async (id: string) => {
try {
const resp = await fetch("/api/superadmin/packages", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ action: "delete", id })
});
if (resp.ok) {
fetchData();
showToast("Paket berhasil dihapus.");
} else {
const errorData = await resp.json();
showToast(errorData.error || "Gagal menghapus paket.", "error");
}
} catch (_e) {
showToast("Error menghapus paket. Periksa koneksi Anda.", "error");
}
};
const saveTenantPackage = async (tenantId: string, packageId: string) => {
try {
const resp = await fetch("/api/superadmin/supreme-dashboard", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
action: "update_tenant_package",
tenantId,
packageId
})
});
if (resp.ok) {
fetchData();
showToast("Paket tenant berhasil diperbarui.");
} else {
const errorData = await resp.json();
showToast(errorData.error || "Gagal menetapkan paket.", "error");
}
} catch (_e) {
showToast("Gagal menetapkan paket. Periksa koneksi.", "error");
}
};
const openTenantMatrix = (tenant: Tenant) => {
setSelectedTenant(tenant);
setByokEnabled(tenant.byokEnabled || false);
setByokKey(tenant.byokKey || "");
let parsed: Record<string, string> = {};
try {
if (typeof tenant.licenses === 'string') parsed = JSON.parse(tenant.licenses);
else parsed = tenant.licenses || {};
if (Array.isArray(parsed)) {
const temp: Record<string, string> = {};
parsed.forEach((k: string) => temp[k] = "GRANTED");
parsed = temp;
}
} catch(_e) {}
setTenantLicenses(parsed);
setShowTenantModal(true);
};
const [isSavingMatrix, setIsSavingMatrix] = useState(false);
const saveTenantMatrix = async () => {
setIsSavingMatrix(true);
try {
const resp = await fetch("/api/superadmin/supreme-dashboard", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
action: "update_tenant_licenses",
tenantId: selectedTenant?.id,
licenses: tenantLicenses,
byokEnabled,
byokKey
})
});
if (resp.ok) {
setShowTenantModal(false);
fetchData();
showToast("Matriks Sovereignty berhasil di-deploy tanpa henti (Zero Downtime).");
} else {
const errorData = await resp.json();
showToast(errorData.error || "Gagal menyimpan matrix.", "error");
}
} catch (_e) {
showToast("Koneksi terputus. Gagal menyimpan matrix.", "error");
} finally {
setIsSavingMatrix(false);
}
};
const applySecurityTier = async () => {
if (!tierModal || selectedTier === tierModal.currentTier) return;
setTierSwitching(true);
try {
const resp = await fetch('/api/superadmin/supreme-dashboard', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'update_security_tier', tenantId: tierModal.tenantId, securityTier: selectedTier }),
});
if (resp.ok) {
fetchData();
showToast(`Security Tier berhasil di-switch ke ${TIER_CONFIG[selectedTier]?.label || selectedTier}`);
setTierModal(null);
} else {
showToast('Gagal mengubah Security Tier', 'error');
}
} catch { showToast('Koneksi gagal', 'error'); }
setTierSwitching(false);
};
if (loading) return <div className="min-h-screen bg-[#f4f5f9] flex items-center justify-center text-blue-600 font-medium">Loading Supreme Admin...</div>;
return (
<div className="min-h-screen bg-[#f4f5f9] text-gray-900 font-sans pb-20 relative">
{/* Quantum Toast Notification System */}
{toast && (
<div className={`fixed top-20 right-8 z-[100] px-6 py-4 rounded-xl shadow-2xl backdrop-blur-xl border flex items-center gap-4 animate-in slide-in-from-right-8 fade-in duration-300 ${toast.type === 'success' ? 'bg-emerald-500/10 border-emerald-500/30 text-emerald-700' : 'bg-red-500/10 border-red-500/30 text-red-700'}`}>
<div className={`w-8 h-8 rounded-full flex items-center justify-center ${toast.type === 'success' ? 'bg-emerald-500 text-white' : 'bg-red-500 text-white'}`}>
{toast.type === 'success' ? (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"></path></svg>
) : (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12"></path></svg>
)}
</div>
<div>
<div className="text-xs font-black uppercase tracking-widest opacity-80 mb-0.5">{toast.type === 'success' ? 'System Success' : 'System Alert'}</div>
<div className="text-sm font-medium">{toast.message}</div>
</div>
</div>
)}
<header className="bg-white border-b border-gray-200 h-16 flex items-center justify-between px-8 sticky top-0 z-40 shadow-sm">
<div className="flex items-center gap-3">
<svg className="w-7 h-7 text-blue-600" fill="currentColor" viewBox="0 0 24 24"><path d="M4 4h10a2 2 0 0 1 2 2v3.5l4-3v11l-4-3V18a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z"></path></svg>
<h1 className="text-xl font-bold tracking-tight text-gray-800">Supreme Admin <span className="text-sm font-normal text-gray-500 ml-2">Workspace Control</span></h1>
</div>
<div className="flex items-center gap-4">
<a href="/supreme-admin/telepathy" className="px-3 py-1.5 bg-gradient-to-r from-[#ff0080] to-[#7928ca] text-white text-xs font-bold rounded-md hover:opacity-90 transition-opacity flex items-center gap-2 shadow-sm">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" /></svg>
TELEPATHY MATRIX
</a>
<a href="/supreme-admin/telemetry" className="px-3 py-1.5 bg-gradient-to-r from-[#25D366] to-[#0b5cff] text-white text-xs font-bold rounded-md hover:opacity-90 transition-opacity flex items-center gap-2 shadow-sm">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" /></svg>
PANOPTICON
</a>
<span className="text-sm text-gray-600 font-medium">{data?.email}</span>
<button onClick={handleLogout} className="text-sm text-blue-600 hover:text-blue-800 font-semibold transition-colors">Sign Out</button>
</div>
</header>
<main className="max-w-7xl mx-auto px-6 py-8">
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-8">
<div className="bg-white p-5 rounded-lg border border-gray-200 shadow-sm">
<div className="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-1">Total Tenants</div>
<div className="text-3xl font-bold text-gray-900">{tenants.length}</div>
</div>
<div className="bg-white p-5 rounded-lg border border-gray-200 shadow-sm">
<div className="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-1">XCU Modules</div>
<div className="text-3xl font-bold text-gray-900">{systemFeatures.length || '101'}</div>
</div>
<div className="bg-white p-5 rounded-lg border border-gray-200 shadow-sm">
<div className="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-1">Active Packages</div>
<div className="text-3xl font-bold text-gray-900">{packages.length}</div>
</div>
<div className="bg-blue-600 p-5 rounded-lg border border-blue-700 shadow-sm text-white flex flex-col justify-center cursor-pointer hover:bg-blue-700 transition-colors" onClick={() => { setEditingPkgId(null); setNewPkgName(""); setNewPkgPrice(""); setSelectedFeatures([]); setShowPackageModal(true); }}>
<div className="text-sm font-bold flex items-center justify-between">
Create New Package
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 4v16m8-8H4"></path></svg>
</div>
</div>
</div>
{/* XCU QUIC ENGINE STATUS PANEL */}
<div className="mb-8 bg-gradient-to-r from-slate-900 via-slate-800 to-slate-900 rounded-2xl border border-slate-700/50 shadow-xl overflow-hidden">
<div className="px-6 py-4 border-b border-slate-700/50 flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-cyan-500 to-blue-600 flex items-center justify-center shadow-lg shadow-cyan-500/20">
<svg className="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" /></svg>
</div>
<div>
<h2 className="text-base font-bold text-white tracking-tight">XCom ULTRA Engine</h2>
<p className="text-[10px] text-slate-400 font-mono">QUIC/WebTransport Port 8443 (UDP) Port 8081 (HTTP)</p>
</div>
</div>
<div className="flex items-center gap-3">
<div className="flex items-center gap-2 px-3 py-1.5 bg-red-500/10 border border-red-500/20 rounded-lg">
<span className="relative flex h-2.5 w-2.5">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-500 opacity-75"></span>
<span className="relative inline-flex rounded-full h-2.5 w-2.5 bg-red-500"></span>
</span>
<span className="text-[10px] font-bold uppercase tracking-wider text-red-400">LIVE</span>
</div>
</div>
</div>
<div className="p-5">
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{xcuNodes.length > 0 ? xcuNodes.map((node: any, idx: number) => (
<div key={idx} className={`relative rounded-xl border p-4 transition-all duration-300 ${
node.online
? 'bg-slate-800/80 border-slate-600/50 hover:border-cyan-500/50 hover:shadow-lg hover:shadow-cyan-500/5'
: 'bg-red-950/30 border-red-800/30'
}`}>
{/* Pulse indicator */}
<div className="absolute top-3 right-3">
<span className={`relative flex h-3 w-3`}>
{node.online && <span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>}
<span className={`relative inline-flex rounded-full h-3 w-3 ${node.online ? 'bg-emerald-400' : 'bg-red-500'}`}></span>
</span>
</div>
{/* Node name */}
<div className="text-xs font-black text-slate-400 uppercase tracking-widest mb-2">{node.name}</div>
<div className="text-[10px] font-mono text-slate-500 mb-3">{node.host}</div>
{node.online ? (
<>
{/* TLS Mode Badge */}
<div className="mb-3">
<div className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg text-[10px] font-bold uppercase tracking-wider ${
node.tlsMode === 'SELFSIGNED'
? 'bg-amber-500/10 text-amber-400 border border-amber-500/20'
: 'bg-emerald-500/10 text-emerald-400 border border-emerald-500/20'
}`}>
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
TLS: {node.tlsMode || 'LETSENCRYPT'}
</div>
</div>
{/* Metrics */}
<div className="grid grid-cols-2 gap-2 mb-3">
<div className="bg-slate-900/50 rounded-lg p-2">
<div className="text-[9px] text-slate-500 uppercase font-bold">CPU</div>
<div className="text-sm font-bold text-cyan-400">{typeof node.cpu === 'number' ? node.cpu.toFixed(1) : '0'}%</div>
</div>
<div className="bg-slate-900/50 rounded-lg p-2">
<div className="text-[9px] text-slate-500 uppercase font-bold">RAM</div>
<div className="text-sm font-bold text-purple-400">{typeof node.ram === 'number' ? node.ram.toFixed(1) : '0'}%</div>
</div>
</div>
{/* Cert hash */}
<div className="text-[8px] font-mono text-slate-600 truncate" title={node.certHash}>CERT: {node.certHash?.substring(0, 16)}...</div>
{/* Status */}
<div className={`mt-2 text-[10px] font-bold uppercase tracking-wider ${
node.status === 'SECURE' ? 'text-emerald-400' : node.status === 'OUROBOROS_IGNITED' ? 'text-red-400' : 'text-slate-400'
}`}>
{node.status}
</div>
</>
) : (
<div className="text-sm font-bold text-red-400 mt-2"> OFFLINE</div>
)}
</div>
)) : (
<div className="col-span-3 text-center py-8">
<div className="text-slate-500 text-sm">Loading XCU Engine status...</div>
</div>
)}
</div>
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
<div className="lg:col-span-2 space-y-6">
<div className="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden">
<div className="px-6 py-5 border-b border-gray-200 bg-gray-50 flex justify-between items-center">
<h2 className="text-lg font-semibold text-gray-800">Client Organizations (Tenants)</h2>
</div>
<div className="divide-y divide-gray-100">
{tenants.map((t: Tenant) => {
const isVIP = t.name.toLowerCase().includes('tsm') || t.name.toLowerCase().includes('snowy');
return (
<div key={t.id} className="flex flex-col border-b border-gray-100 last:border-0">
<div className="p-6 hover:bg-gray-50 transition-colors flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
<div className="flex-1">
<div className="flex items-center gap-3 mb-1">
<h3 className="text-base font-bold text-gray-900">{t.name}</h3>
{isVIP && <span className="px-2 py-0.5 bg-blue-100 text-blue-700 text-[10px] font-bold rounded uppercase tracking-wider">VIP Partner</span>}
{/* Security Tier Badge */}
{(() => {
const tier = (t as any).securityTier || 'STANDARD';
const badgeMap: Record<string,string> = {
STANDARD: 'bg-emerald-50 text-emerald-600 border-emerald-200',
SOVEREIGN: 'bg-cyan-50 text-cyan-700 border-cyan-200',
CLIENT_CA: 'bg-amber-50 text-amber-700 border-amber-200',
};
const labelMap: Record<string,string> = { STANDARD: '🌐 LET\'S ENCRYPT', SOVEREIGN: '🛡️ PRIVATE CA', CLIENT_CA: '🏛️ CLIENT CA' };
return (
<>
<button
onClick={() => { setSelectedTier(tier); setTierModal({ tenantId: t.id, tenantName: t.name, currentTier: tier }); }}
className={`inline-flex items-center gap-1 px-2 py-0.5 rounded text-[10px] font-bold uppercase tracking-wider transition-all hover:scale-105 border ${badgeMap[tier] || badgeMap.STANDARD}`}
title="Klik untuk ubah Security Tier"
>
{labelMap[tier] || '🌐 STANDARD'}
</button>
{(tier === 'SOVEREIGN' || tier === 'CLIENT_CA') && (
<a href="/supreme-admin/sovereign-setup" className={`px-2 py-0.5 text-white text-[10px] font-bold rounded transition-colors ${tier === 'CLIENT_CA' ? 'bg-amber-500 hover:bg-amber-600' : 'bg-cyan-600 hover:bg-cyan-700'}`}>CA Setup </a>
)}
</>
);
})()}
</div>
<div className="text-xs text-gray-500 font-mono mb-2 flex items-center gap-2">
<svg className="w-3.5 h-3.5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"></path></svg>
License: <strong className="text-gray-700">{t.licenseNumber || 'PENDING'}</strong>
</div>
</div>
<div className="flex flex-col sm:items-end gap-3 w-full sm:w-auto">
<div className="flex flex-col items-end gap-1 w-full">
<span className="text-[10px] font-bold text-gray-500 uppercase">Assigned Package</span>
<select
className="text-xs border rounded px-2 py-1 bg-gray-50 w-full sm:w-48 outline-none focus:ring-1 focus:ring-blue-500"
value={t.package?.id || ""}
onChange={e => saveTenantPackage(t.id, e.target.value)}
>
<option value="">-- No Package (Custom) --</option>
{packages.map(p => (
<option key={p.id} value={p.id}>{p.name}</option>
))}
</select>
</div>
<button onClick={() => openTenantMatrix(t)} className="px-4 py-2 bg-white border border-gray-300 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-50 hover:text-blue-600 transition-colors self-start sm:self-auto">
Manage Feature Matrix & BYOK
</button>
</div>
</div>
{/* Render Users List for the Tenant */}
{t.users && t.users.length > 0 && (
<div className="bg-gray-50 border-t border-gray-100 p-4 pl-10">
<div className="text-[11px] font-bold text-gray-500 uppercase tracking-widest mb-2 flex items-center gap-2">
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"></path></svg>
Registered Neural Entities
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
{t.users.map((u: any) => (
<div key={u.id} className="flex justify-between items-center bg-white border border-gray-200 p-2 rounded-md shadow-sm">
<div className="flex flex-col">
<span className="text-sm font-semibold text-gray-800">{u.email}</span>
<span className="text-[10px] text-gray-400 font-mono">{u.id}</span>
</div>
<span className={`text-[10px] px-2 py-0.5 rounded-full font-bold uppercase ${u.role === 'admin' ? 'bg-purple-100 text-purple-700' : u.role === 'superadmin' ? 'bg-red-100 text-red-700' : 'bg-gray-100 text-gray-700'}`}>
{u.role}
</span>
</div>
))}
</div>
</div>
)}
</div>
);
})}
</div>
</div>
</div>
<div className="lg:col-span-1 space-y-6">
<div className="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden">
<div className="px-6 py-5 border-b border-gray-200 bg-gray-50">
<h2 className="text-lg font-semibold text-gray-800">Module Packages</h2>
</div>
<div className="p-4 space-y-3">
{packages.map((p: Package) => {
let featList: string[] = [];
try {
featList = JSON.parse(p.features || "[]");
} catch (e) {}
const isJVC = p.name.includes("JVC");
const isJC = p.name.includes("JC");
const isCombo = isJVC && isJC;
const bgClass = isCombo ? "bg-gradient-to-br from-blue-800 via-teal-700 to-emerald-600 text-white border-none shadow-2xl shadow-teal-900/40 ring-1 ring-teal-400/50" : isJVC ? "bg-gradient-to-br from-indigo-950 via-blue-900 to-indigo-900 text-white border-none shadow-xl shadow-blue-900/20" : isJC ? "bg-gradient-to-br from-teal-950 via-emerald-900 to-teal-900 text-white border-none shadow-xl shadow-emerald-900/20" : "bg-white border border-gray-200 text-gray-900 shadow-sm";
const badgeClass = isCombo ? "bg-white/20 text-white border border-white/30 font-bold drop-shadow-sm" : isJVC ? "bg-blue-500/20 text-blue-100 border border-blue-400/30" : isJC ? "bg-emerald-500/20 text-emerald-100 border border-emerald-400/30" : "bg-gray-50 text-gray-700 border border-gray-200";
const textMuted = isJVC || isJC || isCombo ? "text-gray-300" : "text-gray-500";
return (
<div key={p.id} className={`p-5 rounded-2xl transition-all duration-300 hover:-translate-y-1 relative overflow-hidden group ${bgClass}`}>
{/* Decorative background glow */}
{(isJVC || isJC || isCombo) && <div className="absolute -top-12 -right-12 w-40 h-40 bg-white opacity-[0.03] blur-3xl rounded-full pointer-events-none group-hover:opacity-10 transition-opacity"></div>}
{isCombo && <div className="absolute -bottom-10 -left-10 w-32 h-32 bg-emerald-400 opacity-20 blur-3xl rounded-full pointer-events-none"></div>}
{isCombo && <div className="absolute -top-10 -right-10 w-32 h-32 bg-blue-400 opacity-20 blur-3xl rounded-full pointer-events-none"></div>}
<div className="flex justify-between items-start mb-4 relative z-10">
<div className="font-bold text-lg tracking-tight flex items-center gap-2 drop-shadow-md">
{isCombo && <svg className="w-5 h-5 text-teal-100" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>}
{p.name}
</div>
<div className="flex flex-col items-end gap-1.5">
<div className={`text-sm font-black ${isJVC || isJC || isCombo ? 'text-white' : 'text-blue-600'}`}>{p.price}</div>
<div className="flex gap-3 mt-1">
<button onClick={() => { setEditingPkgId(p.id); setNewPkgName(p.name); setNewPkgPrice(p.price); setSelectedFeatures(featList); setShowPackageModal(true); }} className={`text-[10px] font-bold uppercase tracking-wider hover:underline ${textMuted}`}>Edit</button>
<button onClick={() => handleDeletePackage(p.id)} className={`text-[10px] font-bold uppercase tracking-wider hover:underline ${isJVC || isJC || isCombo ? 'text-red-300' : 'text-red-500'}`}>Delete</button>
</div>
</div>
</div>
<div className={`text-[10px] font-bold uppercase tracking-widest mb-3 border-t pt-4 ${isJVC || isJC || isCombo ? 'border-white/10 text-white/50' : 'border-gray-100 text-gray-400'}`}>
Core Capabilities ({featList.length} Modules)
</div>
<div className="flex flex-wrap gap-1.5 relative z-10">
{featList.length > 0 ? (
featList.map((f: string) => (
<span key={f} className={`text-[9.5px] font-mono px-2 py-1 rounded-md backdrop-blur-md ${badgeClass}`}>
{f}
</span>
))
) : (
<span className={`text-[10px] italic ${textMuted}`}>No modules defined</span>
)}
</div>
</div>
);
})}
</div>
</div>
</div>
</div>
</main>
{/* CREATE PACKAGE MODAL */}
{showPackageModal && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm">
<div className="bg-white w-full max-w-2xl rounded-xl shadow-2xl overflow-hidden flex flex-col max-h-[90vh]">
<div className="px-6 py-4 border-b border-gray-200 flex justify-between items-center bg-gray-50">
<h2 className="text-xl font-bold text-gray-900">Create XCU Module Package</h2>
<button onClick={() => setShowPackageModal(false)} className="text-gray-400 hover:text-gray-700"></button>
</div>
<div className="p-6 overflow-y-auto flex-1">
<div id="pkgForm" className="space-y-6">
<div className="grid grid-cols-2 gap-4">
<input type="text" value={newPkgName} onChange={e => setNewPkgName(e.target.value)} placeholder="Package Name" className="border p-2 rounded" required />
<input type="text" value={newPkgPrice} onChange={e => setNewPkgPrice(e.target.value)} placeholder="Price (Rp)" className="border p-2 rounded" required />
</div>
<div>
<div className="flex items-center justify-between mb-4 border-b pb-2">
<h3 className="text-sm font-bold">Select Modules</h3>
<input type="text" placeholder="Search..." value={searchQuery} onChange={e => setSearchQuery(e.target.value)} className="text-xs border rounded-full px-3 py-1 outline-none" />
</div>
<div className="space-y-4">
{['JVC', 'JC', 'XCU', 'XTM', 'IAM'].map(mod => {
const filtered = systemFeatures.filter(f => (f.module === mod || (!f.module && mod === 'IAM')) && (f.name.toLowerCase().includes(searchQuery.toLowerCase()) || f.key.toLowerCase().includes(searchQuery.toLowerCase())));
if (filtered.length === 0) return null;
return (
<div key={mod}>
<div className="text-[10px] font-black text-blue-600 mb-2 flex justify-between">
<span>{mod} MODULES</span>
<div className="space-x-2">
<button type="button" onClick={() => setSelectedFeatures(Array.from(new Set([...selectedFeatures, ...systemFeatures.filter(f => f.module === mod || (!f.module && mod === 'IAM')).map(f => f.key)])))} className="hover:underline">Select All</button>
<button type="button" onClick={() => setSelectedFeatures(selectedFeatures.filter(k => !systemFeatures.filter(f => f.module === mod || (!f.module && mod === 'IAM')).some(f => f.key === k)))} className="hover:underline">Clear</button>
</div>
</div>
<div className="grid grid-cols-2 gap-2">
{filtered.map(f => (
<label key={f.key} className="flex items-center gap-2 p-2 border rounded hover:bg-gray-50 cursor-pointer">
<input type="checkbox" checked={selectedFeatures.includes(f.key)} onChange={e => e.target.checked ? setSelectedFeatures([...selectedFeatures, f.key]) : setSelectedFeatures(selectedFeatures.filter(x => x !== f.key))} />
<div className="text-[10px]">{f.name}</div>
</label>
))}
</div>
</div>
);
})}
</div>
</div>
</div>
</div>
<div className="p-4 border-t bg-gray-50 flex justify-end gap-2">
<button type="button" onClick={() => setShowPackageModal(false)} className="px-4 py-2 border rounded">Cancel</button>
<button type="button" onClick={handleSavePackage} className="px-4 py-2 bg-blue-600 text-white rounded">Save Package</button>
</div>
</div>
</div>
)}
{/* TENANT MATRIX MODAL */}
{showTenantModal && selectedTenant && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm">
<div className="bg-white w-full max-w-3xl rounded-xl shadow-2xl overflow-hidden flex flex-col max-h-[90vh]">
<div className="px-6 py-4 border-b bg-gray-50 flex justify-between items-center relative overflow-hidden">
<div className="absolute top-0 right-0 w-64 h-full bg-gradient-to-l from-blue-100/50 to-transparent pointer-events-none"></div>
<div>
<h2 className="text-2xl font-black text-gray-900 tracking-tight flex items-center gap-3">
{selectedTenant.name}
<span className="px-3 py-1 bg-gray-900 text-white text-[10px] font-bold rounded-full uppercase tracking-widest shadow-sm">
{selectedTenant.package ? selectedTenant.package.name : "A LA CARTE (CUSTOM)"}
</span>
</h2>
<p className="text-xs text-gray-500 font-medium mt-1">Superadmin Matrix Control & Sovereignty Panel</p>
</div>
<button onClick={() => setShowTenantModal(false)} className="w-8 h-8 flex items-center justify-center rounded-full hover:bg-gray-200 text-gray-500 transition-colors z-10"></button>
</div>
<div className="p-6 overflow-y-auto flex-1 bg-gradient-to-b from-gray-50/50 to-white">
{/* SPECTACULAR LICENSE TIER BANNER */}
<div className={`mb-6 relative overflow-hidden rounded-2xl p-6 border ${selectedTenant.package ? 'bg-gradient-to-br from-indigo-950 via-blue-900 to-indigo-900 border-none shadow-xl shadow-blue-900/20 text-white' : 'bg-white border-dashed border-gray-300 text-gray-800'}`}>
{selectedTenant.package && <div className="absolute -top-24 -right-24 w-64 h-64 bg-blue-400 opacity-20 blur-3xl rounded-full pointer-events-none"></div>}
{selectedTenant.package && <div className="absolute -bottom-24 -left-24 w-64 h-64 bg-cyan-400 opacity-20 blur-3xl rounded-full pointer-events-none"></div>}
<div className="relative z-10 flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
<div>
<div className={`text-[10px] font-black uppercase tracking-widest mb-1 ${selectedTenant.package ? 'text-blue-300' : 'text-gray-400'}`}>Active Quantum Tier</div>
<div className="text-2xl font-black flex items-center gap-2">
{selectedTenant.package ? (
<>
<svg className="w-6 h-6 text-cyan-400" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l10-7.27z"/></svg>
{selectedTenant.package.name}
</>
) : (
<>
<svg className="w-6 h-6 text-gray-400" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/></svg>
Custom A La Carte
</>
)}
</div>
<p className={`text-xs mt-2 max-w-xl ${selectedTenant.package ? 'text-blue-100' : 'text-gray-500'}`}>
{selectedTenant.package ?
"Modul-modul di bawah ini otomatis di-kunci (GRANTED) berdasarkan paket yang dipilih. Anda dapat menambahkan modul tambahan sebagai A La Carte." :
"Tenant ini tidak terikat pada paket apapun. Semua modul diatur secara manual per-item melalui saklar di bawah ini."}
</p>
</div>
{selectedTenant.package && (
<div className="px-4 py-2 bg-white/10 backdrop-blur border border-white/20 rounded-xl text-xs font-bold text-blue-50">
Paket Terkunci (Auto-Granted)
</div>
)}
</div>
</div>
<div className="mb-6 flex flex-col md:flex-row justify-between items-start md:items-center gap-4 bg-blue-50/80 p-6 rounded-2xl border border-blue-100 shadow-inner">
<div className="flex-1">
<h3 className="text-sm font-black text-blue-900 uppercase tracking-widest mb-1 flex items-center gap-2">
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"><path fillRule="evenodd" d="M2.166 4.999A11.954 11.954 0 0010 1.944 11.954 11.954 0 0017.834 5c.11.65.166 1.32.166 2.001 0 5.225-3.34 9.67-8 11.317C5.34 16.67 2 12.225 2 7c0-.682.057-1.35.166-2.001zm11.541 3.708a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd"></path></svg>
Quantum BYOK Sovereignty
</h3>
<p className="text-[10px] text-blue-700 font-medium">Berikan otoritas penuh kepada tenant untuk mendikte kunci enkripsi E2EE mereka sendiri.</p>
</div>
<div className="flex flex-col gap-2 w-full md:w-64">
<label className="flex items-center gap-3 cursor-pointer bg-white px-4 py-3 rounded-xl border border-blue-200 shadow-sm hover:border-blue-400 transition-colors">
<input type="checkbox" checked={byokEnabled} onChange={e => setByokEnabled(e.target.checked)} className="w-4 h-4 text-blue-600 rounded focus:ring-blue-500" />
<span className="text-[10px] font-bold text-gray-700">Enable BYOK Mode</span>
</label>
{byokEnabled && (
<input
type="text"
placeholder="Enter Custom Quantum Key..."
value={byokKey}
onChange={e => setByokKey(e.target.value)}
className="text-[10px] font-mono bg-white border border-blue-200 rounded-xl px-3 py-2 outline-none focus:ring-2 focus:ring-blue-500"
/>
)}
</div>
</div>
<div className="mb-6 flex justify-between items-center">
<input type="text" placeholder="Filter Matrix..." value={searchQuery} onChange={e => setSearchQuery(e.target.value)} className="border rounded-full px-4 py-2 text-sm w-64 outline-none focus:ring-2 focus:ring-blue-500" />
</div>
<div className="space-y-8">
{['JVC', 'JC', 'XCU', 'XTM', 'IAM'].map(mod => {
const filtered = systemFeatures.filter(f => (f.module === mod || (!f.module && mod === 'IAM')) && (f.name.toLowerCase().includes(searchQuery.toLowerCase()) || f.key.toLowerCase().includes(searchQuery.toLowerCase())));
if (filtered.length === 0) return null;
return (
<div key={mod}>
<div className="flex justify-between items-center mb-4 border-l-4 border-blue-600 pl-3">
<span className="text-[10px] font-black text-blue-600">{mod} MODULES</span>
<div className="space-x-2">
<button type="button" onClick={() => { const u = {...tenantLicenses}; systemFeatures.filter(f => f.module === mod || (!f.module && mod === 'IAM')).forEach(f => u[f.key] = 'GRANTED'); setTenantLicenses(u); }} className="text-[8px] font-bold text-emerald-600 bg-emerald-50 px-2 py-1 rounded">Grant All</button>
<button type="button" onClick={() => { const u = {...tenantLicenses}; systemFeatures.filter(f => f.module === mod || (!f.module && mod === 'IAM')).forEach(f => u[f.key] = 'UPSELL'); setTenantLicenses(u); }} className="text-[8px] font-bold text-blue-600 bg-blue-50 px-2 py-1 rounded">Upsell All</button>
<button type="button" onClick={() => { const u = {...tenantLicenses}; systemFeatures.filter(f => f.module === mod || (!f.module && mod === 'IAM')).forEach(f => u[f.key] = 'HIDDEN'); setTenantLicenses(u); }} className="text-[8px] font-bold text-red-600 bg-red-50 px-2 py-1 rounded">Block All</button>
</div>
</div>
<div className="grid grid-cols-1 gap-2">
{filtered.map(feat => {
let isIncludedInPackage = false;
if (selectedTenant?.package) {
try {
const pkgFeats = JSON.parse(selectedTenant.package.features || "[]");
if (pkgFeats.includes(feat.key)) isIncludedInPackage = true;
} catch(e) {}
}
const val = isIncludedInPackage ? 'GRANTED' : (tenantLicenses[feat.key] || 'HIDDEN');
return (
<div key={feat.key} className={`flex justify-between items-center p-3 border rounded-lg ${isIncludedInPackage ? 'bg-gray-50 border-gray-200 opacity-70' : 'hover:border-blue-200'}`}>
<div className="text-sm font-bold">{feat.name} <span className="text-[9px] font-mono text-gray-400 block">{feat.key}</span></div>
<div className="flex items-center gap-3">
{isIncludedInPackage && <span className="text-[9px] font-bold text-blue-600 bg-blue-50 px-2 py-0.5 rounded border border-blue-100 uppercase">Included in Package</span>}
<select
value={val}
onChange={e => setTenantLicenses({...tenantLicenses, [feat.key]: e.target.value})}
className="text-xs font-bold p-1 rounded border"
disabled={isIncludedInPackage}
>
<option value="GRANTED">🟢 GRANTED</option>
<option value="UPSELL">💎 UPSELL</option>
<option value="HIDDEN"> HIDDEN</option>
</select>
</div>
</div>
);
})}
</div>
</div>
);
})}
</div>
</div>
<div className="p-5 border-t bg-gray-50 flex justify-end gap-3 relative z-50 shadow-[0_-10px_20px_-10px_rgba(0,0,0,0.05)]">
<button type="button" onClick={(e) => { e.preventDefault(); e.stopPropagation(); setShowTenantModal(false); }} disabled={isSavingMatrix} className="px-6 py-2.5 border border-gray-300 rounded-xl hover:bg-gray-100 text-gray-700 font-bold transition-colors cursor-pointer relative z-50">Cancel</button>
<button type="button" onClick={(e) => { e.preventDefault(); e.stopPropagation(); saveTenantMatrix(); }} disabled={isSavingMatrix} className={`px-6 py-2.5 rounded-xl font-bold transition-all shadow-lg cursor-pointer relative z-50 flex items-center gap-2 ${isSavingMatrix ? 'bg-blue-400 text-white cursor-not-allowed' : 'bg-gradient-to-r from-blue-600 to-indigo-600 text-white hover:shadow-blue-500/30 hover:-translate-y-0.5'}`}>
{isSavingMatrix ? (
<>
<svg className="animate-spin h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle><path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>
Menyimpan...
</>
) : 'Deploy Matrix'}
</button>
</div>
</div>
</div>
)}
{/* SECURITY TIER SWITCH MODAL */}
{tierModal && (
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-md" onClick={() => !tierSwitching && setTierModal(null)}>
<div className="bg-gradient-to-b from-slate-900 to-slate-950 w-full max-w-lg rounded-2xl shadow-2xl border border-slate-700/50 overflow-hidden" onClick={e => e.stopPropagation()}>
{/* Header */}
<div className="p-6 text-center border-b border-slate-800">
<div className="w-14 h-14 mx-auto mb-3 rounded-2xl bg-gradient-to-br from-cyan-500 to-blue-600 flex items-center justify-center shadow-lg shadow-cyan-500/20">
<svg className="w-7 h-7 text-white" fill="currentColor" viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
</div>
<h3 className="text-lg font-bold text-white">Security Tier Configuration</h3>
<p className="text-xs text-slate-400 mt-1">Tenant: <strong className="text-white">{tierModal.tenantName}</strong></p>
</div>
{/* Radio Options */}
<div className="p-5 space-y-2">
{Object.entries(TIER_CONFIG).map(([key, cfg]) => (
<button
key={key}
onClick={() => setSelectedTier(key)}
className={`w-full text-left p-4 rounded-xl border-2 transition-all ${
selectedTier === key
? `${cfg.bg} ${cfg.border} ring-1 ${cfg.border}`
: 'border-slate-700/50 hover:border-slate-600'
}`}
>
<div className="flex items-center gap-3">
<div className={`w-5 h-5 rounded-full border-2 flex items-center justify-center ${
selectedTier === key ? cfg.border : 'border-slate-600'
}`}>
{selectedTier === key && <div className={`w-2.5 h-2.5 rounded-full ${
key === 'STANDARD' ? 'bg-emerald-400' : key === 'SOVEREIGN' ? 'bg-cyan-400' : 'bg-amber-400'
}`}></div>}
</div>
<div className="flex-1">
<div className="flex items-center gap-2">
<span className="text-base">{cfg.icon}</span>
<span className={`text-sm font-bold ${selectedTier === key ? cfg.color : 'text-slate-300'}`}>{cfg.label}</span>
{tierModal.currentTier === key && <span className="text-[8px] font-bold px-1.5 py-0.5 rounded bg-slate-700 text-slate-400 uppercase">Current</span>}
</div>
<p className="text-[11px] text-slate-500 mt-0.5 ml-7">{cfg.desc}</p>
</div>
</div>
</button>
))}
</div>
{/* Actions */}
<div className="px-5 pb-5 flex gap-3">
<button
onClick={() => setTierModal(null)}
disabled={tierSwitching}
className="flex-1 px-4 py-3 bg-slate-800 hover:bg-slate-700 text-slate-300 font-bold rounded-xl transition-colors border border-slate-700"
>Batal</button>
<button
onClick={applySecurityTier}
disabled={tierSwitching || selectedTier === tierModal.currentTier}
className={`flex-1 px-4 py-3 font-bold rounded-xl transition-all shadow-lg flex items-center justify-center gap-2 ${
tierSwitching || selectedTier === tierModal.currentTier
? 'bg-slate-700 text-slate-500 cursor-not-allowed'
: 'bg-gradient-to-r from-cyan-600 to-blue-600 text-white hover:shadow-cyan-500/30 hover:scale-[1.02]'
}`}
>
{tierSwitching ? (
<><div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"></div> Switching...</>
) : (
<><svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg> {selectedTier === tierModal.currentTier ? 'No Change' : 'Apply Security Tier'}</>
)}
</button>
</div>
</div>
</div>
)}
</div>
);
}
@@ -0,0 +1,255 @@
"use client";
import { useEffect, useState } from "react";
export default function SovereignSetup() {
const [os, setOs] = useState<string>("unknown");
const [certStatus, setCertStatus] = useState<"idle" | "testing" | "ok" | "fail">("idle");
const [tenantName, setTenantName] = useState("SOVEREIGN TENANT");
useEffect(() => {
const ua = navigator.userAgent.toLowerCase();
if (ua.includes("android")) setOs("android");
else if (ua.includes("iphone") || ua.includes("ipad")) setOs("ios");
else if (ua.includes("mac")) setOs("macos");
else if (ua.includes("windows")) setOs("windows");
else if (ua.includes("linux")) setOs("linux");
else setOs("unknown");
// Fetch tenant info
fetch("/api/auth/me").then(r => r.json()).then(d => {
if (d.tenantName) setTenantName(d.tenantName);
}).catch(() => {});
}, []);
const testConnection = async () => {
setCertStatus("testing");
try {
const resp = await fetch("/api/superadmin/xcu-tls-switch");
if (resp.ok) {
const data = await resp.json();
const onlineNodes = data.nodes?.filter((n: any) => n.online) || [];
setCertStatus(onlineNodes.length > 0 ? "ok" : "fail");
} else {
setCertStatus("fail");
}
} catch {
setCertStatus("fail");
}
};
const instructions: Record<string, { title: string; icon: string; steps: string[] }> = {
android: {
title: "Android",
icon: "📱",
steps: [
"Tap tombol \"Download CA Certificate\" di bawah",
"Buka Settings → Security → Encryption & Credentials",
"Tap \"Install a certificate\" → \"CA certificate\"",
"Pilih file xcu-sovereign-ca.crt yang baru di-download",
"Konfirmasi dengan PIN/Fingerprint",
"Selesai! Certificate berlaku 30 tahun"
]
},
ios: {
title: "iPhone / iPad",
icon: "🍎",
steps: [
"Tap tombol \"Download CA Certificate\" di bawah",
"iOS akan menampilkan \"Profile Downloaded\"",
"Buka Settings → General → VPN & Device Management",
"Tap profile \"XCU Sovereign CA\" → Install",
"Buka Settings → General → About → Certificate Trust Settings",
"Enable trust untuk \"XCU Sovereign CA\"",
"Selesai! Certificate berlaku 30 tahun"
]
},
windows: {
title: "Windows",
icon: "🖥️",
steps: [
"Klik tombol \"Download CA Certificate\" di bawah",
"Double-click file xcu-sovereign-ca.crt",
"Klik \"Install Certificate...\"",
"Pilih \"Local Machine\" → Next",
"Pilih \"Place all certificates in the following store\"",
"Klik Browse → pilih \"Trusted Root Certification Authorities\"",
"Klik Finish → Yes",
"Restart browser. Selesai!"
]
},
macos: {
title: "macOS",
icon: "💻",
steps: [
"Klik tombol \"Download CA Certificate\" di bawah",
"Double-click file xcu-sovereign-ca.crt → Keychain Access terbuka",
"Certificate muncul di login keychain",
"Double-click certificate → Trust → \"Always Trust\"",
"Tutup dialog, masukkan password Mac",
"Restart browser. Selesai!"
]
},
linux: {
title: "Linux",
icon: "🐧",
steps: [
"Download CA Certificate",
"sudo cp xcu-sovereign-ca.crt /usr/local/share/ca-certificates/",
"sudo update-ca-certificates",
"Restart browser. Selesai!"
]
},
unknown: {
title: "Device",
icon: "🔧",
steps: ["Download CA Certificate dan install sesuai OS Anda"]
}
};
const currentOs = instructions[os] || instructions.unknown;
return (
<div className="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950 text-white">
{/* Header */}
<header className="border-b border-slate-800 px-6 py-4">
<div className="max-w-4xl mx-auto flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-amber-500 to-orange-600 flex items-center justify-center shadow-lg">
<svg className="w-5 h-5 text-white" fill="currentColor" viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
</div>
<div>
<h1 className="text-lg font-bold tracking-tight">Sovereign Security Setup</h1>
<p className="text-xs text-slate-400">{tenantName} Private CA Installation</p>
</div>
</div>
<a href="/supreme-admin" className="text-xs text-slate-400 hover:text-white transition-colors"> Back to Dashboard</a>
</div>
</header>
<main className="max-w-4xl mx-auto px-6 py-10 space-y-8">
{/* Hero Card */}
<div className="bg-gradient-to-r from-amber-500/10 via-orange-500/5 to-transparent border border-amber-500/20 rounded-2xl p-8">
<div className="flex items-start gap-4">
<div className="text-4xl">🛡</div>
<div>
<h2 className="text-2xl font-bold mb-2">Mode Sovereign Aktif</h2>
<p className="text-slate-300 text-sm leading-relaxed">
Tenant ini beroperasi dalam <strong className="text-amber-400">Security Tier SOVEREIGN</strong>.
Semua koneksi QUIC/WebTransport menggunakan Private CA yang tidak bergantung pada internet global.
Setiap device perlu install sertifikat CA <strong>1× saja</strong>, berlaku <strong>30 tahun</strong>.
</p>
</div>
</div>
</div>
{/* Download Section */}
<div className="bg-slate-800/50 border border-slate-700 rounded-2xl p-8">
<h3 className="text-lg font-bold mb-4 flex items-center gap-2">
<span className="w-8 h-8 rounded-lg bg-emerald-500/20 flex items-center justify-center text-emerald-400 text-sm font-bold">1</span>
Download Certificate
</h3>
<div className="flex flex-wrap gap-4">
<a
href="/api/superadmin/sovereign-ca/download"
download="xcu-sovereign-ca.crt"
className="inline-flex items-center gap-3 px-6 py-3 bg-gradient-to-r from-emerald-600 to-emerald-500 hover:from-emerald-500 hover:to-emerald-400 text-white font-bold rounded-xl transition-all duration-300 shadow-lg shadow-emerald-500/20 hover:shadow-emerald-500/40 hover:scale-105"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>
Download CA Certificate
</a>
<div className="flex items-center gap-2 text-xs text-slate-500">
<span>Format: X.509 PEM</span>
<span></span>
<span>Validitas: 30 tahun</span>
<span></span>
<span>Algorithm: RSA-4096 + SHA-256</span>
</div>
</div>
</div>
{/* OS-Specific Instructions */}
<div className="bg-slate-800/50 border border-slate-700 rounded-2xl p-8">
<h3 className="text-lg font-bold mb-1 flex items-center gap-2">
<span className="w-8 h-8 rounded-lg bg-blue-500/20 flex items-center justify-center text-blue-400 text-sm font-bold">2</span>
Install Certificate
</h3>
<p className="text-xs text-slate-400 mb-6">
Terdeteksi: <strong className="text-cyan-400">{currentOs.icon} {currentOs.title}</strong>
</p>
{/* OS Tabs */}
<div className="flex flex-wrap gap-2 mb-6">
{Object.entries(instructions).filter(([k]) => k !== 'unknown').map(([key, val]) => (
<button
key={key}
onClick={() => setOs(key)}
className={`px-4 py-2 rounded-lg text-xs font-bold uppercase tracking-wider transition-all ${
os === key
? 'bg-cyan-500 text-white shadow-lg shadow-cyan-500/30'
: 'bg-slate-700 text-slate-400 hover:bg-slate-600 hover:text-white'
}`}
>
{val.icon} {val.title}
</button>
))}
</div>
{/* Steps */}
<div className="space-y-3">
{currentOs.steps.map((step, idx) => (
<div key={idx} className="flex gap-3 items-start">
<div className="w-6 h-6 rounded-full bg-slate-700 flex items-center justify-center text-[10px] font-bold text-cyan-400 flex-shrink-0 mt-0.5">
{idx + 1}
</div>
<p className="text-sm text-slate-300">{step}</p>
</div>
))}
</div>
</div>
{/* Connection Test */}
<div className="bg-slate-800/50 border border-slate-700 rounded-2xl p-8">
<h3 className="text-lg font-bold mb-4 flex items-center gap-2">
<span className="w-8 h-8 rounded-lg bg-purple-500/20 flex items-center justify-center text-purple-400 text-sm font-bold">3</span>
Verify Connection
</h3>
<div className="flex items-center gap-4">
<button
onClick={testConnection}
disabled={certStatus === "testing"}
className="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-purple-600 to-purple-500 hover:from-purple-500 hover:to-purple-400 text-white font-bold rounded-xl transition-all duration-300 shadow-lg shadow-purple-500/20 disabled:opacity-50"
>
{certStatus === "testing" ? (
<div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin"></div>
) : (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
)}
Test Connection
</button>
{certStatus === "ok" && (
<div className="flex items-center gap-2 px-4 py-2 bg-emerald-500/10 border border-emerald-500/20 rounded-xl">
<span className="relative flex h-3 w-3">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
<span className="relative inline-flex rounded-full h-3 w-3 bg-emerald-400"></span>
</span>
<span className="text-sm font-bold text-emerald-400">Koneksi Aman XCU Engine Online</span>
</div>
)}
{certStatus === "fail" && (
<div className="flex items-center gap-2 px-4 py-2 bg-red-500/10 border border-red-500/20 rounded-xl">
<span className="w-3 h-3 rounded-full bg-red-500"></span>
<span className="text-sm font-bold text-red-400">Koneksi Gagal Pastikan certificate sudah terinstall</span>
</div>
)}
</div>
</div>
{/* Info */}
<div className="text-center text-xs text-slate-600 py-4">
XCom ULTRA Sovereign Security Infrastructure Private CA Zero Internet Dependency
</div>
</main>
</div>
);
}
@@ -0,0 +1,288 @@
"use client";
import { useEffect, useState, useRef } from "react";
import { useDictionary } from "@/lib/dictionary";
import { useRouter } from "next/navigation";
export default function PanopticonTelemetry() {
const { t } = useDictionary();
const [logs, setLogs] = useState<{ id: string; time: string; action: string; target: string; status: string }[]>([]);
const [activeConnections, setActiveConnections] = useState(14029);
const [bandwidth, setBandwidth] = useState(24.5);
const [targetKillId, setTargetKillId] = useState("");
const canvasRef = useRef<HTMLCanvasElement>(null);
const router = useRouter();
const [isCheckingAuth, setIsCheckingAuth] = useState(true);
useEffect(() => {
const checkAuth = async () => {
try {
const res = await fetch("/api/superadmin/supreme-dashboard");
const data = await res.json();
if (data.error) {
router.push("/");
} else {
setIsCheckingAuth(false);
}
} catch (err) {
router.push("/");
}
};
checkAuth();
}, [router]);
// Move conditional return AFTER all hooks to comply with React Rules of Hooks
// (early return is placed after line 124 instead)
// WebGL-Style Waveform Simulation using Canvas for Zero-Error absolute performance
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
let animationFrameId: number;
let time = 0;
const resize = () => {
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
};
window.addEventListener("resize", resize);
resize();
const draw = () => {
time += 0.05;
ctx.clearRect(0, 0, canvas.width, canvas.height);
const width = canvas.width;
const height = canvas.height;
const centerY = height / 2;
// Draw multiple waves
for (let i = 0; i < 3; i++) {
ctx.beginPath();
ctx.moveTo(0, centerY);
for (let x = 0; x < width; x++) {
const frequency = 0.01 + (i * 0.005);
const amplitude = 30 + (i * 15) + Math.sin(time + x * 0.02) * 10;
const y = Math.sin(x * frequency + time + i * 2) * amplitude;
ctx.lineTo(x, centerY + y);
}
// WhatsApp Emerald to Zoom Blue Gradient
const gradient = ctx.createLinearGradient(0, 0, width, 0);
gradient.addColorStop(0, "rgba(37, 211, 102, 0.4)"); // WhatsApp Green
gradient.addColorStop(0.5, "rgba(11, 92, 255, 0.6)"); // Zoom Blue
gradient.addColorStop(1, "rgba(255, 0, 128, 0.3)"); // XCU Magenta
ctx.strokeStyle = gradient;
ctx.lineWidth = 2 + i;
ctx.stroke();
}
animationFrameId = requestAnimationFrame(draw);
};
draw();
return () => {
window.removeEventListener("resize", resize);
cancelAnimationFrame(animationFrameId);
};
}, []);
// Fetch real telemetry data from PANOPTICON backend
useEffect(() => {
const fetchTelemetry = async () => {
try {
const res = await fetch("/api/superadmin/telemetry");
if (res.ok) {
const data = await res.json();
// Transform quantum logs into UI log format
const formattedLogs = data.logs.map((log: any) => ({
id: log.id,
time: log.nanoTimestamp ? new Date(log.nanoTimestamp).toISOString().split("T")[1].substring(0, 8) : "00:00:00",
action: log.action,
target: log.targetId,
status: log.action.includes("KILL") ? "TERMINATED" : "OK",
}));
setLogs(formattedLogs);
setActiveConnections(data.stats.totalTelemetryRecords);
setBandwidth(parseFloat(data.stats.totalBandwidthBytes) / 1024 / 1024 / 1024);
}
} catch (err) {
console.error("PANOPTICON Sync Error:", err);
}
};
fetchTelemetry();
const interval = setInterval(fetchTelemetry, 2000);
return () => clearInterval(interval);
}, []);
// Auth guard AFTER all hooks (React Rules of Hooks compliance)
if (isCheckingAuth) {
return <div className="min-h-screen bg-black flex items-center justify-center text-purple-500 font-mono text-sm">INITIALIZING SECURE CONNECTION...</div>;
}
const executeLiveKill = async () => {
if (!targetKillId) return;
// Spectactular Kill Trigger Effect
document.body.style.animation = "shake 0.5s cubic-bezier(.36,.07,.19,.97) both";
setTimeout(() => document.body.style.animation = "", 500);
const res = await fetch("/api/telemetry/live-kill", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
targetType: "USER",
targetId: targetKillId,
reason: "SUPREME_ADMIN_OVERRIDE"
})
});
if (res.ok) {
setLogs(prev => [{
id: "KILL_" + Date.now(),
time: new Date().toISOString().split("T")[1].substring(0, 8),
action: "LIVE_KILL_EXECUTE",
target: targetKillId,
status: "TERMINATED"
}, ...prev]);
setTargetKillId("");
alert("XCU MoQ Ejection Berhasil. Sesi Dihanguskan.");
} else {
alert("Akses Ditolak: Quantum Jurisdiction");
}
};
return (
<div className="min-h-screen bg-[#050914] text-gray-200 font-sans selection:bg-blue-500/30 overflow-hidden relative">
<style dangerouslySetInnerHTML={{__html: `
@keyframes shake {
10%, 90% { transform: translate3d(-1px, 0, 0); }
20%, 80% { transform: translate3d(2px, 0, 0); }
30%, 50%, 70% { transform: translate3d(-4px, 0, 0); }
40%, 60% { transform: translate3d(4px, 0, 0); }
}
.matrix-bg {
background-image:
linear-gradient(rgba(11, 92, 255, 0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(37, 211, 102, 0.05) 1px, transparent 1px);
background-size: 30px 30px;
}
`}} />
{/* Decorative Grid */}
<div className="absolute inset-0 matrix-bg pointer-events-none z-0"></div>
<div className="relative z-10 p-6 md:p-10 max-w-7xl mx-auto flex flex-col gap-8 h-screen">
{/* HEADER */}
<header className="flex justify-between items-center border-b border-white/10 pb-6">
<div>
<h1 className="text-3xl font-black tracking-tighter text-transparent bg-clip-text bg-gradient-to-r from-[#25D366] via-[#0b5cff] to-[#ff0080]">
PANOPTICON OMNISCIENT
</h1>
<p className="text-sm font-mono text-blue-400/80 uppercase tracking-widest mt-1">
Supreme Admin XCU Level 1 Akses Absolut
</p>
</div>
<div className="flex gap-4 items-center">
<div className="px-4 py-2 rounded-lg bg-green-500/10 border border-green-500/30 flex items-center gap-2 shadow-[0_0_15px_rgba(37,211,102,0.2)]">
<span className="w-2 h-2 rounded-full bg-green-500 animate-pulse"></span>
<span className="font-mono text-green-400 text-sm font-bold">CLUSTER STABLE</span>
</div>
<a href="/supreme-admin" className="px-4 py-2 rounded-lg bg-white/5 hover:bg-white/10 border border-white/10 text-sm font-bold transition-all">
Tutup Dasbor
</a>
</div>
</header>
{/* TOP METRICS */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<div className="bg-black/40 backdrop-blur-xl border border-white/5 rounded-2xl p-6 relative overflow-hidden group">
<div className="absolute inset-0 bg-gradient-to-br from-blue-500/10 to-transparent opacity-0 group-hover:opacity-100 transition-all duration-500"></div>
<p className="text-sm font-mono text-gray-500 uppercase">XCU Active MoC Streams</p>
<p className="text-5xl font-black mt-2 text-white font-mono tracking-tighter">
{activeConnections.toLocaleString()}
</p>
</div>
<div className="bg-black/40 backdrop-blur-xl border border-white/5 rounded-2xl p-6 relative overflow-hidden group">
<div className="absolute inset-0 bg-gradient-to-br from-green-500/10 to-transparent opacity-0 group-hover:opacity-100 transition-all duration-500"></div>
<p className="text-sm font-mono text-gray-500 uppercase">Global Bandwidth (Gbps)</p>
<p className="text-5xl font-black mt-2 text-transparent bg-clip-text bg-gradient-to-r from-white to-gray-500 font-mono tracking-tighter">
{bandwidth.toFixed(2)}
</p>
</div>
<div className="bg-black/40 backdrop-blur-xl border border-red-500/20 rounded-2xl p-6 relative shadow-[0_0_30px_rgba(255,0,0,0.1)]">
<p className="text-sm font-bold text-red-500 uppercase mb-4 flex items-center gap-2">
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2L1 21h22M12 6l7.5 13h-15M11 10h2v5h-2M11 16h2v2h-2"/></svg>
GUILLOTINE PANEL
</p>
<div className="flex gap-2">
<input
type="text"
value={targetKillId}
onChange={(e) => setTargetKillId(e.target.value)}
placeholder="Target ID (e.g. tsm@pc24.id)"
className="w-full bg-black/50 border border-red-500/30 rounded-lg px-3 py-2 text-sm font-mono focus:outline-none focus:border-red-500 text-white placeholder-gray-600"
/>
<button
onClick={executeLiveKill}
className="bg-red-600 hover:bg-red-500 text-white px-4 py-2 rounded-lg font-bold text-sm tracking-widest shadow-[0_0_15px_rgba(255,0,0,0.4)] transition-all hover:scale-105 active:scale-95"
>
KILL
</button>
</div>
</div>
</div>
{/* VISUALIZATION & LOGS */}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 flex-1 min-h-0">
{/* Waveform Canvas */}
<div className="lg:col-span-2 bg-black/40 backdrop-blur-xl border border-white/5 rounded-2xl relative overflow-hidden flex flex-col">
<div className="p-4 border-b border-white/5 flex justify-between items-center bg-black/40">
<p className="text-xs font-mono text-blue-400">LIVE XCU eBPF TELEMETRY (ZOOM x WA MULTIPLEXING)</p>
<div className="flex gap-2">
<span className="w-2 h-2 rounded-full bg-blue-500"></span>
<span className="w-2 h-2 rounded-full bg-green-500"></span>
</div>
</div>
<div className="flex-1 relative">
<canvas ref={canvasRef} className="absolute inset-0 w-full h-full opacity-80 mix-blend-screen"></canvas>
</div>
</div>
{/* Hacker Log Stream */}
<div className="bg-black/60 backdrop-blur-xl border border-white/5 rounded-2xl flex flex-col overflow-hidden relative shadow-inner">
<div className="absolute inset-x-0 top-0 h-8 bg-gradient-to-b from-blue-500/10 to-transparent z-10 pointer-events-none"></div>
<div className="p-4 border-b border-white/5 bg-[#0a0a0a]">
<p className="text-xs font-mono text-gray-400 flex items-center gap-2">
<span className="w-2 h-2 rounded-full bg-red-500 animate-ping"></span>
QUANTUM TRACE LOGS
</p>
</div>
<div className="flex-1 overflow-y-auto p-4 font-mono text-xs flex flex-col gap-1">
{logs.map((log, i) => (
<div key={log.id + i} className="flex gap-3 hover:bg-white/5 px-2 py-1 rounded transition-colors group">
<span className="text-gray-600">[{log.time}]</span>
<span className={log.status === 'TERMINATED' ? 'text-red-500 font-bold' : log.status === 'WARN' ? 'text-yellow-500' : 'text-green-400'}>
{log.action}
</span>
<span className="text-blue-300 ml-auto opacity-70 group-hover:opacity-100">{log.target}</span>
</div>
))}
</div>
</div>
</div>
</div>
</div>
);
}
@@ -0,0 +1,315 @@
"use client";
import { useEffect, useState, useRef } from "react";
import { useDictionary } from "@/lib/dictionary";
import { useOmni } from "@/components/OmniSyncProvider";
import Link from "next/link";
import { useRouter } from "next/navigation";
interface NeuralSubject {
id: string;
name: string;
attentionScore: number;
cognitiveLoad: number;
alphaWave: number;
status: "FOCUSED" | "DISTRACTED" | "ZONED_OUT";
}
export default function TelepathyMatrix() {
const { t } = useDictionary();
const { theme, locale } = useOmni();
const router = useRouter();
const [isCheckingAuth, setIsCheckingAuth] = useState(true);
// ALL HOOKS MUST BE DECLARED BEFORE ANY CONDITIONAL RETURN (React Rules of Hooks)
const [subjects, setSubjects] = useState<NeuralSubject[]>([
{ id: "xcu_subj_01", name: "Commander Alpha", attentionScore: 95, cognitiveLoad: 80, alphaWave: 0.8, status: "FOCUSED" },
{ id: "xcu_subj_02", name: "Operative Bravo", attentionScore: 88, cognitiveLoad: 60, alphaWave: 0.6, status: "FOCUSED" },
{ id: "xcu_subj_03", name: "Spectre 7", attentionScore: 45, cognitiveLoad: 30, alphaWave: 0.4, status: "DISTRACTED" },
{ id: "xcu_subj_04", name: "Agent Echo", attentionScore: 12, cognitiveLoad: 10, alphaWave: 0.1, status: "ZONED_OUT" },
{ id: "xcu_subj_05", name: "Node Delta", attentionScore: 78, cognitiveLoad: 70, alphaWave: 0.7, status: "FOCUSED" },
{ id: "xcu_subj_06", name: "Vanguard 1", attentionScore: 25, cognitiveLoad: 15, alphaWave: 0.2, status: "ZONED_OUT" },
]);
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const checkAuth = async () => {
try {
const res = await fetch("/api/superadmin/supreme-dashboard");
const data = await res.json();
if (data.error) {
router.push("/");
} else {
setIsCheckingAuth(false);
}
} catch (err) {
router.push("/");
}
};
checkAuth();
}, [router]);
// Brainwave Visualization Effect - MUST be before conditional return (React Rules of Hooks)
useEffect(() => {
if (isCheckingAuth) return;
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
let animationFrameId: number;
let time = 0;
const resize = () => {
canvas.width = canvas.parentElement?.clientWidth || 800;
canvas.height = 150;
};
window.addEventListener("resize", resize);
resize();
const draw = () => {
time += 0.05;
ctx.clearRect(0, 0, canvas.width, canvas.height);
const width = canvas.width;
const height = canvas.height;
const centerY = height / 2;
// Draw 3 Brainwaves (Alpha, Beta, Gamma)
const waves = [
{ color: "rgba(11, 92, 255, 0.8)", freq: 0.02, amp: 20, speed: 1.5 }, // Alpha (Blue)
{ color: "rgba(37, 211, 102, 0.8)", freq: 0.05, amp: 10, speed: 2.5 }, // Beta (Green)
{ color: "rgba(255, 0, 128, 0.8)", freq: 0.1, amp: 5, speed: 4.0 } // Gamma (Magenta)
];
waves.forEach((wave, i) => {
ctx.beginPath();
ctx.moveTo(0, centerY);
for (let x = 0; x < width; x++) {
const y = Math.sin(x * wave.freq + time * wave.speed + i) * wave.amp
+ Math.sin(x * wave.freq * 0.5 + time) * (wave.amp * 0.5);
ctx.lineTo(x, centerY + y);
}
ctx.strokeStyle = wave.color;
ctx.lineWidth = 2;
ctx.stroke();
});
// Draw grid overlay
ctx.strokeStyle = "rgba(255,255,255,0.05)";
ctx.lineWidth = 1;
for (let x = 0; x < width; x += 30) {
ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, height); ctx.stroke();
}
for (let y = 0; y < height; y += 30) {
ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(width, y); ctx.stroke();
}
animationFrameId = requestAnimationFrame(draw);
};
draw();
return () => {
window.removeEventListener("resize", resize);
cancelAnimationFrame(animationFrameId);
};
}, [isCheckingAuth]);
// Simulate real-time neural data updates - MUST be before conditional return
useEffect(() => {
if (isCheckingAuth) return;
const interval = setInterval(() => {
setSubjects(prev => prev.map(s => {
let newScore = s.attentionScore + (Math.random() * 10 - 5);
newScore = Math.max(0, Math.min(100, newScore));
let newStatus: "FOCUSED" | "DISTRACTED" | "ZONED_OUT" = "FOCUSED";
if (newScore < 30) newStatus = "ZONED_OUT";
else if (newScore < 60) newStatus = "DISTRACTED";
return {
...s,
attentionScore: newScore,
cognitiveLoad: Math.max(0, Math.min(100, s.cognitiveLoad + (Math.random() * 6 - 3))),
status: newStatus
};
}));
}, 2000);
return () => clearInterval(interval);
}, [isCheckingAuth]);
if (isCheckingAuth) {
return <div className="min-h-screen bg-black flex items-center justify-center text-purple-500 font-mono text-sm">INITIALIZING SECURE CONNECTION...</div>;
}
const sendSensoryPing = (id: string, name: string) => {
// Flash the screen to simulate ping
const el = document.getElementById(`card-${id}`);
if (el) {
el.classList.add("ring-4", "ring-[#ff0080]", "ring-opacity-100", "scale-105");
setTimeout(() => el.classList.remove("ring-4", "ring-[#ff0080]", "ring-opacity-100", "scale-105"), 500);
}
alert(`Sensory Ping (Haptic & Audio) disuntikkan langsung ke korteks partisipan [${name}]`);
};
return (
<div className={`min-h-screen ${theme === 'dark' ? 'bg-[#03060a] text-gray-200' : 'bg-gray-50 text-gray-900'} font-sans selection:bg-purple-500/30 overflow-x-hidden relative`}>
<style dangerouslySetInnerHTML={{__html: `
@keyframes cyber-pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.8; transform: scale(0.98); }
}
.animate-cyber-pulse {
animation: cyber-pulse 2s infinite ease-in-out;
}
@keyframes emergency-flash {
0%, 100% { background-color: rgba(220, 38, 38, 0.1); border-color: rgba(220, 38, 38, 0.3); }
50% { background-color: rgba(220, 38, 38, 0.4); border-color: rgba(220, 38, 38, 0.8); box-shadow: 0 0 20px rgba(220, 38, 38, 0.6); }
}
.emergency-flash {
animation: emergency-flash 1s infinite;
}
`}} />
{/* Decorative Grid */}
<div className="absolute inset-0 z-0 pointer-events-none" style={{
backgroundImage: theme === 'dark'
? 'linear-gradient(rgba(255, 0, 128, 0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 0, 128, 0.03) 1px, transparent 1px)'
: 'linear-gradient(rgba(0, 0, 0, 0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(0, 0, 0, 0.03) 1px, transparent 1px)',
backgroundSize: '40px 40px'
}}></div>
<div className="relative z-10 p-6 md:p-10 max-w-7xl mx-auto flex flex-col gap-8">
{/* HEADER */}
<header className="flex flex-col md:flex-row justify-between items-start md:items-center border-b border-white/10 pb-6 gap-4">
<div>
<div className="flex items-center gap-3 mb-2">
<div className="w-8 h-8 bg-purple-500/20 rounded-lg flex items-center justify-center border border-purple-500/50 shadow-[0_0_15px_rgba(168,85,247,0.4)]">
<svg className="w-5 h-5 text-purple-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path></svg>
</div>
<h1 className="text-3xl font-black tracking-tighter text-transparent bg-clip-text bg-gradient-to-r from-[#ff0080] to-[#7928ca]">
TELEPATHY MATRIX
</h1>
</div>
<p className="text-sm font-mono text-purple-400/80 uppercase tracking-widest">
Global Neural Attention & Cognitive Load Dashboard
</p>
</div>
<div className="flex gap-4 items-center">
<div className="px-4 py-2 rounded-lg bg-red-500/10 border border-red-500/30 flex items-center gap-2">
<span className="w-2 h-2 rounded-full bg-red-500 animate-pulse"></span>
<span className="font-mono text-red-400 text-xs font-bold uppercase">Surveillance Active</span>
</div>
<Link href="/supreme-admin" className="px-4 py-2 rounded-lg bg-white/5 hover:bg-white/10 border border-white/10 text-sm font-bold transition-all shadow-sm">
Kembali ke Supreme Admin
</Link>
</div>
</header>
{/* MASTER OSCILLATOR CANVAS */}
<div className={`rounded-2xl border ${theme === 'dark' ? 'bg-black/60 border-white/10' : 'bg-white border-gray-200'} backdrop-blur-xl p-6 relative overflow-hidden shadow-2xl`}>
<div className="absolute top-4 left-4 flex items-center gap-2 z-20">
<span className="text-[10px] font-black uppercase tracking-widest text-gray-400">Aggregated Brainwaves</span>
</div>
<div className="absolute top-4 right-4 flex gap-3 z-20 text-[9px] font-black uppercase tracking-widest">
<div className="flex items-center gap-1"><span className="w-2 h-2 bg-blue-500 rounded-full"></span> Alpha (Relaxed)</div>
<div className="flex items-center gap-1"><span className="w-2 h-2 bg-green-500 rounded-full"></span> Beta (Focused)</div>
<div className="flex items-center gap-1"><span className="w-2 h-2 bg-[#ff0080] rounded-full"></span> Gamma (High Load)</div>
</div>
<div className="w-full h-[150px] mt-4 relative z-10 opacity-80 mix-blend-screen">
<canvas ref={canvasRef} className="absolute inset-0 w-full h-full"></canvas>
</div>
</div>
{/* NEURAL GRID */}
<div>
<div className="flex items-center justify-between mb-6">
<h2 className="text-xl font-black uppercase tracking-widest flex items-center gap-2">
<svg className="w-5 h-5 text-gray-500" fill="currentColor" viewBox="0 0 20 20"><path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z"></path><path fillRule="evenodd" d="M4 5a2 2 0 012-2 3 3 0 003 3h2a3 3 0 003-3 2 2 0 012 2v11a2 2 0 01-2 2H6a2 2 0 01-2-2V5zm3 4a1 1 0 000 2h.01a1 1 0 100-2H7zm3 0a1 1 0 000 2h3a1 1 0 100-2h-3zm-3 4a1 1 0 100 2h.01a1 1 0 100-2H7zm3 0a1 1 0 100 2h3a1 1 0 100-2h-3z" clipRule="evenodd"></path></svg>
Active Subjects
</h2>
<div className="text-[10px] font-mono bg-white/5 border border-white/10 px-3 py-1 rounded-full text-gray-400">
{subjects.filter(s => s.status === 'ZONED_OUT').length} CRITICAL / {subjects.length} TOTAL
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{subjects.map(subject => {
const isCritical = subject.status === 'ZONED_OUT';
return (
<div
id={`card-${subject.id}`}
key={subject.id}
className={`glass-panel p-6 rounded-2xl border transition-all duration-300 relative overflow-hidden group ${
isCritical ? 'emergency-flash' : theme === 'dark' ? 'border-white/5 bg-white/2 hover:border-white/20' : 'border-gray-200 bg-white hover:border-purple-300 shadow-sm'
}`}
>
{/* Background Glow */}
<div className={`absolute -right-10 -top-10 w-32 h-32 rounded-full blur-3xl opacity-20 pointer-events-none transition-colors ${
isCritical ? 'bg-red-500' : subject.status === 'FOCUSED' ? 'bg-emerald-500' : 'bg-amber-500'
}`}></div>
<div className="flex justify-between items-start mb-6 relative z-10">
<div>
<div className="text-[10px] font-mono text-gray-500">{subject.id}</div>
<h3 className={`text-lg font-black tracking-tight mt-1 ${theme === 'dark' ? 'text-white' : 'text-gray-900'}`}>{subject.name}</h3>
</div>
<div className={`px-2 py-1 rounded-md text-[9px] font-black uppercase tracking-widest border ${
isCritical ? 'bg-red-500/20 text-red-500 border-red-500/30' :
subject.status === 'FOCUSED' ? 'bg-emerald-500/20 text-emerald-500 border-emerald-500/30' :
'bg-amber-500/20 text-amber-500 border-amber-500/30'
}`}>
{subject.status}
</div>
</div>
<div className="space-y-5 relative z-10">
<div>
<div className="flex justify-between text-xs mb-1 font-bold">
<span className="text-gray-500 uppercase">Attention Score</span>
<span className={isCritical ? 'text-red-500' : 'text-emerald-500'}>{subject.attentionScore.toFixed(1)}%</span>
</div>
<div className="w-full bg-black/40 rounded-full h-1.5 overflow-hidden border border-white/5">
<div className={`h-full transition-all duration-500 ${isCritical ? 'bg-red-500' : 'bg-emerald-500'}`} style={{ width: `${subject.attentionScore}%` }}></div>
</div>
</div>
<div>
<div className="flex justify-between text-xs mb-1 font-bold">
<span className="text-gray-500 uppercase">Cognitive Load</span>
<span className="text-purple-400">{subject.cognitiveLoad.toFixed(1)}%</span>
</div>
<div className="w-full bg-black/40 rounded-full h-1.5 overflow-hidden border border-white/5">
<div className="bg-purple-500 h-full transition-all duration-500" style={{ width: `${subject.cognitiveLoad}%` }}></div>
</div>
</div>
</div>
<div className="mt-6 pt-4 border-t border-white/10 relative z-10 flex justify-between items-center">
<div className="text-[9px] font-mono text-gray-500">
Alpha: {subject.alphaWave.toFixed(2)}Hz
</div>
<button
onClick={() => sendSensoryPing(subject.id, subject.name)}
className={`px-4 py-2 rounded-lg text-[10px] font-black uppercase tracking-widest transition-all shadow-lg hover:scale-105 active:scale-95 ${
isCritical
? 'bg-red-600 hover:bg-red-500 text-white shadow-red-500/30'
: 'bg-white/10 hover:bg-white/20 text-gray-300 border border-white/10'
}`}
>
Sensory Ping
</button>
</div>
</div>
);
})}
</div>
</div>
</div>
</div>
);
}