import { useEffect, useRef } from 'react'; interface Props { x: number; y: number; mmsi: number; vesselName: string; onRequestTrack: (mmsi: number, minutes: number) => void; onClose: () => void; } const TRACK_OPTIONS = [ { label: '6시간', minutes: 360 }, { label: '12시간', minutes: 720 }, { label: '1일', minutes: 1440 }, { label: '3일', minutes: 4320 }, { label: '5일', minutes: 7200 }, ] as const; const MENU_WIDTH = 180; const MENU_PAD = 8; export function VesselContextMenu({ x, y, mmsi, vesselName, onRequestTrack, onClose }: Props) { const ref = useRef(null); // 화면 밖 보정 const left = Math.min(x, window.innerWidth - MENU_WIDTH - MENU_PAD); const maxTop = window.innerHeight - (TRACK_OPTIONS.length * 30 + 56) - MENU_PAD; const top = Math.min(y, maxTop); useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; const onClick = (e: MouseEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) onClose(); }; const onScroll = () => onClose(); window.addEventListener('keydown', onKey); window.addEventListener('mousedown', onClick, true); window.addEventListener('scroll', onScroll, true); return () => { window.removeEventListener('keydown', onKey); window.removeEventListener('mousedown', onClick, true); window.removeEventListener('scroll', onScroll, true); }; }, [onClose]); const handleSelect = (minutes: number) => { onRequestTrack(mmsi, minutes); onClose(); }; return (
{/* Header */}
{vesselName}
{/* 항적조회 항목 */}
항적조회
{TRACK_OPTIONS.map((opt) => ( ))}
); }