"use client"; import React, { useEffect, useState } from "react"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Switch } from "@/components/ui/switch"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command"; import { Check, ChevronsUpDown, Plus, X, GripVertical, Loader2 } from "lucide-react"; import { cn } from "@/lib/utils"; import type { TabItem, TabsComponent } from "@/types/screen-management"; interface TabsConfigPanelProps { config: any; onChange: (config: any) => void; } interface ScreenInfo { screenId: number; screenName: string; screenCode: string; tableName: string; } export function TabsConfigPanel({ config, onChange }: TabsConfigPanelProps) { const [screens, setScreens] = useState([]); const [loading, setLoading] = useState(false); const [localTabs, setLocalTabs] = useState(config.tabs || []); // 화면 목록 로드 useEffect(() => { const loadScreens = async () => { try { setLoading(true); // API 클라이언트 동적 import (named export 사용) const { apiClient } = await import("@/lib/api/client"); // 전체 화면 목록 조회 (페이징 사이즈 크게) const response = await apiClient.get("/screen-management/screens", { params: { size: 1000 } }); console.log("화면 목록 조회 성공:", response.data); if (response.data.success && response.data.data) { setScreens(response.data.data); } } catch (error: any) { console.error("Failed to load screens:", error); console.error("Error response:", error.response?.data); } finally { setLoading(false); } }; loadScreens(); }, []); // 컴포넌트 변경 시 로컬 상태 동기화 useEffect(() => { setLocalTabs(config.tabs || []); }, [config.tabs]); // 탭 추가 const handleAddTab = () => { const newTab: TabItem = { id: `tab-${Date.now()}`, label: `새 탭 ${localTabs.length + 1}`, order: localTabs.length, disabled: false, }; const updatedTabs = [...localTabs, newTab]; setLocalTabs(updatedTabs); onChange({ ...config, tabs: updatedTabs }); }; // 탭 제거 const handleRemoveTab = (tabId: string) => { const updatedTabs = localTabs.filter((tab) => tab.id !== tabId); setLocalTabs(updatedTabs); onChange({ ...config, tabs: updatedTabs }); }; // 탭 라벨 변경 const handleLabelChange = (tabId: string, label: string) => { const updatedTabs = localTabs.map((tab) => (tab.id === tabId ? { ...tab, label } : tab)); setLocalTabs(updatedTabs); onChange({ ...config, tabs: updatedTabs }); }; // 탭 화면 선택 const handleScreenSelect = (tabId: string, screenId: number, screenName: string) => { const updatedTabs = localTabs.map((tab) => (tab.id === tabId ? { ...tab, screenId, screenName } : tab)); setLocalTabs(updatedTabs); onChange({ ...config, tabs: updatedTabs }); }; // 탭 비활성화 토글 const handleDisabledToggle = (tabId: string, disabled: boolean) => { const updatedTabs = localTabs.map((tab) => (tab.id === tabId ? { ...tab, disabled } : tab)); setLocalTabs(updatedTabs); onChange({ ...config, tabs: updatedTabs }); }; // 탭 순서 변경 const handleMoveTab = (tabId: string, direction: "up" | "down") => { const index = localTabs.findIndex((tab) => tab.id === tabId); if ( (direction === "up" && index === 0) || (direction === "down" && index === localTabs.length - 1) ) { return; } const newTabs = [...localTabs]; const targetIndex = direction === "up" ? index - 1 : index + 1; [newTabs[index], newTabs[targetIndex]] = [newTabs[targetIndex], newTabs[index]]; // order 값 재조정 const updatedTabs = newTabs.map((tab, idx) => ({ ...tab, order: idx })); setLocalTabs(updatedTabs); onChange({ ...config, tabs: updatedTabs }); }; return (

탭 설정

{/* 탭 방향 */}
{/* 탭 스타일 */}
{/* 선택 상태 유지 */}

페이지 새로고침 후에도 선택한 탭이 유지됩니다

onChange({ ...config, persistSelection: checked })} />
{/* 탭 닫기 버튼 */}

각 탭에 닫기 버튼을 표시합니다

onChange({ ...config, allowCloseable: checked })} />

탭 목록

{localTabs.length === 0 ? (

탭이 없습니다

탭 추가 버튼을 클릭하여 새 탭을 생성하세요

) : (
{localTabs.map((tab, index) => (
탭 {index + 1}
{/* 탭 라벨 */}
handleLabelChange(tab.id, e.target.value)} placeholder="탭 이름" className="h-8 text-xs sm:h-9 sm:text-sm" />
{/* 화면 선택 */}
{loading ? (
로딩 중...
) : ( handleScreenSelect(tab.id, screenId, screenName) } /> )} {tab.screenName && (

선택된 화면: {tab.screenName}

)}
{/* 비활성화 */}
handleDisabledToggle(tab.id, checked)} />
))}
)}
); } // 화면 선택 Combobox 컴포넌트 function ScreenSelectCombobox({ screens, selectedScreenId, onSelect, }: { screens: ScreenInfo[]; selectedScreenId?: number; onSelect: (screenId: number, screenName: string) => void; }) { const [open, setOpen] = useState(false); const selectedScreen = screens.find((s) => s.screenId === selectedScreenId); return ( 화면을 찾을 수 없습니다. {screens.map((screen) => ( { onSelect(screen.screenId, screen.screenName); setOpen(false); }} className="text-xs sm:text-sm" >
{screen.screenName} 코드: {screen.screenCode} | 테이블: {screen.tableName}
))}
); }