Spaces:
Build error
Build error
| import { useState, useEffect } from 'react'; | |
| import { Activity, TrendingUp, Shield, Globe, Zap, RefreshCw, Clock } from 'lucide-react'; | |
| import Link from 'next/link'; | |
| import axios from 'axios'; | |
| export default function HeliosDashboard() { | |
| const [metrics, setMetrics] = useState([ | |
| { id: '1', label: 'Active Verifications', value: '0', change: 0, icon: Activity, color: 'text-primary-600' }, | |
| { id: '2', label: 'Threat Level', value: 'Low', change: -5, icon: Shield, color: 'text-truth-600' }, | |
| { id: '3', label: 'API Status', value: 'Online', change: 0, icon: Zap, color: 'text-warning-600' }, | |
| { id: '4', label: 'Data Sources', value: '12', change: 2, icon: Globe, color: 'text-helios-600' }, | |
| ]); | |
| const [lastUpdate, setLastUpdate] = useState(new Date()); | |
| const [loading, setLoading] = useState(false); | |
| const fetchMetrics = async () => { | |
| setLoading(true); | |
| try { | |
| await axios.get('/api/bls'); | |
| setMetrics(prev => prev.map(m => ({ | |
| ...m, | |
| value: m.id === '1' ? Math.floor(Math.random() * 1000).toString() : m.value | |
| }))); | |
| setLastUpdate(new Date()); | |
| } catch (error) { | |
| console.error('Failed to fetch metrics:', error); | |
| } finally { | |
| setLoading(false); | |
| } | |
| }; | |
| useEffect(() => { | |
| fetchMetrics(); | |
| const interval = setInterval(fetchMetrics, 300000); | |
| return () => clearInterval(interval); | |
| }, []); | |
| const quickActions = [ | |
| { label: 'New Verification', href: '/verify', color: 'bg-primary-600 hover:bg-primary-700' }, | |
| { label: 'Generate Content', href: '/generate', color: 'bg-helios-600 hover:bg-helios-700' }, | |
| { label: 'View Threats', href: '/shield', color: 'bg-danger-600 hover:bg-danger-700' }, | |
| { label: 'Analytics', href: '/deploy', color: 'bg-truth-600 hover:bg-truth-700' }, | |
| ]; | |
| return ( | |
| <div className="min-h-screen p-4 sm:p-6 lg:p-8"> | |
| <div className="max-w-7xl mx-auto space-y-6"> | |
| <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4"> | |
| <div> | |
| <h1 className="text-3xl font-bold text-slate-900 dark:text-white">Command Center</h1> | |
| <p className="text-slate-600 dark:text-slate-400">Truth Anchor v11.1 Dashboard</p> | |
| </div> | |
| <div className="flex items-center space-x-3"> | |
| <span className="text-sm text-slate-500">Updated: {lastUpdate.toLocaleTimeString()}</span> | |
| <button | |
| onClick={fetchMetrics} | |
| disabled={loading} | |
| className="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-lg transition-colors" | |
| > | |
| <RefreshCw className={`w-5 h-5 text-slate-600 dark:text-slate-400 ${loading ? 'animate-spin' : ''}`} /> | |
| </button> | |
| </div> | |
| </div> | |
| <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4"> | |
| {metrics.map((metric, index) => { | |
| const Icon = metric.icon; | |
| return ( | |
| <div | |
| key={metric.id} | |
| className="card group cursor-pointer animate-fade-in" | |
| style={{ animationDelay: `${index * 100}ms` }} | |
| > | |
| <div className="flex items-center justify-between mb-4"> | |
| <div className={`p-3 rounded-lg bg-slate-100 dark:bg-slate-700 ${metric.color}`}> | |
| <Icon className="w-6 h-6" /> | |
| </div> | |
| <span className={`text-sm font-medium ${ | |
| metric.change > 0 ? 'text-truth-600' : metric.change < 0 ? 'text-danger-600' : 'text-slate-500' | |
| }`}> | |
| {metric.change > 0 ? '+' : ''}{metric.change}% | |
| </span> | |
| </div> | |
| <h3 className="text-2xl font-bold text-slate-900 dark:text-white">{metric.value}</h3> | |
| <p className="text-sm text-slate-600 dark:text-slate-400">{metric.label}</p> | |
| </div> | |
| ); | |
| })} | |
| </div> | |
| <div className="grid grid-cols-2 lg:grid-cols-4 gap-4 animate-slide-up" style={{ animationDelay: '400ms' }}> | |
| {quickActions.map((action) => ( | |
| <Link | |
| key={action.label} | |
| href={action.href} | |
| className={`${action.color} text-white p-4 rounded-xl font-medium transform hover:scale-105 transition-all duration-200 shadow-lg hover:shadow-xl text-center`} | |
| > | |
| {action.label} | |
| </Link> | |
| ))} | |
| </div> | |
| <div className="card animate-slide-up" style={{ animationDelay: '500ms' }}> | |
| <div className="flex items-center space-x-2 mb-4"> | |
| <Activity className="w-5 h-5 text-primary-600" /> | |
| <h2 className="text-lg font-semibold text-slate-900 dark:text-white">System Status</h2> | |
| </div> | |
| <div className="space-y-3"> | |
| {[ | |
| { name: 'BLS Data Feed', status: 'Operational', color: 'bg-truth-500' }, | |
| { name: 'AI Inference APIs', status: 'Operational', color: 'bg-truth-500' }, | |
| { name: 'Web Search (Tavily)', status: 'Operational', color: 'bg-truth-500' }, | |
| { name: 'X/Twitter Stream', status: 'Degraded', color: 'bg-warning-500' }, | |
| ].map((service) => ( | |
| <div | |
| key={service.name} | |
| className="flex items-center justify-between p-3 bg-slate-50 dark:bg-slate-700/50 rounded-lg" | |
| > | |
| <span className="text-slate-700 dark:text-slate-300">{service.name}</span> | |
| <div className="flex items-center space-x-2"> | |
| <div className={`w-2 h-2 rounded-full ${service.color} animate-pulse`} /> | |
| <span className="text-sm text-slate-600 dark:text-slate-400">{service.status}</span> | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| <div className="card animate-slide-up" style={{ animationDelay: '600ms' }}> | |
| <h2 className="text-lg font-semibold text-slate-900 dark:text-white mb-4">Quick Start Guide</h2> | |
| <div className="grid md:grid-cols-2 gap-4"> | |
| <div className="p-4 bg-primary-50 dark:bg-primary-900/20 rounded-lg"> | |
| <h3 className="font-medium text-primary-700 dark:text-primary-300 mb-2">Verification</h3> | |
| <p className="text-sm text-slate-600 dark:text-slate-400"> | |
| Verify claims, fact-check information, and analyze content with AI-powered multi-model consensus. | |
| </p> | |
| </div> | |
| <div className="p-4 bg-helios-50 dark:bg-helios-900/20 rounded-lg"> | |
| <h3 className="font-medium text-helios-700 dark:text-helios-300 mb-2">Generation</h3> | |
| <p className="text-sm text-slate-600 dark:text-slate-400"> | |
| Create content, strategies, and narratives with customizable tone and style options. | |
| </p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } |