import { useState } from 'react' import { X, Edit, Trash2, ExternalLink, Plus } from 'lucide-react' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { useCanvasStore } from '@/stores/canvasStore' import { NODE_TYPE_LABELS, STATUS_COLORS, type ServiceInfo } from '@/types' import { getServiceUrl } from '@/utils/serviceUrl' interface DetailPanelProps { onEdit: (id: string) => void } export function DetailPanel({ onEdit }: DetailPanelProps) { const { nodes, selectedNodeId, setSelectedNode, deleteNode, updateNode } = useCanvasStore() const node = nodes.find((n) => n.id === selectedNodeId) const [addingService, setAddingService] = useState(false) const [newSvc, setNewSvc] = useState<{ port: string; protocol: 'tcp' | 'udp'; service_name: string }>({ port: '', protocol: 'tcp', service_name: '', }) if (!node || node.data.type === 'groupRect') return null const { data } = node const statusColor = STATUS_COLORS[data.status] const host = data.ip ?? data.hostname const handleDelete = () => { if (confirm(`Delete "${data.label}"?`)) { deleteNode(node.id) } } const handleAddService = () => { const port = parseInt(newSvc.port, 10) if (!newSvc.service_name.trim() || isNaN(port) || port < 1 || port > 65535) return const svc: ServiceInfo = { port, protocol: newSvc.protocol, service_name: newSvc.service_name.trim(), } updateNode(node.id, { services: [...(data.services ?? []), svc] }) setNewSvc({ port: '', protocol: 'tcp', service_name: '' }) setAddingService(false) } const handleRemoveService = (index: number) => { const updated = data.services.filter((_, i) => i !== index) updateNode(node.id, { services: updated }) } return ( ) } function DetailRow({ label, value, mono }: { label: string; value: string; mono?: boolean }) { return (