import type { NodeProps } from "@xyflow/react"; import { Handle, Position } from "@xyflow/react"; import { Box, Check, Copy, Cpu, HardDrive, Server } from "lucide-react"; import { useState } from "react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/cn"; import type { ServerMetadata, TopologyNodeData } from "@/lib/topology-types"; export function ServerNode({ data, selected }: NodeProps) { const nodeData = data as TopologyNodeData | TopologyNodeData; const metadata = nodeData.metadata as ServerMetadata | ServerMetadata; const { server, readyPods, podCount, health } = metadata; const k8sNodes = "k8sNodes" in metadata ? metadata.k8sNodes : []; const connectedProxies = "connectedProxies" in metadata ? metadata.connectedProxies : []; const connectionInfo = "connectionInfo" in metadata ? metadata.connectionInfo : null; const metrics = "metrics" in metadata ? metadata.metrics : undefined; const [copied, setCopied] = useState(false); const handleCopy = async (e: React.MouseEvent) => { e.stopPropagation(); if (connectionInfo?.connectionString) { await navigator.clipboard.writeText(connectionInfo.connectionString); setCopied(true); setTimeout(() => setCopied(false), 2000); } }; const getStatusBadge = () => { switch (health) { case "healthy": return Healthy; case "degraded": return Degraded; case "unhealthy": return Unhealthy; default: return ( Unknown ); } }; return (

{server.id}

{server.description && (

{server.description}

)}
{getStatusBadge()}
{server.jar_type} MC {server.minecraft_version} {server.type} {connectionInfo && ( {connectionInfo.type} )}
Pods {readyPods}/{podCount}
Memory {metrics?.memoryUsage && ( {metrics.memoryUsage} / )} {server.memory_request}/{server.memory}MB
CPU {metrics?.cpuUsage && {metrics.cpuUsage} / } {server.cpu_request || "N/A"}/{server.cpu_limit || "N/A"}
{connectionInfo?.connectionString && (
{connectionInfo.connectionString}
{connectionInfo.note && (

{connectionInfo.note}

)}
)} {"pods" in metadata && metadata.pods && metadata.pods.length > 0 && (
Restarts sum + (p.restarts || 0), 0) > 0 ? "text-yellow-600" : "text-green-600" )} > {metadata.pods.reduce((sum, p) => sum + (p.restarts || 0), 0)}
{metadata.pods[0]?.age && (
Age {metadata.pods[0].age}
)} {metadata.pods[0]?.ip && (
Pod IP {metadata.pods[0].ip}
)}
)} {(k8sNodes.length > 0 || connectedProxies.length > 0) && (
{connectedProxies.length > 0 && (
Exposed By {connectedProxies.length} proxies
)} {k8sNodes.length > 0 && (
K8s Node {k8sNodes[0]}
)}
)}
); }