'use client' import { useState, useCallback } from 'react' import { useParams, useRouter } from 'next/navigation' import Link from 'next/link' import { ArrowLeft, Server, Power, RefreshCw, AlertTriangle, Cpu, HardDrive, Network, MemoryStick, Activity, Loader2, Box, Unlink, Settings } from 'lucide-react' import { useEnterpriseClient, useClientServer, useServerStatsHistory, useCollectServerStats, useServerAction, useRemoveServerFromClient } from '@/hooks/use-enterprise-clients' import { RangeSelector, StatsCard, CpuUsageChart, MemoryUsageChart, DiskIOChart, NetworkChart } from '@/components/admin/enterprise-stats-charts' import { LiveStatsPanel } from '@/components/admin/live-stats-panel' import { EnterpriseContainerList } from '@/components/admin/enterprise-container-list' import type { StatsRange } from '@/lib/api/admin' import type { StatsDataPoint } from '@/lib/services/stats-collection-service' export default function ServerDetailPage() { const params = useParams() const router = useRouter() const clientId = params.id as string const serverId = params.serverId as string const [range, setRange] = useState('24h') const [actionLoading, setActionLoading] = useState(null) const { data: client, isLoading: clientLoading } = useEnterpriseClient(clientId) const { data: server, isLoading: serverLoading, refetch: refetchServer } = useClientServer(clientId, serverId) const { data: statsData, isLoading: statsLoading } = useServerStatsHistory(clientId, serverId, range) const collectStats = useCollectServerStats() const serverAction = useServerAction() const removeServer = useRemoveServerFromClient() // Stable callback for refreshing stats (used by LiveStatsPanel) const handleRefreshStats = useCallback(() => { collectStats.mutate({ clientId, serverId }) }, [collectStats, clientId, serverId]) const isLoading = clientLoading || serverLoading if (isLoading) { return (
) } if (!client || !server) { return (

Server not found

The server you're looking for doesn't exist or has been removed.

Back to client
) } // Convert API response to StatsDataPoint[] format for charts const history: StatsDataPoint[] = statsData?.history?.map(h => ({ ...h, timestamp: new Date(h.timestamp) })) || [] const latest = statsData?.latest const handlePowerAction = async (command: 'ON' | 'OFF' | 'POWERCYCLE' | 'RESET') => { setActionLoading(command) try { await serverAction.mutateAsync({ clientId, serverId, action: { action: 'power', command } }) // Refresh server data after action setTimeout(() => refetchServer(), 2000) } catch (error) { console.error('Power action failed:', error) } finally { setActionLoading(null) } } const handleUnlinkServer = async () => { if (!confirm(`Are you sure you want to unlink "${server?.nickname || server?.netcupServerId}" from this client?\n\nThis will remove the server from this enterprise client. The server itself will not be affected.`)) { return } try { await removeServer.mutateAsync({ clientId, serverId }) router.push(`/admin/enterprise-clients/${clientId}`) } catch (error) { console.error('Failed to unlink server:', error) } } const statusColor = server.netcupStatus === 'RUNNING' || server.netcupStatus === 'running' ? 'bg-green-100 text-green-800' : server.netcupStatus === 'SHUTOFF' || server.netcupStatus === 'stopped' ? 'bg-red-100 text-red-800' : 'bg-yellow-100 text-yellow-800' return (
{/* Header */}

{server.nickname || server.netcupServerId}

{server.netcupStatus}

{server.purpose && `${server.purpose} • `} {client.name} • Netcup ID: {server.netcupServerId}

{/* Power Controls */}
{/* Server Info */} {server.netcupIps && server.netcupIps.length > 0 && (
IP Address:{' '} {server.netcupIps[0]}
{server.netcupHostname && (
Hostname:{' '} {server.netcupHostname}
)}
)} {/* Live Stats Panel with Auto-Refresh */} {/* Historical Charts */}

Historical Metrics

{statsLoading ? (
) : (
{/* CPU Chart */}

CPU Usage

{/* Memory Chart */}

Memory Usage

{/* Disk I/O Chart */}

Disk I/O

{/* Network Chart */}

Network Traffic

)}
{/* Quick Stats Cards */}
} /> } /> } /> } />
{/* Containers */}

Containers

) }