import type { NodeProps } from "@xyflow/react"; import { Handle, Position } from "@xyflow/react"; import { Box, Check, Copy, Cpu, Globe, HardDrive, Network } 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 { ProxyMetadata, TopologyNodeData } from "@/lib/topology-types"; export function ProxyNode({ data, selected }: NodeProps) { const nodeData = data as TopologyNodeData | TopologyNodeData; const metadata = nodeData.metadata as ProxyMetadata | ProxyMetadata; const { proxy, readyPods, podCount, health, connectedServers } = metadata; const k8sNodes = "k8sNodes" in metadata ? metadata.k8sNodes : []; 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 (

{proxy.id}

{proxy.description && (

{proxy.description}

)}
{getStatusBadge()}
{proxy.type} {connectionInfo && ( {connectionInfo.type} )}
Pods {readyPods}/{podCount}
{proxy.node_port && (
NodePort {proxy.node_port}
)} {connectionInfo?.connectionString && (
Address
{connectionInfo.connectionString}
{connectionInfo.note && (

{connectionInfo.note}

)}
)}
Memory {metrics?.memoryUsage && ( {metrics.memoryUsage} / )} {proxy.memory}MB
CPU {metrics?.cpuUsage && {metrics.cpuUsage} / } {proxy.cpu_request || "N/A"}/{proxy.cpu_limit || "N/A"}
{"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}
)}
Routing To {connectedServers.length} servers
{k8sNodes.length > 0 && (
K8s Node {k8sNodes[0]}
)}
)}
); }