"use client"; import React, { useState, useCallback } from "react"; import { ChartConfig, QueryResult, MarkerColorRule } from "./types"; import { Plus, Trash2 } from "lucide-react"; import { v4 as uuidv4 } from "uuid"; interface VehicleMapConfigPanelProps { config?: ChartConfig; queryResult?: QueryResult; onConfigChange: (config: ChartConfig) => void; } /** * 차량 위치 지도 설정 패널 * - 위도/경도 컬럼 매핑 * - 라벨/상태 컬럼 설정 */ export function VehicleMapConfigPanel({ config, queryResult, onConfigChange }: VehicleMapConfigPanelProps) { const [currentConfig, setCurrentConfig] = useState(config || {}); // 설정 업데이트 const updateConfig = useCallback( (updates: Partial) => { const newConfig = { ...currentConfig, ...updates }; setCurrentConfig(newConfig); onConfigChange(newConfig); }, [currentConfig, onConfigChange], ); // 사용 가능한 컬럼 목록 const availableColumns = queryResult?.columns || []; const sampleData = queryResult?.rows?.[0] || {}; // 마커 색상 모드 변경 const handleMarkerColorModeChange = useCallback( (mode: "single" | "conditional") => { if (mode === "single") { updateConfig({ markerColorMode: "single", markerColorColumn: undefined, markerColorRules: undefined, markerDefaultColor: "#3b82f6", // 파란색 }); } else { updateConfig({ markerColorMode: "conditional", markerColorRules: [], markerDefaultColor: "#6b7280", // 회색 }); } }, [updateConfig], ); // 마커 색상 규칙 추가 const addColorRule = useCallback(() => { const newRule: MarkerColorRule = { id: uuidv4(), value: "", color: "#3b82f6", label: "", }; const currentRules = currentConfig.markerColorRules || []; updateConfig({ markerColorRules: [...currentRules, newRule] }); }, [currentConfig.markerColorRules, updateConfig]); // 마커 색상 규칙 삭제 const deleteColorRule = useCallback( (id: string) => { const currentRules = currentConfig.markerColorRules || []; updateConfig({ markerColorRules: currentRules.filter((rule) => rule.id !== id) }); }, [currentConfig.markerColorRules, updateConfig], ); // 마커 색상 규칙 업데이트 const updateColorRule = useCallback( (id: string, updates: Partial) => { const currentRules = currentConfig.markerColorRules || []; updateConfig({ markerColorRules: currentRules.map((rule) => (rule.id === id ? { ...rule, ...updates } : rule)), }); }, [currentConfig.markerColorRules, updateConfig], ); return (

🗺️ 지도 설정

{/* 쿼리 결과가 없을 때 */} {!queryResult && (
💡 먼저 SQL 쿼리를 실행하여 데이터를 가져온 후 지도를 설정할 수 있습니다.
)} {/* 데이터 필드 매핑 */} {queryResult && ( <> {/* 지도 제목 */}
updateConfig({ title: e.target.value })} placeholder="차량 위치 지도" className="w-full rounded-lg border border-border px-2 py-1.5 text-xs" />
{/* 위도 컬럼 설정 */}
{/* 경도 컬럼 설정 */}
{/* 라벨 컬럼 (선택사항) */}
{/* 마커 색상 설정 */}
🎨 마커 색상 설정
{/* 색상 모드 선택 */}
{/* 단일 색상 모드 */} {(currentConfig.markerColorMode || "single") === "single" && (
updateConfig({ markerDefaultColor: e.target.value })} className="h-8 w-12 cursor-pointer rounded border border-border" /> updateConfig({ markerDefaultColor: e.target.value })} placeholder="#3b82f6" className="flex-1 rounded-lg border border-border px-2 py-1.5 text-xs" />

모든 마커가 동일한 색상으로 표시됩니다

)} {/* 조건부 색상 모드 */} {currentConfig.markerColorMode === "conditional" && (
{/* 색상 조건 컬럼 선택 */}

이 컬럼의 값에 따라 마커 색상이 결정됩니다

{/* 기본 색상 */}
updateConfig({ markerDefaultColor: e.target.value })} className="h-8 w-12 cursor-pointer rounded border border-border" /> updateConfig({ markerDefaultColor: e.target.value })} placeholder="#6b7280" className="flex-1 rounded-lg border border-border px-2 py-1.5 text-xs" />

규칙에 매칭되지 않는 경우 사용할 색상

{/* 색상 규칙 목록 */}
{/* 규칙 리스트 */} {(currentConfig.markerColorRules || []).length === 0 ? (

추가 버튼을 눌러 색상 규칙을 만드세요

) : (
{(currentConfig.markerColorRules || []).map((rule) => (
{/* 규칙 헤더 */}
규칙
{/* 조건 값 */}
updateColorRule(rule.id, { value: e.target.value })} placeholder="예: active, inactive" className="w-full rounded border border-border px-2 py-1 text-xs" />
{/* 색상 */}
updateColorRule(rule.id, { color: e.target.value })} className="h-8 w-12 cursor-pointer rounded border border-border" /> updateColorRule(rule.id, { color: e.target.value })} placeholder="#3b82f6" className="flex-1 rounded border border-border px-2 py-1 text-xs" />
{/* 라벨 (선택사항) */}
updateColorRule(rule.id, { label: e.target.value })} placeholder="예: 활성, 비활성" className="w-full rounded border border-border px-2 py-1 text-xs" />
))}
)}
)}
{/* 날씨 정보 표시 옵션 */}

마커 팝업에 해당 위치의 날씨 정보를 함께 표시합니다

현재 발효 중인 기상특보(주의보/경보)를 지도에 색상 영역으로 표시합니다

{/* 설정 미리보기 */}
📋 설정 미리보기
위도: {currentConfig.latitudeColumn || "미설정"}
경도: {currentConfig.longitudeColumn || "미설정"}
라벨: {currentConfig.labelColumn || "없음"}
색상 모드: {currentConfig.markerColorMode === "conditional" ? "조건부" : "단일"}
{currentConfig.markerColorMode === "conditional" && ( <>
색상 조건 컬럼: {currentConfig.markerColorColumn || "미설정"}
색상 규칙 개수: {(currentConfig.markerColorRules || []).length}개
)}
날씨 표시: {currentConfig.showWeather ? "활성화" : "비활성화"}
기상특보 표시: {currentConfig.showWeatherAlerts ? "활성화" : "비활성화"}
데이터 개수: {queryResult.rows.length}개
{/* 필수 필드 확인 */} {(!currentConfig.latitudeColumn || !currentConfig.longitudeColumn) && (
⚠️ 위도와 경도 컬럼을 반드시 선택해야 지도에 표시할 수 있습니다.
)} )}
); }