/** * Admin Dashboard Component * Comprehensive monitoring and management interface for Medical AI Platform * * Features: * - Real-time system health monitoring * - Pipeline statistics and performance metrics * - Model performance tracking * - Cache management * - Alert management * - Review queue management * - Compliance overview */ import React, { useState, useEffect } from 'react'; import { Activity, AlertCircle, BarChart3, Database, GitBranch, Shield, Clock, TrendingUp } from 'lucide-react'; interface DashboardData { status: string; timestamp: string; system: { uptime_seconds: number; uptime_human: string; error_rate: number; total_requests: number; error_threshold: number; status: string; }; pipeline: { total_jobs_processed: number; completed_jobs: number; failed_jobs: number; processing_jobs: number; success_rate: number; }; models: { total_registered: number; performance: Record; }; synthesis: { total_syntheses: number; avg_confidence: number; requiring_review: number; avg_processing_time_ms: number; }; cache: { total_entries: number; hits: number; misses: number; hit_rate: number; evictions: number; memory_usage_mb: number; avg_retrieval_time_ms: number; cache_efficiency: number; }; alerts: { active_count: number; critical_count: number; recent: Alert[]; }; compliance: { hipaa_compliant: boolean; gdpr_compliant: boolean; audit_logging_active: boolean; phi_removal_active: boolean; encryption_enabled: boolean; }; components: Record; } interface ModelPerformance { version: string; total_inferences: number; avg_latency_ms: number; error_rate: number; last_used: string; } interface Alert { alert_id: string; level: string; message: string; category: string; timestamp: string; resolved: boolean; details: Record; } const AdminDashboard: React.FC = () => { const [dashboardData, setDashboardData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [activeTab, setActiveTab] = useState<'overview' | 'models' | 'cache' | 'alerts'>('overview'); const [autoRefresh, setAutoRefresh] = useState(true); // Fetch dashboard data const fetchDashboard = async () => { try { const response = await fetch('/health/dashboard'); if (!response.ok) { throw new Error('Failed to fetch dashboard data'); } const data = await response.json(); setDashboardData(data); setError(null); } catch (err) { setError(err instanceof Error ? err.message : 'Unknown error'); } finally { setLoading(false); } }; // Initial load and auto-refresh useEffect(() => { fetchDashboard(); if (autoRefresh) { const interval = setInterval(fetchDashboard, 10000); // Refresh every 10 seconds return () => clearInterval(interval); } }, [autoRefresh]); // Status badge component const StatusBadge: React.FC<{ status: string }> = ({ status }) => { const colors = { operational: 'bg-green-100 text-green-800', healthy: 'bg-green-100 text-green-800', degraded: 'bg-yellow-100 text-yellow-800', critical: 'bg-red-100 text-red-800', ready: 'bg-blue-100 text-blue-800', active: 'bg-blue-100 text-blue-800' }; const color = colors[status.toLowerCase() as keyof typeof colors] || 'bg-gray-100 text-gray-800'; return ( {status.toUpperCase()} ); }; // Metric card component const MetricCard: React.FC<{ title: string; value: string | number; subtitle?: string; icon: React.ReactNode; status?: 'good' | 'warning' | 'critical'; }> = ({ title, value, subtitle, icon, status }) => { const statusColors = { good: 'border-green-200 bg-green-50', warning: 'border-yellow-200 bg-yellow-50', critical: 'border-red-200 bg-red-50' }; const borderColor = status ? statusColors[status] : 'border-gray-200 bg-white'; return (
{title}
{icon}
{value}
{subtitle &&
{subtitle}
}
); }; // Resolve alert const resolveAlert = async (alertId: string) => { try { const response = await fetch(`/admin/alerts/${alertId}/resolve`, { method: 'POST' }); if (response.ok) { fetchDashboard(); // Refresh data } } catch (err) { console.error('Failed to resolve alert:', err); } }; // Clear cache const clearCache = async () => { if (!confirm('Are you sure you want to clear all cache entries? This may temporarily impact performance.')) { return; } try { const response = await fetch('/admin/cache/clear', { method: 'POST' }); if (response.ok) { alert('Cache cleared successfully'); fetchDashboard(); } } catch (err) { alert('Failed to clear cache'); } }; if (loading) { return (

