'use client'
import { useState, useEffect } from 'react'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Progress } from '@/components/ui/progress'
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import {
BarChart3,
TrendingUp,
Activity,
Cpu,
HardDrive,
Wifi,
AlertTriangle,
CheckCircle,
Zap,
Database,
Globe,
Server,
Clock
} from 'lucide-react'
// Mock monitoring data
const mockSystemMetrics = {
cpu: {
usage: 45,
cores: 8,
temperature: 58,
frequency: 3.2
},
memory: {
used: 4.2,
total: 16,
percentage: 26
},
disk: {
used: 120,
total: 512,
percentage: 23
},
network: {
upload: 2.1,
download: 15.8,
latency: 23,
connections: 12
}
}
const mockPerformanceMetrics = {
responseTime: [45, 42, 48, 41, 44, 46, 43, 40, 47, 42],
throughput: [8500, 8650, 8400, 8750, 8600, 8450, 8700, 8550, 8800, 8650],
errorRate: [0.01, 0.008, 0.012, 0.009, 0.011, 0.007, 0.013, 0.010, 0.008, 0.009],
cpuUsage: [45, 48, 42, 46, 44, 47, 43, 45, 41, 46],
memoryUsage: [26, 28, 24, 27, 25, 29, 26, 27, 23, 25]
}
const mockAlerts = [
{
id: 'alert_001',
severity: 'warning',
title: 'High CPU Usage',
message: 'CPU usage has exceeded 80% for the last 5 minutes',
timestamp: '2025-12-17T10:30:00Z',
resolved: false
},
{
id: 'alert_002',
severity: 'info',
title: 'Scheduled Maintenance',
message: 'System maintenance scheduled for tonight at 2:00 AM',
timestamp: '2025-12-17T08:00:00Z',
resolved: false
},
{
id: 'alert_003',
severity: 'success',
title: 'Backup Completed',
message: 'Daily backup completed successfully',
timestamp: '2025-12-17T06:00:00Z',
resolved: true
}
]
const mockServiceStatus = [
{
name: 'Frontend (Next.js)',
status: 'healthy',
uptime: '99.9%',
responseTime: '45ms',
version: '16.0.0'
},
{
name: 'Backend (FastAPI)',
status: 'healthy',
uptime: '99.8%',
responseTime: '23ms',
version: '1.0.0'
},
{
name: 'Database (PostgreSQL)',
status: 'healthy',
uptime: '99.9%',
responseTime: '12ms',
version: '15.4'
},
{
name: 'ROS 2 Bridge',
status: 'healthy',
uptime: '99.7%',
responseTime: '8ms',
version: 'Rolling'
},
{
name: 'WebRTC Server',
status: 'warning',
uptime: '98.5%',
responseTime: '67ms',
version: '1.0.0'
}
]
interface MetricCardProps {
title: string;
value: string | number;
unit: string;
icon: React.ComponentType<{ className?: string }>;
trend?: number;
color?: string;
}
const MetricCard: React.FC<MetricCardProps> = ({ title, value, unit, icon: Icon, trend, color = 'blue' }) => (
<Card>
<CardContent className="p-6">
<div className="flex items-center justify-between">
<div>
<div className="text-2xl font-bold">{value}{unit}</div>
<div className="text-sm text-muted-foreground">{title}</div>
</div>
<div className={`p-3 rounded-full bg-${color}-100`}>
<Icon className={`h-6 w-6 text-${color}-600`} />
</div>
</div>
{trend && (
<div className="flex items-center mt-4 text-sm">
<TrendingUp className={`h-4 w-4 mr-1 ${
trend > 0 ? 'text-green-500' : 'text-red-500'
}`} />
<span className={trend > 0 ? 'text-green-500' : 'text-red-500'}>
{trend > 0 ? '+' : ''}{trend.toFixed(1)}% from last hour
</span>
</div>
)}
</CardContent>
</Card>
)
interface SimpleChartProps {
data: number[];
label: string;
color?: string;
height?: number;
}
const SimpleChart: React.FC<SimpleChartProps> = ({ data, label, color = 'blue', height = 80 }) => {
const maxValue = Math.max(...data)
const minValue = Math.min(...data)
const range = maxValue - minValue || 1
return (
<div className="space-y-2">
<div className="flex items-center justify-between text-sm">
<span>{label}</span>
<span className="font-medium">
{data[data.length - 1]?.toFixed(1)}
</span>
</div>
<div
className="relative bg-muted/50 rounded"
style={{ height: `${height}px` }}
>
<svg className="w-full h-full" viewBox={`0 0 ${data.length} ${height}`}>
<polyline
fill="none"
stroke={`var(--${color}-500)`}
strokeWidth="2"
points={
data.map((value, index) => {
const x = (index / (data.length - 1)) * data.length
const y = height - ((value - minValue) / range) * (height - 10) - 5
return `${x},${y}`
}).join(' ')
}
/>
</svg>
</div>
</div>
)
}
export default function MonitoringPage() {
const [systemMetrics, setSystemMetrics] = useState(mockSystemMetrics)
const [performanceMetrics, setPerformanceMetrics] = useState(mockPerformanceMetrics)
const [alerts, setAlerts] = useState(mockAlerts)
const [serviceStatus, setServiceStatus] = useState(mockServiceStatus)
// Mock real-time updates
useEffect(() => {
const interval = setInterval(() => {
// Update system metrics
setSystemMetrics(prev => ({
...prev,
cpu: {
...prev.cpu,
usage: Math.max(0, Math.min(100, prev.cpu.usage + (Math.random() - 0.5) * 10))
},
memory: {
...prev.memory,
used: Math.max(0, Math.min(prev.memory.total, prev.memory.used + (Math.random() - 0.5) * 0.5)),
percentage: 0 // Will be calculated
},
network: {
...prev.network,
upload: Math.max(0, prev.network.upload + (Math.random() - 0.5) * 0.5),
download: Math.max(0, prev.network.download + (Math.random() - 0.5) * 2),
latency: Math.max(10, prev.network.latency + (Math.random() - 0.5) * 5)
}
}))
// Calculate memory percentage
setSystemMetrics(prev => ({
...prev,
memory: {
...prev.memory,
percentage: (prev.memory.used / prev.memory.total) * 100
}
}))
// Update performance metrics
setPerformanceMetrics(prev => ({
responseTime: [...prev.responseTime.slice(1), Math.max(20, 60 + (Math.random() - 0.5) * 10)],
throughput: [...prev.throughput.slice(1), Math.max(8000, 8500 + (Math.random() - 0.5) * 500)],
errorRate: [...prev.errorRate.slice(1), Math.max(0, 0.01 + (Math.random() - 0.5) * 0.005)],
cpuUsage: [...prev.cpuUsage.slice(1), Math.max(0, Math.min(100, prev.cpuUsage[prev.cpuUsage.length - 1] + (Math.random() - 0.5) * 5))],
memoryUsage: [...prev.memoryUsage.slice(1), Math.max(0, Math.min(100, prev.memoryUsage[prev.memoryUsage.length - 1] + (Math.random() - 0.5) * 2))]
}))
}, 2000) // Update every 2 seconds
return () => clearInterval(interval)
}, [])
return (
<div className="min-h-screen bg-background">
<div className="container mx-auto px-4 py-8">
{/* Header */}
<div className="mb-8">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
<BarChart3 className="h-8 w-8 text-primary" />
<div>
<h1 className="text-3xl font-bold">System Monitoring</h1>
<p className="text-muted-foreground">
Real-time performance metrics and system health monitoring
</p>
</div>
</div>
<div className="flex items-center space-x-4">
<Badge variant="outline" className="flex items-center space-x-2">
<Activity className="h-3 w-3" />
<span>Live Monitoring</span>
</Badge>
<Button variant="outline" size="sm">
<Database className="mr-2 h-4 w-4" />
Export Metrics
</Button>
</div>
</div>
</div>
{/* Key Metrics Overview */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
<MetricCard
title="Response Time"
value={performanceMetrics.responseTime[performanceMetrics.responseTime.length - 1].toFixed(0)}
unit="ms"
icon={Zap}
trend={-2.1}
color="green"
/>
<MetricCard
title="Throughput"
value={(performanceMetrics.throughput[performanceMetrics.throughput.length - 1] / 1000).toFixed(1)}
unit="k req/s"
icon={TrendingUp}
trend={1.8}
color="blue"
/>
<MetricCard
title="Error Rate"
value={(performanceMetrics.errorRate[performanceMetrics.errorRate.length - 1] * 100).toFixed(2)}
unit="%"
icon={AlertTriangle}
trend={-0.5}
color="red"
/>
<MetricCard
title="Active Connections"
value={systemMetrics.network.connections}
unit=""
icon={Globe}
trend={0.8}
color="purple"
/>
</div>
{/* Alerts Section */}
{alerts.filter(a => !a.resolved).length > 0 && (
<div className="mb-8">
<h2 className="text-xl font-bold mb-4">Active Alerts</h2>
<div className="space-y-4">
{alerts.filter(a => !a.resolved).map((alert) => (
<Alert key={alert.id} className={
alert.severity === 'warning' ? 'border-yellow-500' :
alert.severity === 'error' ? 'border-red-500' : 'border-blue-500'
}>
<AlertTriangle className="h-4 w-4" />
<AlertTitle>{alert.title}</AlertTitle>
<AlertDescription>
{alert.message}
<div className="text-xs text-muted-foreground mt-1">
{new Date(alert.timestamp).toLocaleString()}
</div>
</AlertDescription>
</Alert>
))}
</div>
</div>
)}
{/* Main Monitoring Interface */}
<Tabs defaultValue="performance" className="space-y-6">
<TabsList className="grid w-full grid-cols-4">
<TabsTrigger value="performance">Performance</TabsTrigger>
<TabsTrigger value="system">System</TabsTrigger>
<TabsTrigger value="services">Services</TabsTrigger>
<TabsTrigger value="network">Network</TabsTrigger>
</TabsList>
<TabsContent value="performance" className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<Card>
<CardHeader>
<CardTitle>Response Time</CardTitle>
<CardDescription>Average API response time over time</CardDescription>
</CardHeader>
<CardContent>
<SimpleChart
data={performanceMetrics.responseTime}
label="Response Time (ms)"
color="green"
height={120}
/>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Throughput</CardTitle>
<CardDescription>Requests per second</CardDescription>
</CardHeader>
<CardContent>
<SimpleChart
data={performanceMetrics.throughput.map(v => v / 1000)}
label="Throughput (k req/s)"
color="blue"
height={120}
/>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Error Rate</CardTitle>
<CardDescription>Percentage of failed requests</CardDescription>
</CardHeader>
<CardContent>
<SimpleChart
data={performanceMetrics.errorRate.map(v => v * 100)}
label="Error Rate (%)"
color="red"
height={120}
/>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Resource Usage</CardTitle>
<CardDescription>CPU and memory utilization</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<SimpleChart
data={performanceMetrics.cpuUsage}
label="CPU Usage (%)"
color="orange"
height={60}
/>
<SimpleChart
data={performanceMetrics.memoryUsage}
label="Memory Usage (%)"
color="purple"
height={60}
/>
</div>
</CardContent>
</Card>
</div>
</TabsContent>
<TabsContent value="system" className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
<Card>
<CardHeader className="pb-3">
<CardTitle className="flex items-center space-x-2 text-lg">
<Cpu className="h-5 w-5 text-blue-500" />
<span>CPU</span>
</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-3">
<div>
<div className="flex justify-between text-sm mb-1">
<span>Usage</span>
<span>{systemMetrics.cpu.usage.toFixed(1)}%</span>
</div>
<Progress value={systemMetrics.cpu.usage} className="h-2" />
</div>
<div className="grid grid-cols-2 gap-4 text-sm">
<div>
<div className="text-muted-foreground">Cores</div>
<div className="font-medium">{systemMetrics.cpu.cores}</div>
</div>
<div>
<div className="text-muted-foreground">Temp</div>
<div className="font-medium">{systemMetrics.cpu.temperature}°C</div>
</div>
</div>
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-3">
<CardTitle className="flex items-center space-x-2 text-lg">
<Database className="h-5 w-5 text-green-500" />
<span>Memory</span>
</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-3">
<div>
<div className="flex justify-between text-sm mb-1">
<span>Usage</span>
<span>{systemMetrics.memory.percentage.toFixed(1)}%</span>
</div>
<Progress value={systemMetrics.memory.percentage} className="h-2" />
</div>
<div className="grid grid-cols-2 gap-4 text-sm">
<div>
<div className="text-muted-foreground">Used</div>
<div className="font-medium">{systemMetrics.memory.used.toFixed(1)}GB</div>
</div>
<div>
<div className="text-muted-foreground">Total</div>
<div className="font-medium">{systemMetrics.memory.total}GB</div>
</div>
</div>
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-3">
<CardTitle className="flex items-center space-x-2 text-lg">
<HardDrive className="h-5 w-5 text-purple-500" />
<span>Storage</span>
</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-3">
<div>
<div className="flex justify-between text-sm mb-1">
<span>Usage</span>
<span>{systemMetrics.disk.percentage.toFixed(1)}%</span>
</div>
<Progress value={systemMetrics.disk.percentage} className="h-2" />
</div>
<div className="grid grid-cols-2 gap-4 text-sm">
<div>
<div className="text-muted-foreground">Used</div>
<div className="font-medium">{systemMetrics.disk.used}GB</div>
</div>
<div>
<div className="text-muted-foreground">Total</div>
<div className="font-medium">{systemMetrics.disk.total}GB</div>
</div>
</div>
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-3">
<CardTitle className="flex items-center space-x-2 text-lg">
<Wifi className="h-5 w-5 text-cyan-500" />
<span>Network</span>
</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-3">
<div className="grid grid-cols-2 gap-4 text-sm">
<div>
<div className="text-muted-foreground">Upload</div>
<div className="font-medium">{systemMetrics.network.upload.toFixed(1)} MB/s</div>
</div>
<div>
<div className="text-muted-foreground">Download</div>
<div className="font-medium">{systemMetrics.network.download.toFixed(1)} MB/s</div>
</div>
</div>
<div className="grid grid-cols-2 gap-4 text-sm">
<div>
<div className="text-muted-foreground">Latency</div>
<div className="font-medium">{systemMetrics.network.latency}ms</div>
</div>
<div>
<div className="text-muted-foreground">Connections</div>
<div className="font-medium">{systemMetrics.network.connections}</div>
</div>
</div>
</div>
</CardContent>
</Card>
</div>
</TabsContent>
<TabsContent value="services" className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{serviceStatus.map((service) => (
<Card key={service.name}>
<CardHeader>
<CardTitle className="flex items-center justify-between">
<span className="text-lg">{service.name}</span>
<Badge variant={
service.status === 'healthy' ? 'default' :
service.status === 'warning' ? 'secondary' : 'destructive'
}>
{service.status}
</Badge>
</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-3">
<div className="flex justify-between text-sm">
<span>Uptime</span>
<span className="font-medium">{service.uptime}</span>
</div>
<div className="flex justify-between text-sm">
<span>Response Time</span>
<span className="font-medium">{service.responseTime}</span>
</div>
<div className="flex justify-between text-sm">
<span>Version</span>
<span className="font-medium">{service.version}</span>
</div>
</div>
</CardContent>
</Card>
))}
</div>
</TabsContent>
<TabsContent value="network" className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<Card>
<CardHeader>
<CardTitle>Network Traffic</CardTitle>
<CardDescription>Real-time network throughput monitoring</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<div className="text-center p-4 bg-muted/50 rounded-lg">
<div className="text-2xl font-bold text-green-500 mb-1">
{systemMetrics.network.download.toFixed(1)}
</div>
<div className="text-sm text-muted-foreground">Download (MB/s)</div>
</div>
<div className="text-center p-4 bg-muted/50 rounded-lg">
<div className="text-2xl font-bold text-blue-500 mb-1">
{systemMetrics.network.upload.toFixed(1)}
</div>
<div className="text-sm text-muted-foreground">Upload (MB/s)</div>
</div>
</div>
<div className="text-center p-4 bg-muted/50 rounded-lg">
<div className="text-2xl font-bold text-purple-500 mb-1">
{systemMetrics.network.latency}
</div>
<div className="text-sm text-muted-foreground">Network Latency (ms)</div>
</div>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Connection Health</CardTitle>
<CardDescription>Active connections and health status</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="text-center p-6 bg-muted/50 rounded-lg">
<div className="text-3xl font-bold text-primary mb-2">
{systemMetrics.network.connections}
</div>
<div className="text-sm text-muted-foreground">Active Connections</div>
</div>
<div className="space-y-2">
<div className="flex justify-between text-sm">
<span>WebRTC Connections</span>
<Badge className="bg-green-500">8 active</Badge>
</div>
<div className="flex justify-between text-sm">
<span>ROS 2 Topics</span>
<Badge className="bg-green-500">15 active</Badge>
</div>
<div className="flex justify-between text-sm">
<span>Database Connections</span>
<Badge className="bg-green-500">5 active</Badge>
</div>
</div>
</div>
</CardContent>
</Card>
</div>
<Card>
<CardHeader>
<CardTitle>Network Topology</CardTitle>
<CardDescription>System connectivity and data flow visualization</CardDescription>
</CardHeader>
<CardContent>
<div className="bg-muted/50 rounded-lg p-6 text-center">
<div className="text-muted-foreground mb-4">
Network topology visualization would be displayed here
</div>
<div className="grid grid-cols-3 gap-4 text-sm">
<div className="bg-background p-3 rounded border text-center">
<Server className="h-6 w-6 mx-auto mb-2 text-primary" />
Frontend
</div>
<div className="bg-background p-3 rounded border text-center">
<Database className="h-6 w-6 mx-auto mb-2 text-primary" />
Backend
</div>
<div className="bg-background p-3 rounded border text-center">
<Globe className="h-6 w-6 mx-auto mb-2 text-primary" />
Robotics
</div>
</div>
</div>
</CardContent>
</Card>
</TabsContent>
</Tabs>
</div>
</div>
)
}