/* * ============================================================================= * VibeQuant (vquant) — AI-Powered Financial Intelligence Platform * ----------------------------------------------------------------------------- * File: client/src/pages/admin.tsx * * Author: Simon-Pierre Boucher * Contact: contact@spboucher.ai * Website: https://www.spboucher.ai * Demo: https://www.vquant.ai * License: MIT (see LICENSE) * * Copyright © 2026 Simon-Pierre Boucher. All rights reserved. * ============================================================================= */ import { useState, useEffect } from "react"; import { useLocation } from "wouter"; import { Shield, Database, FileText, MessageSquare, Trash2, Sparkles, DollarSign, TrendingUp, Users as UsersIcon, Activity, Zap, AlertCircle, RefreshCw } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Badge } from "@/components/ui/badge"; interface User { id: string; displayName: string; createdAt: string; } interface Session { id: string; sessionId: string; userId: string | null; title: string; createdAt: string; updatedAt: string; inputTokens: number; outputTokens: number; totalCost: number; } interface SharedReport { id: string; shareId: string; question: string; createdAt: string; } interface UserMetric { userId: string; displayName: string; inputTokens: number; outputTokens: number; totalTokens: number; cost: number; sessionCount: number; } interface Metrics { totalInputTokens: number; totalOutputTokens: number; totalTokens: number; totalCost: number; totalSessions: number; averageCostPerSession: number; userMetrics: UserMetric[]; } interface DatabaseData { users: User[]; sessions: Session[]; sharedReports: SharedReport[]; metrics: Metrics; } interface ActiveUsersData { total: number; generating: number; idle: number; error: number; users: Array<{ sessionId: string; userId: string | null; status: string; currentQuery: string | null; lastHeartbeat: string; userAgent: string | null; }>; } interface RealTimeStats { activeUsers: { total: number; generating: number; }; sessions: { total: number; today: number; }; tokens: { total: number; input: number; output: number; }; cost: { total: number; today: number; }; errors: { lastHour: number; rate: number; }; } export default function Admin() { const [, setLocation] = useLocation(); const [isAuthenticated, setIsAuthenticated] = useState(false); const [password, setPassword] = useState(""); const [error, setError] = useState(""); const [isLoading, setIsLoading] = useState(true); const [databaseData, setDatabaseData] = useState(null); const [activeUsersData, setActiveUsersData] = useState(null); const [realTimeStats, setRealTimeStats] = useState(null); const [autoRefresh, setAutoRefresh] = useState(true); // Auto-login on mount (no password required) useEffect(() => { const autoLogin = async () => { try { const response = await fetch("/api/admin/login", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({}), }); if (response.ok) { setIsAuthenticated(true); await refreshAllData(); } } catch (err) { console.error("Auto-login failed:", err); } finally { setIsLoading(false); } }; autoLogin(); }, []); // Auto-refresh data every 10 seconds if enabled useEffect(() => { if (!isAuthenticated || !autoRefresh) return; const interval = setInterval(() => { refreshAllData(); }, 10000); // Refresh every 10 seconds return () => clearInterval(interval); }, [isAuthenticated, autoRefresh]); const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); setError(""); setIsLoading(true); try { const response = await fetch("/api/admin/login", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ password }), }); const data = await response.json(); if (!response.ok) { throw new Error(data.error || "Failed to login"); } setIsAuthenticated(true); await loadDatabaseData(); } catch (err: any) { setError(err.message || "Failed to login"); } finally { setIsLoading(false); } }; const loadDatabaseData = async () => { try { const response = await fetch("/api/admin/database"); if (!response.ok) { if (response.status === 403) { setIsAuthenticated(false); return; } throw new Error("Failed to load database data"); } const data = await response.json(); setDatabaseData(data); } catch (err: any) { setError(err.message || "Failed to load database data"); } }; const loadActiveUsers = async () => { try { const response = await fetch("/api/analytics/active-users"); if (response.ok) { const data = await response.json(); setActiveUsersData(data); } } catch (err: any) { console.error("Failed to load active users:", err); } }; const loadRealTimeStats = async () => { try { const response = await fetch("/api/analytics/real-time-stats"); if (response.ok) { const data = await response.json(); setRealTimeStats(data); } } catch (err: any) { console.error("Failed to load real-time stats:", err); } }; const refreshAllData = async () => { await Promise.all([ loadDatabaseData(), loadActiveUsers(), loadRealTimeStats(), ]); }; const deleteSession = async (id: string) => { if (!confirm("Are you sure you want to delete this session?")) { return; } try { const response = await fetch(`/api/admin/sessions/${id}`, { method: "DELETE", }); if (!response.ok) { throw new Error("Failed to delete session"); } await loadDatabaseData(); } catch (err: any) { setError(err.message || "Failed to delete session"); } }; const deleteReport = async (id: string) => { if (!confirm("Are you sure you want to delete this shared report?")) { return; } try { const response = await fetch(`/api/admin/reports/${id}`, { method: "DELETE", }); if (!response.ok) { throw new Error("Failed to delete report"); } await loadDatabaseData(); } catch (err: any) { setError(err.message || "Failed to delete report"); } }; const formatDate = (dateString: string) => { return new Date(dateString).toLocaleString(); }; // Show loading screen during auto-login if (!isAuthenticated && isLoading) { return (

Loading admin panel...

); } if (!isAuthenticated) { return (
{/* Decorative gradient blobs */}
{/* Header */}
{/* Main Content */}

Admin Access

Enter the admin password to access the database panel

Database Administration View and manage all database records
setPassword(e.target.value)} required disabled={isLoading} className="h-11 bg-background/50 border-border/50 focus:border-primary transition-all" />
{error && ( {error} )}
); } return (
{/* Header */}
{/* Main Content */}

Database Administration

View and manage all database records

{error && ( {error} )} {databaseData && (
Live Metrics Sessions ({databaseData.sessions.length}) Shared Reports ({databaseData.sharedReports.length})
setAutoRefresh(!autoRefresh)}> Auto-refresh {autoRefresh ? 'ON' : 'OFF'}
{/* Metrics Tab */} {/* Real-Time Active Users Section */} {activeUsersData && (

Live Activity Monitor

{activeUsersData.generating} Generating {activeUsersData.total} Active
{activeUsersData.users.length > 0 ? ( Session Status Current Query Last Activity {activeUsersData.users.map((user) => ( {user.sessionId.substring(0, 12)}... {user.status === 'generating' && } {user.status === 'error' && } {user.status} {user.currentQuery || '-'} {new Date(user.lastHeartbeat).toLocaleTimeString()} ))}
) : (

No active users at the moment

)}
)} {/* Real-Time Stats Overview */} {realTimeStats && (
Active Users Now
{realTimeStats.activeUsers.total}

{realTimeStats.activeUsers.generating} generating

Sessions Today
{realTimeStats.sessions.today}

of {realTimeStats.sessions.total} total

Cost Today
${realTimeStats.cost.today.toFixed(3)}

${realTimeStats.cost.total.toFixed(3)} total

10 ? 'red' : 'yellow'}-500/50 bg-${realTimeStats.errors.rate > 10 ? 'red' : 'yellow'}-500/5`}> 10 ? 'red' : 'yellow'}-500`} /> Error Rate
10 ? 'red' : 'yellow'}-500`}> {realTimeStats.errors.rate.toFixed(1)}%

{realTimeStats.errors.lastHour} errors last hour

)} {/* Historical Overview Cards */}

Cumulative Metrics

Total Cost
${databaseData.metrics.totalCost.toFixed(4)}

Across {databaseData.metrics.totalSessions} sessions

Total Tokens
{databaseData.metrics.totalTokens.toLocaleString()}

{databaseData.metrics.totalInputTokens.toLocaleString()} in / {databaseData.metrics.totalOutputTokens.toLocaleString()} out

Avg Cost/Session
${databaseData.metrics.averageCostPerSession.toFixed(4)}

Per conversation

Model
Opus 4.8

$5/$25 per M tokens

{/* Sessions Tab */} All Conversation Sessions Manage conversation history Session ID User ID Title Tokens Cost Updated At Actions {databaseData.sessions.map((session) => ( {session.sessionId.substring(0, 8)}... {session.userId ? `${session.userId.substring(0, 8)}...` : "Anonymous"} {session.title} {(session.inputTokens + session.outputTokens).toLocaleString()} ({session.inputTokens}↑/{session.outputTokens}↓) ${session.totalCost.toFixed(4)} {formatDate(session.updatedAt)} ))}
{/* Shared Reports Tab */} All Shared Reports Manage publicly shared reports Share ID Question Preview Created At Actions {databaseData.sharedReports.map((report) => ( {report.shareId} {report.question} {formatDate(report.createdAt)} ))}
)}
); }