import { useState, useEffect, useRef } from 'react' import type { NextPage } from 'next' import Head from 'next/head' import AdminLayout from '../../../components/AdminLayout' import { ChartBarIcon, ServerStackIcon, CircleStackIcon as DatabaseIcon, CpuChipIcon, CircleStackIcon, GlobeAltIcon, ExclamationTriangleIcon, CheckCircleIcon, ClockIcon, ArrowPathIcon } from '@heroicons/react/24/outline' import { Line, Bar } from 'react-chartjs-2' interface RealtimeMetrics { timestamp: string cpu_usage: number memory_usage: number disk_usage: number active_connections: number api_requests_per_minute: number database_queries_per_minute: number response_time: number error_rate: number } interface SystemAlert { id: string type: 'warning' | 'error' | 'info' title: string message: string timestamp: string resolved: boolean } interface ActiveUser { id: string name: string email: string last_activity: string ip_address: string location: string } const RealtimeMonitoring: NextPage = () => { const [metrics, setMetrics] = useState([]) const [alerts, setAlerts] = useState([]) const [activeUsers, setActiveUsers] = useState([]) const [isConnected, setIsConnected] = useState(false) const [autoRefresh, setAutoRefresh] = useState(true) const intervalRef = useRef(null) useEffect(() => { if (autoRefresh) { fetchData() intervalRef.current = setInterval(fetchData, 5000) // Update every 5 seconds } else if (intervalRef.current) { clearInterval(intervalRef.current) } return () => { if (intervalRef.current) { clearInterval(intervalRef.current) } } }, [autoRefresh]) const fetchData = async () => { try { // Fetch real-time metrics const metricsResponse = await fetch('/api/admin/monitoring/realtime') if (metricsResponse.ok) { const newMetric = await metricsResponse.json() setMetrics(prev => { const updated = [...prev, newMetric].slice(-20) // Keep last 20 data points return updated }) setIsConnected(true) } // Fetch alerts const alertsResponse = await fetch('/api/admin/monitoring/alerts') if (alertsResponse.ok) { const alertsData = await alertsResponse.json() setAlerts(alertsData) } // Fetch active users const usersResponse = await fetch('/api/admin/monitoring/active-users') if (usersResponse.ok) { const usersData = await usersResponse.json() setActiveUsers(usersData) } } catch (error) { console.error('Failed to fetch monitoring data:', error) setIsConnected(false) } } const getLatestMetric = () => metrics[metrics.length - 1] || {} const getStatusColor = (value: number, thresholds: { warning: number, critical: number }) => { if (value >= thresholds.critical) return 'text-red-600 bg-red-100' if (value >= thresholds.warning) return 'text-yellow-600 bg-yellow-100' return 'text-green-600 bg-green-100' } // Chart configurations const cpuChartData = { labels: metrics.map((_, index) => `${index * 5}s ago`).reverse(), datasets: [ { label: 'CPU Usage %', data: metrics.map(m => m.cpu_usage).reverse(), borderColor: 'rgb(239, 68, 68)', backgroundColor: 'rgba(239, 68, 68, 0.1)', tension: 0.4, fill: true, }, ], } const memoryChartData = { labels: metrics.map((_, index) => `${index * 5}s ago`).reverse(), datasets: [ { label: 'Memory Usage %', data: metrics.map(m => m.memory_usage).reverse(), borderColor: 'rgb(59, 130, 246)', backgroundColor: 'rgba(59, 130, 246, 0.1)', tension: 0.4, fill: true, }, ], } const apiRequestsData = { labels: metrics.map((_, index) => `${index * 5}s`).reverse(), datasets: [ { label: 'API Requests/min', data: metrics.map(m => m.api_requests_per_minute).reverse(), backgroundColor: 'rgba(34, 197, 94, 0.8)', borderColor: 'rgb(34, 197, 94)', }, ], } const latest = getLatestMetric() return ( Real-time Monitoring - Hliadka.sk Admin {/* Connection Status */}
{isConnected ? 'Pripojené' : 'Odpojené'}
Posledná aktualizácia: {new Date().toLocaleTimeString('sk-SK')}
{/* System Status Cards */}

CPU Usage

{latest.cpu_usage || 0}%

= 90 ? 'bg-red-500' : (latest.cpu_usage || 0) >= 70 ? 'bg-yellow-500' : 'bg-green-500' }`} style={{ width: `${latest.cpu_usage || 0}%` }} />

Memory Usage

{latest.memory_usage || 0}%

= 95 ? 'bg-red-500' : (latest.memory_usage || 0) >= 80 ? 'bg-yellow-500' : 'bg-green-500' }`} style={{ width: `${latest.memory_usage || 0}%` }} />

Active Connections

{latest.active_connections || 0}

Databáza + API

Response Time

{latest.response_time || 0}ms

Priemerný API response

{/* Real-time Charts */}

CPU Usage - Posledných 100s

`${value}%` } }, x: { display: false } }, elements: { point: { radius: 0 } } }} height={200} />

Memory Usage - Posledných 100s

`${value}%` } }, x: { display: false } }, elements: { point: { radius: 0 } } }} height={200} />
{/* API Activity */}

API Activity - Requests per Minute

{/* Alerts and Active Users */}
{/* System Alerts */}

Systémové upozornenia

{alerts.length > 0 ? alerts.map((alert) => (
{alert.type === 'error' ? ( ) : alert.type === 'warning' ? ( ) : ( )} {alert.title}
{new Date(alert.timestamp).toLocaleTimeString('sk-SK')}

{alert.message}

)) : (

Žiadne aktívne upozornenia

)}
{/* Active Users */}

Aktívni používatelia

{activeUsers.map((user) => (
{user.name}
{user.email}
{user.location}
{new Date(user.last_activity).toLocaleTimeString('sk-SK')}
{user.ip_address}
))} {activeUsers.length === 0 && (

Žiadni aktívni používatelia

)}
) } export default RealtimeMonitoring