import { useParams, Link } from 'react-router'; import { useQuery } from '@tanstack/react-query'; import { ArrowLeft, Network, Wifi, WifiOff, Cpu, MemoryStick, HardDrive, Server, Activity, } from 'lucide-react'; import { api } from '@/lib/api'; import { formatBytes } from '@/lib/utils'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Progress } from '@/components/ui/progress'; interface NodeDetail { id: string; name: string; fqdn: string; daemonPort: number; grpcPort: number; memoryTotal: number; diskTotal: number; isOnline: boolean; daemonVersion: string | null; createdAt: string; } interface NodeStats { cpuPercent: number; memoryUsed: number; memoryTotal: number; diskUsed: number; diskTotal: number; activeServers: number; totalServers: number; uptime: number; } interface ServerSummary { id: string; name: string; status: string; memoryLimit: number; cpuLimit: number; gameName: string; } export function NodeDetailPage() { const { orgId, nodeId } = useParams(); const { data: node } = useQuery({ queryKey: ['node', orgId, nodeId], queryFn: () => api.get(`/organizations/${orgId}/nodes/${nodeId}`), }); const { data: stats } = useQuery({ queryKey: ['node-stats', orgId, nodeId], queryFn: () => api.get(`/organizations/${orgId}/nodes/${nodeId}/stats`), refetchInterval: 10_000, }); const { data: serversData } = useQuery({ queryKey: ['node-servers', orgId, nodeId], queryFn: () => api.get<{ data: ServerSummary[] }>( `/organizations/${orgId}/nodes/${nodeId}/servers`, ), }); const servers = serversData?.data ?? []; if (!node) { return (
); } const memPercent = stats ? Math.round((stats.memoryUsed / stats.memoryTotal) * 100) : 0; const diskPercent = stats ? Math.round((stats.diskUsed / stats.diskTotal) * 100) : 0; return (

{node.name}

{node.fqdn}:{node.daemonPort}

{node.isOnline ? ( <> Online ) : ( <> Offline )}
{/* Stats Cards */}
CPU Usage
{stats ? `${stats.cpuPercent.toFixed(1)}%` : '—'}
Memory
{stats ? `${formatBytes(stats.memoryUsed)} / ${formatBytes(stats.memoryTotal)}` : '—'}
Disk
{stats ? `${formatBytes(stats.diskUsed)} / ${formatBytes(stats.diskTotal)}` : '—'}
Servers
{stats ? `${stats.activeServers} / ${stats.totalServers}` : servers.length.toString()}

{stats ? 'active / total' : 'total servers'}

{/* Node Info */}
Node Information {node.daemonVersion && ( )} Servers on this Node {servers.length === 0 ? (

No servers on this node

) : (
{servers.map((srv) => (

{srv.name}

{srv.gameName}

{srv.status} {formatBytes(srv.memoryLimit)} RAM
))}
)}
); } function InfoRow({ label, value }: { label: string; value: string }) { return (
{label} {value}
); }