import React, { useState } from 'react'; import { getSecurityColor } from '../utils/securityColors'; interface MapNodeProps { id: string; name: string; position: { x: number; y: number }; onClick: () => void; onDoubleClick?: (e: React.MouseEvent) => void; onDragStart?: (e: React.MouseEvent) => void; onDrag?: (e: React.MouseEvent) => void; onDragEnd?: (e: React.MouseEvent) => void; onContextMenu?: (e: React.MouseEvent) => void; type: 'region' | 'system'; security?: number; signatures?: number; isDraggable?: boolean; disableNavigate?: boolean; jumps?: number; kills?: number; showJumps?: boolean; showKills?: boolean; viewBoxWidth?: number; // Add viewBox width for scaling calculations } export const MapNode: React.FC = ({ id, name, position, onClick, onDoubleClick, onDragStart, onDrag, onDragEnd, onContextMenu, type, security, signatures, isDraggable = false, disableNavigate = false, jumps, kills, showJumps = false, showKills = false, viewBoxWidth = 1200, }) => { const [isHovered, setIsHovered] = useState(false); const [isDragging, setIsDragging] = useState(false); const handleMouseDown = (e: React.MouseEvent) => { console.log('MapNode handleMouseDown', { isDraggable, type, isDragging }); if (!isDraggable || type !== 'system') return; e.stopPropagation(); onDragStart?.(e); }; const handleMouseMove = (e: React.MouseEvent) => { console.log('MapNode handleMouseMove', { isDragging, isDraggable, type }); if (!isDragging || !isDraggable || type !== 'system') return; e.stopPropagation(); onDrag?.(e); }; const handleMouseUp = (e: React.MouseEvent) => { console.log('MapNode handleMouseUp', { isDragging, isDraggable, type }); if (!isDragging || !isDraggable || type !== 'system') return; e.stopPropagation(); setIsDragging(false); onDragEnd?.(e); }; const handleMouseLeave = (e: React.MouseEvent) => { console.log('MapNode handleMouseLeave', { isDragging, isDraggable, type }); if (!isDragging || !isDraggable || type !== 'system') return; e.stopPropagation(); setIsDragging(false); onDragEnd?.(e); }; const nodeColor = security !== undefined ? getSecurityColor(security) : '#a855f7'; if (type === 'region') { const pillWidth = Math.max(name.length * 5, 40); const pillHeight = 18; return ( setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} onClick={(e) => { e.stopPropagation(); onClick(); }} > {/* Glow effect */} {/* Main pill */} {/* Text inside pill - made smaller */} {name} ); } else { const nodeSize = 6; const textOffset = 20; return ( setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} onMouseDown={handleMouseDown} onClick={(e) => { e.stopPropagation(); onClick(); }} onDoubleClick={(e) => { e.stopPropagation(); onDoubleClick?.(e); }} onContextMenu={(e) => { e.stopPropagation(); onContextMenu?.(e); }} > {/* Node glow effect */} {/* Main node - removed stroke to eliminate white border */} {/* Inner core */} {/* Node label - fixed visual size regardless of zoom */} {name} {security !== undefined && ( {security.toFixed(1)} )} {/* Dynamic text positioning based on what's shown */} {(() => { let currentY = textOffset + 15; const textElements = []; // Add signatures if present if (signatures !== undefined && signatures > 0) { textElements.push( 📡 {signatures} ); currentY += 15; } // Add jumps if enabled and present if (showJumps && jumps !== undefined) { textElements.push( 🚀 {jumps} ); currentY += 15; } // Add kills if enabled and present if (showKills && kills !== undefined) { textElements.push( ⚔️ {kills} ); } return textElements; })()} ); } };