import { useState, useEffect } from 'react' import { AreaChart, Area, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts' import { getMetricsHistory } from '../api' import { useUser } from '../context/UserContext' const GRAFANA_URL = 'https://grafana.dimension47.de' export default function MetricsChart({ serverId, serverName, expanded = false }) { const { token } = useUser() const [data, setData] = useState(null) const [loading, setLoading] = useState(true) const [range, setRange] = useState('1h') useEffect(() => { const fetchData = async () => { try { const metrics = await getMetricsHistory(token, serverId, range) setData(metrics) } catch (err) { console.error('Failed to fetch metrics:', err) } finally { setLoading(false) } } fetchData() const interval = setInterval(fetchData, 60000) return () => clearInterval(interval) }, [token, serverId, range]) const formatTime = (timestamp) => { const date = new Date(timestamp) return date.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }) } const formatBytes = (bytes) => { if (bytes < 1024) return bytes.toFixed(0) + ' B/s' if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB/s' return (bytes / 1024 / 1024).toFixed(1) + ' MB/s' } if (loading) { return (
LOADING_METRICS...
) } if (!data || data.cpu.length === 0) { return (
NO_DATA_AVAILABLE
) } const combinedData = data.cpu.map((point, i) => ({ timestamp: point.timestamp, cpu: point.value, memory: data.memory[i]?.value || 0, networkRx: data.networkRx[i]?.value || 0, networkTx: data.networkTx[i]?.value || 0 })) const CustomTooltip = ({ active, payload, label }) => { if (active && payload && payload.length) { return (
{formatTime(label)}
{payload.map((entry, i) => (
{entry.name}: {entry.name.includes('Network') ? formatBytes(entry.value) : entry.value.toFixed(1) + '%'}
))}
) } return null } const ChartCard = ({ title, dataKey, color, domain, formatter }) => (
{title} {formatter ? formatter(combinedData[combinedData.length - 1]?.[dataKey] || 0) : (combinedData[combinedData.length - 1]?.[dataKey] || 0).toFixed(1) + '%' }
{expanded && ( <> formatBytes(v).split(' ')[0] : (v) => v.toFixed(0)} /> } /> )}
) return (
{/* Header */}
// METRICS_HISTORY
📊 GRAFANA
{/* Charts */} {expanded ? (
) : (
)}
) }