import { useCallback, useRef, useState } from 'react' import { useAreaSearchStore } from '../stores/areaSearchStore' import { MAX_ZONES, ZONE_COLORS } from '../types/areaSearch.types' import type { ZoneDrawType } from '../types/areaSearch.types' const DRAW_BUTTONS: { type: ZoneDrawType; label: string; icon: string }[] = [ { type: 'Polygon', label: '폴리곤', icon: '⬠' }, { type: 'Box', label: '사각형', icon: '▭' }, { type: 'Circle', label: '원', icon: '○' }, ] interface ZoneDrawPanelProps { maxZones?: number disabled?: boolean } export default function ZoneDrawPanel({ maxZones = MAX_ZONES, disabled }: ZoneDrawPanelProps) { const zones = useAreaSearchStore((s) => s.zones) const activeDrawType = useAreaSearchStore((s) => s.activeDrawType) const setActiveDrawType = useAreaSearchStore((s) => s.setActiveDrawType) const removeZone = useAreaSearchStore((s) => s.removeZone) const reorderZones = useAreaSearchStore((s) => s.reorderZones) const canAddZone = zones.length < maxZones // 드래그 순서 변경 const dragIndexRef = useRef(null) const [dragOverIndex, setDragOverIndex] = useState(null) const handleDrawClick = useCallback( (type: ZoneDrawType) => { if (!canAddZone || disabled) return setActiveDrawType(activeDrawType === type ? null : type) }, [activeDrawType, canAddZone, disabled, setActiveDrawType], ) const handleDragStart = useCallback((e: React.DragEvent, index: number) => { dragIndexRef.current = index e.dataTransfer.effectAllowed = 'move' }, []) const handleDragOver = useCallback((e: React.DragEvent, index: number) => { e.preventDefault() setDragOverIndex(index) }, []) const handleDrop = useCallback( (e: React.DragEvent, toIndex: number) => { e.preventDefault() const from = dragIndexRef.current if (from !== null && from !== toIndex) { reorderZones(from, toIndex) } dragIndexRef.current = null setDragOverIndex(null) }, [reorderZones], ) return (
구역 설정 {zones.length}/{maxZones}
{/* 그리기 버튼 */}
{DRAW_BUTTONS.map((btn) => ( ))}
{activeDrawType && (

{activeDrawType === 'Polygon' && '지도를 클릭하여 꼭짓점을 추가하세요. 더블클릭으로 완료.'} {activeDrawType === 'Box' && '드래그하여 사각형을 그리세요.'} {activeDrawType === 'Circle' && '드래그하여 원을 그리세요.'} (ESC: 취소)

)} {/* 구역 목록 */} {zones.length > 0 && (
    {zones.map((zone, index) => { const color = ZONE_COLORS[zone.colorIndex % ZONE_COLORS.length] return (
  • 1} onDragStart={(e) => handleDragStart(e, index)} onDragOver={(e) => handleDragOver(e, index)} onDrop={(e) => handleDrop(e, index)} onDragEnd={() => { dragIndexRef.current = null; setDragOverIndex(null) }} className={`flex items-center gap-2 rounded-md px-2 py-1.5 text-xs transition ${ dragOverIndex === index ? 'ring-1 ring-primary/40' : '' } bg-surface-hover/50 hover:bg-surface-hover`} > {zones.length > 1 && ( )} 구역 {zone.name} {zone.type === 'Box' ? '사각형' : zone.type === 'Circle' ? '원' : '폴리곤'}
  • ) })}
)}
) }