Loading dashboard...

); } if (error) { return (

Error: {error}

); } if (!dashboardData) { return null; } return (
{/* Header */}

Medical AI Platform - Admin Dashboard

Real-time monitoring and system management

{/* Tabs */}
{['overview', 'models', 'cache', 'alerts'].map((tab) => ( ))}
{/* Content */}
{/* Overview Tab */} {activeTab === 'overview' && (
{/* System Status Grid */}

System Status

} status="good" /> } status={dashboardData.system.error_rate > dashboardData.system.error_threshold ? 'critical' : 'good'} /> } /> } status={dashboardData.alerts.critical_count > 0 ? 'critical' : dashboardData.alerts.active_count > 0 ? 'warning' : 'good'} />
{/* Pipeline Statistics */}

Pipeline Statistics

} /> } status="good" /> } status={dashboardData.pipeline.failed_jobs > 0 ? 'warning' : 'good'} /> } status={dashboardData.pipeline.success_rate > 0.95 ? 'good' : dashboardData.pipeline.success_rate > 0.85 ? 'warning' : 'critical'} />
{/* Cache & Synthesis */}
{/* Cache Statistics */}

Cache Performance

Hit Rate {(dashboardData.cache.hit_rate * 100).toFixed(1)}%
Entries {dashboardData.cache.total_entries.toLocaleString()}
Memory Usage {dashboardData.cache.memory_usage_mb.toFixed(1)} MB
Avg Retrieval {dashboardData.cache.avg_retrieval_time_ms.toFixed(2)} ms
{/* Synthesis Statistics */}

Clinical Synthesis

Total Syntheses {dashboardData.synthesis.total_syntheses.toLocaleString()}
Avg Confidence {(dashboardData.synthesis.avg_confidence * 100).toFixed(1)}%
Requiring Review {dashboardData.synthesis.requiring_review.toLocaleString()}
Avg Processing {dashboardData.synthesis.avg_processing_time_ms.toFixed(0)} ms
{/* Compliance Status */}

Compliance Status

{Object.entries(dashboardData.compliance).map(([key, value]) => (
{value ? '✓' : '✗'}
{key.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}
))}
)} {/* Models Tab */} {activeTab === 'models' && (

Model Performance

{Object.entries(dashboardData.models.performance).map(([modelId, perf]) => ( ))}
Model ID Version Inferences Avg Latency Error Rate Last Used
{modelId} {perf.version} {perf.total_inferences.toLocaleString()} {perf.avg_latency_ms.toFixed(1)} ms {(perf.error_rate * 100).toFixed(2)}% {perf.last_used}
)} {/* Cache Tab */} {activeTab === 'cache' && (

Cache Management

} /> } status={dashboardData.cache.hit_rate > 0.7 ? 'good' : dashboardData.cache.hit_rate > 0.4 ? 'warning' : 'critical'} /> } />

Cache Performance Analysis

{dashboardData.cache.hit_rate < 0.5 && (

⚠ Low cache hit rate ({(dashboardData.cache.hit_rate * 100).toFixed(1)}%). Consider increasing cache size or TTL.

)} {dashboardData.cache.hit_rate >= 0.8 && (

✓ Excellent cache hit rate ({(dashboardData.cache.hit_rate * 100).toFixed(1)}%). Cache performing optimally.

)}

Cache efficiency: {dashboardData.cache.cache_efficiency.toFixed(1)}%

)} {/* Alerts Tab */} {activeTab === 'alerts' && (

Active Alerts ({dashboardData.alerts.active_count})

{dashboardData.alerts.recent.length === 0 ? (

No active alerts

) : (
{dashboardData.alerts.recent.map((alert) => (
{alert.level.toUpperCase()} {alert.category} {new Date(alert.timestamp).toLocaleString()}

{alert.message}

{Object.keys(alert.details).length > 0 && (
                            {JSON.stringify(alert.details, null, 2)}
                          
)}
{!alert.resolved && ( )}
))}
)}
)}
); }; export default AdminDashboard;