"use client"; import React, { useState, useEffect } from "react"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Switch } from "@/components/ui/switch"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { apiClient } from "@/lib/api/client"; interface LocationSwapSelectorConfigPanelProps { config: any; onChange: (config: any) => void; tableColumns?: Array<{ columnName: string; columnLabel?: string; dataType?: string }>; screenTableName?: string; } /** * LocationSwapSelector 설정 패널 */ export function LocationSwapSelectorConfigPanel({ config, onChange, tableColumns = [], screenTableName, }: LocationSwapSelectorConfigPanelProps) { const [tables, setTables] = useState>([]); const [columns, setColumns] = useState>([]); const [codeCategories, setCodeCategories] = useState>([]); // 테이블 목록 로드 useEffect(() => { const loadTables = async () => { try { const response = await apiClient.get("/table-management/tables"); if (response.data.success && response.data.data) { setTables( response.data.data.map((t: any) => ({ name: t.tableName || t.table_name, label: t.displayName || t.tableLabel || t.table_label || t.tableName || t.table_name, })) ); } } catch (error) { console.error("테이블 목록 로드 실패:", error); } }; loadTables(); }, []); // 선택된 테이블의 컬럼 로드 useEffect(() => { const loadColumns = async () => { const tableName = config?.dataSource?.tableName; if (!tableName) { setColumns([]); return; } try { const response = await apiClient.get(`/table-management/tables/${tableName}/columns`); if (response.data.success) { // API 응답 구조 처리: data가 배열이거나 data.columns가 배열일 수 있음 let columnData = response.data.data; if (!Array.isArray(columnData) && columnData?.columns) { columnData = columnData.columns; } if (Array.isArray(columnData)) { setColumns( columnData.map((c: any) => ({ name: c.columnName || c.column_name || c.name, label: c.displayName || c.columnLabel || c.column_label || c.columnName || c.column_name || c.name, })) ); } } } catch (error) { console.error("컬럼 목록 로드 실패:", error); } }; if (config?.dataSource?.type === "table") { loadColumns(); } }, [config?.dataSource?.tableName, config?.dataSource?.type]); // 코드 카테고리 로드 (API가 없을 수 있으므로 에러 무시) useEffect(() => { const loadCodeCategories = async () => { try { const response = await apiClient.get("/code-management/categories"); if (response.data.success && response.data.data) { setCodeCategories( response.data.data.map((c: any) => ({ value: c.category_code || c.categoryCode || c.code, label: c.category_name || c.categoryName || c.name, })) ); } } catch (error: any) { // 404는 API가 없는 것이므로 무시 if (error?.response?.status !== 404) { console.error("코드 카테고리 로드 실패:", error); } } }; loadCodeCategories(); }, []); const handleChange = (path: string, value: any) => { const keys = path.split("."); const newConfig = { ...config }; let current: any = newConfig; for (let i = 0; i < keys.length - 1; i++) { if (!current[keys[i]]) { current[keys[i]] = {}; } current = current[keys[i]]; } current[keys[keys.length - 1]] = value; onChange(newConfig); }; return (
{/* 데이터 소스 타입 */}
{/* 고정 옵션 설정 (type이 static일 때) */} {(!config?.dataSource?.type || config?.dataSource?.type === "static") && (

고정 옵션 설정

{ const options = config?.dataSource?.staticOptions || []; const newOptions = [...options]; newOptions[0] = { ...newOptions[0], value: e.target.value }; handleChange("dataSource.staticOptions", newOptions); }} placeholder="예: pohang" className="h-8 text-xs" />
{ const options = config?.dataSource?.staticOptions || []; const newOptions = [...options]; newOptions[0] = { ...newOptions[0], label: e.target.value }; handleChange("dataSource.staticOptions", newOptions); }} placeholder="예: 포항" className="h-8 text-xs" />
{ const options = config?.dataSource?.staticOptions || []; const newOptions = [...options]; newOptions[1] = { ...newOptions[1], value: e.target.value }; handleChange("dataSource.staticOptions", newOptions); }} placeholder="예: gwangyang" className="h-8 text-xs" />
{ const options = config?.dataSource?.staticOptions || []; const newOptions = [...options]; newOptions[1] = { ...newOptions[1], label: e.target.value }; handleChange("dataSource.staticOptions", newOptions); }} placeholder="예: 광양" className="h-8 text-xs" />

고정된 2개 장소만 사용할 때 설정하세요. (예: 포항 ↔ 광양)

)} {/* 테이블 선택 (type이 table일 때) */} {config?.dataSource?.type === "table" && ( <>
)} {/* 코드 카테고리 선택 (type이 code일 때) */} {config?.dataSource?.type === "code" && (
)} {/* 필드 매핑 */}

필드 매핑 (저장 위치)

{screenTableName && (

현재 화면 테이블: {screenTableName}

)}
{tableColumns.length > 0 ? ( ) : ( handleChange("departureField", e.target.value)} placeholder="departure" /> )}
{tableColumns.length > 0 ? ( ) : ( handleChange("destinationField", e.target.value)} placeholder="destination" /> )}
{tableColumns.length > 0 ? ( ) : ( handleChange("departureLabelField", e.target.value)} placeholder="departure_name" /> )}
{tableColumns.length > 0 ? ( ) : ( handleChange("destinationLabelField", e.target.value)} placeholder="destination_name" /> )}
{/* UI 설정 */}

UI 설정

handleChange("departureLabel", e.target.value)} />
handleChange("destinationLabel", e.target.value)} />
handleChange("showSwapButton", checked)} />
{/* 안내 */}

사용 방법:
1. 데이터 소스에서 장소 목록을 가져올 위치를 선택합니다
2. 출발지/도착지 값이 저장될 필드를 지정합니다
3. 교환 버튼을 클릭하면 출발지와 도착지가 바뀝니다

); }