From 4edb8236f3bfdfff4c1232b8408d1959b1544313 Mon Sep 17 00:00:00 2001 From: Nan Kyung Lee Date: Tue, 24 Mar 2026 15:37:23 +0900 Subject: [PATCH] =?UTF-8?q?feat(korea):=20=EC=9E=91=EC=A0=84=EA=B0=80?= =?UTF-8?q?=EC=9D=B4=EB=93=9C=20=EC=B0=BD=20=EB=93=9C=EB=9E=98=EA=B7=B8=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=EA=B0=80=EB=8A=A5=20+=20=ED=81=AC?= =?UTF-8?q?=EA=B8=B0=20=EC=A1=B0=EC=A0=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/korea/OpsGuideModal.tsx | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/korea/OpsGuideModal.tsx b/frontend/src/components/korea/OpsGuideModal.tsx index 154cba7..aba5af5 100644 --- a/frontend/src/components/korea/OpsGuideModal.tsx +++ b/frontend/src/components/korea/OpsGuideModal.tsx @@ -1,4 +1,4 @@ -import { useState, useMemo } from 'react'; +import { useState, useMemo, useRef, useCallback } from 'react'; import type { Ship } from '../../types'; import { COAST_GUARD_FACILITIES, CG_TYPE_LABEL } from '../../services/coastGuard'; import type { CoastGuardFacility } from '../../services/coastGuard'; @@ -32,6 +32,23 @@ const RISK_ICON = { CRITICAL: '🔴', HIGH: '🟡', MEDIUM: '🔵' }; export function OpsGuideModal({ ships, onClose, onFlyTo }: Props) { const [selectedKCG, setSelectedKCG] = useState(null); const [searchRadius, setSearchRadius] = useState(30); // NM + const [pos, setPos] = useState({ x: 60, y: 60 }); + const dragRef = useRef<{ startX: number; startY: number; origX: number; origY: number } | null>(null); + + const onDragStart = useCallback((e: React.MouseEvent) => { + e.preventDefault(); + dragRef.current = { startX: e.clientX, startY: e.clientY, origX: pos.x, origY: pos.y }; + const onMove = (ev: MouseEvent) => { + if (!dragRef.current) return; + setPos({ + x: dragRef.current.origX + (ev.clientX - dragRef.current.startX), + y: dragRef.current.origY + (ev.clientY - dragRef.current.startY), + }); + }; + const onUp = () => { dragRef.current = null; window.removeEventListener('mousemove', onMove); window.removeEventListener('mouseup', onUp); }; + window.addEventListener('mousemove', onMove); + window.addEventListener('mouseup', onUp); + }, [pos]); // 해경서/지방청만 (파출소 제외) const kcgBases = useMemo(() => @@ -108,11 +125,12 @@ export function OpsGuideModal({ ships, onClose, onFlyTo }: Props) { const highCount = suspects.filter(s => s.riskLevel === 'HIGH').length; return ( -
-
e.stopPropagation()}> +
+
- {/* Header */} -
+ {/* Header — drag handle */} +
+ 경비함정 작전 가이드 해경 기지 기준 주변 불법어선·어구 탐지