import { memo, useState, useRef, useEffect } from 'react' import { NodeResizer, useReactFlow, type NodeProps } from '@xyflow/react' import type { GroupNodeData } from '@/types/network-diagram' const GROUP_COLORS: Record = { subnet: '#60a5fa', vlan: '#a78bfa', site: '#34d399', dmz: '#f87171', custom: '#94a3b8', } const GroupNodeComponent = ({ data, selected, id }: NodeProps) => { const groupData = data as GroupNodeData const color = GROUP_COLORS[groupData.groupType] ?? GROUP_COLORS.custom const [editing, setEditing] = useState(false) const [labelValue, setLabelValue] = useState(groupData.label ?? '') const inputRef = useRef(null) const { updateNodeData } = useReactFlow() useEffect(() => { if (editing) inputRef.current?.focus() }, [editing]) // Sync if external data.label changes useEffect(() => { if (!editing) setLabelValue(groupData.label ?? '') }, [groupData.label, editing]) const handleLabelCommit = () => { setEditing(false) if (labelValue !== groupData.label) { updateNodeData(id, { ...groupData, label: labelValue }) } } return ( <>
{editing ? ( setLabelValue(e.target.value)} onBlur={handleLabelCommit} onKeyDown={e => { if (e.key === 'Enter' || e.key === 'Escape') handleLabelCommit() e.stopPropagation() }} className="rounded-sm px-1.5 py-0.5 text-[11px] font-semibold bg-card/90 border-none outline-none min-w-[40px] max-w-[200px]" style={{ color }} /> ) : ( setEditing(true)} > {labelValue || groupData.groupType} )}
) } GroupNodeComponent.displayName = 'GroupNode' export const GroupNode = memo(GroupNodeComponent) export default GroupNode