mirror of
https://github.com/AeThex-Corporation/AeThex-OS.git
synced 2026-04-25 09:27:21 +00:00
Introduces authentication via JWT, session management with CSRF protection, and new admin routes for managing users, projects, and monitoring security. Enhances dashboard and home pages with dynamic metrics fetched from the backend. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 279f1558-c0e3-40e4-8217-be7e9f4c6eca Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: dcd55177-c240-4288-8fc0-652032c758f2 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/b984cb14-1d19-4944-922b-bc79e821ed35/279f1558-c0e3-40e4-8217-be7e9f4c6eca/2riq6Ir Replit-Helium-Checkpoint-Created: true
204 lines
9.1 KiB
TypeScript
204 lines
9.1 KiB
TypeScript
import { motion } from "framer-motion";
|
|
import { Link } from "wouter";
|
|
import { useQuery } from "@tanstack/react-query";
|
|
import { ArrowLeft, Users, ShieldAlert, Globe, Activity, TrendingUp, Target } from "lucide-react";
|
|
import { Bar, BarChart, ResponsiveContainer, LineChart, Line, Tooltip } from "recharts";
|
|
import mapBg from '@assets/generated_images/abstract_holographic_world_map_data_visualization.png';
|
|
|
|
export default function Dashboard() {
|
|
const { data: metrics } = useQuery({
|
|
queryKey: ["metrics"],
|
|
queryFn: async () => {
|
|
const res = await fetch("/api/metrics");
|
|
return res.json();
|
|
},
|
|
});
|
|
|
|
const MOCK_DATA = [
|
|
{ name: "Mon", value: 400 },
|
|
{ name: "Tue", value: 300 },
|
|
{ name: "Wed", value: 550 },
|
|
{ name: "Thu", value: 450 },
|
|
{ name: "Fri", value: 700 },
|
|
{ name: "Sat", value: 600 },
|
|
{ name: "Sun", value: 800 },
|
|
];
|
|
|
|
const THREAT_DATA = [
|
|
{ name: "00:00", value: 12 },
|
|
{ name: "04:00", value: 8 },
|
|
{ name: "08:00", value: 45 },
|
|
{ name: "12:00", value: 120 },
|
|
{ name: "16:00", value: 90 },
|
|
{ name: "20:00", value: 35 },
|
|
];
|
|
|
|
return (
|
|
<div className="min-h-screen bg-background text-foreground font-mono relative overflow-hidden">
|
|
|
|
{/* Background Map */}
|
|
<div
|
|
className="absolute inset-0 opacity-15 pointer-events-none z-0 mix-blend-screen"
|
|
style={{ backgroundImage: `url(${mapBg})`, backgroundSize: 'cover', backgroundPosition: 'center' }}
|
|
/>
|
|
|
|
<div className="relative z-10 p-6 md:p-10 flex flex-col min-h-screen">
|
|
|
|
{/* Header */}
|
|
<div className="flex flex-col md:flex-row justify-between items-start md:items-center mb-10 gap-4">
|
|
<div>
|
|
<Link href="/">
|
|
<button className="text-muted-foreground hover:text-primary transition-colors flex items-center gap-2 uppercase text-xs tracking-widest mb-2">
|
|
<ArrowLeft className="w-4 h-4" /> Return to Home
|
|
</button>
|
|
</Link>
|
|
<h1 className="text-3xl font-display font-bold uppercase text-white tracking-widest flex items-center gap-3">
|
|
<Globe className="w-8 h-8 text-primary" />
|
|
Axiom Command
|
|
</h1>
|
|
<p className="text-muted-foreground text-sm font-tech">Global Ecosystem Status // Live Data from Supabase</p>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-4">
|
|
<div className="text-right">
|
|
<div className="text-xs text-muted-foreground uppercase">System Status</div>
|
|
<div className="text-green-500 font-bold flex items-center gap-2 justify-end">
|
|
<span className="w-2 h-2 bg-green-500 rounded-full animate-pulse" /> OPERATIONAL
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* KPI Grid - Live Data */}
|
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-6 mb-10">
|
|
<Card
|
|
title="Active Architects"
|
|
value={metrics?.totalProfiles || 0}
|
|
icon={<Users className="w-5 h-5 text-primary" />}
|
|
/>
|
|
<Card
|
|
title="Total Projects"
|
|
value={metrics?.totalProjects || 0}
|
|
icon={<Activity className="w-5 h-5 text-secondary" />}
|
|
/>
|
|
<Card
|
|
title="Online Now"
|
|
value={metrics?.onlineUsers || 0}
|
|
icon={<div className="w-3 h-3 bg-green-500 rounded-full animate-pulse" />}
|
|
/>
|
|
<Card
|
|
title="Verified Users"
|
|
value={metrics?.verifiedUsers || 0}
|
|
icon={<ShieldAlert className="w-5 h-5 text-primary" />}
|
|
/>
|
|
</div>
|
|
|
|
{/* Charts Section */}
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 flex-1">
|
|
|
|
{/* Map / Main Viz */}
|
|
<div className="md:col-span-2 bg-card/50 border border-white/10 p-6 backdrop-blur-sm flex flex-col relative overflow-hidden group">
|
|
<div className="absolute inset-0 bg-gradient-to-b from-transparent to-background/80 pointer-events-none" />
|
|
<h3 className="text-sm font-bold text-white uppercase tracking-widest mb-6 flex items-center gap-2 relative z-10">
|
|
<Globe className="w-4 h-4" /> Global Deployment Heatmap
|
|
</h3>
|
|
|
|
{/* Fake Map Markers */}
|
|
<div className="flex-1 relative min-h-[300px] border border-white/5 bg-black/20 rounded-lg overflow-hidden">
|
|
<div className="absolute top-1/4 left-1/4 w-3 h-3 bg-primary rounded-full animate-ping" />
|
|
<div className="absolute top-1/4 left-1/4 w-3 h-3 bg-primary rounded-full" />
|
|
|
|
<div className="absolute top-1/3 left-1/2 w-3 h-3 bg-secondary rounded-full animate-ping" style={{ animationDelay: '0.3s' }} />
|
|
<div className="absolute top-1/3 left-1/2 w-3 h-3 bg-secondary rounded-full" />
|
|
|
|
<div className="absolute bottom-1/3 right-1/4 w-3 h-3 bg-destructive rounded-full animate-ping" style={{ animationDelay: '0.7s' }} />
|
|
<div className="absolute bottom-1/3 right-1/4 w-3 h-3 bg-destructive rounded-full" />
|
|
</div>
|
|
</div>
|
|
|
|
{/* Side Charts */}
|
|
<div className="space-y-6">
|
|
<div className="bg-card/50 border border-white/10 p-6 backdrop-blur-sm h-[200px] flex flex-col">
|
|
<h3 className="text-xs font-bold text-muted-foreground uppercase tracking-widest mb-4">Recruitment Velocity</h3>
|
|
<div className="flex-1 w-full">
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
<BarChart data={MOCK_DATA}>
|
|
<Bar dataKey="value" fill="hsl(var(--primary))" radius={[2, 2, 0, 0]} />
|
|
</BarChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="bg-card/50 border border-white/10 p-6 backdrop-blur-sm h-[200px] flex flex-col">
|
|
<h3 className="text-xs font-bold text-muted-foreground uppercase tracking-widest mb-4">Threat Vectors (24h)</h3>
|
|
<div className="flex-1 w-full">
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
<LineChart data={THREAT_DATA}>
|
|
<Line type="monotone" dataKey="value" stroke="hsl(var(--destructive))" strokeWidth={2} dot={false} />
|
|
<Tooltip
|
|
contentStyle={{ backgroundColor: 'hsl(var(--card))', border: '1px solid hsl(var(--border))' }}
|
|
itemStyle={{ color: 'hsl(var(--foreground))' }}
|
|
/>
|
|
</LineChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{/* XP Stats */}
|
|
<div className="mt-8 bg-card/50 border border-white/10 p-6">
|
|
<h3 className="text-sm font-bold text-white uppercase tracking-widest mb-4">
|
|
Ecosystem Stats (Live)
|
|
</h3>
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-6">
|
|
<div>
|
|
<div className="text-3xl font-display font-bold text-primary">
|
|
{metrics?.totalXP?.toLocaleString() || 0}
|
|
</div>
|
|
<div className="text-xs text-muted-foreground uppercase">Total XP Earned</div>
|
|
</div>
|
|
<div>
|
|
<div className="text-3xl font-display font-bold text-white">
|
|
{metrics?.avgLevel || 1}
|
|
</div>
|
|
<div className="text-xs text-muted-foreground uppercase">Avg Level</div>
|
|
</div>
|
|
<div>
|
|
<div className="text-3xl font-display font-bold text-secondary">
|
|
{metrics?.totalProfiles || 0}
|
|
</div>
|
|
<div className="text-xs text-muted-foreground uppercase">Registered</div>
|
|
</div>
|
|
<div>
|
|
<div className="text-3xl font-display font-bold text-green-500">
|
|
{metrics?.onlineUsers || 0}
|
|
</div>
|
|
<div className="text-xs text-muted-foreground uppercase">Online Now</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function Card({ title, value, icon }: { title: string, value: number, icon: React.ReactNode }) {
|
|
return (
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 10 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
className="bg-card/50 border border-white/10 p-6 backdrop-blur-sm hover:border-primary/30 transition-colors"
|
|
>
|
|
<div className="flex justify-between items-start mb-4">
|
|
<div className="text-xs text-muted-foreground uppercase tracking-widest font-bold">{title}</div>
|
|
{icon}
|
|
</div>
|
|
<div className="flex items-end justify-between">
|
|
<div className="text-3xl font-display font-bold text-white">{value}</div>
|
|
</div>
|
|
</motion.div>
|
|
)
|
|
}
|