"use client"; import React, { useState, useEffect } from "react"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Button } from "@/components/ui/button"; import { X, Loader2 } from "lucide-react"; import type { TabsComponent, TabItem } from "@/types/screen-management"; import { InteractiveScreenViewerDynamic } from "@/components/screen/InteractiveScreenViewerDynamic"; interface TabsWidgetProps { component: TabsComponent; className?: string; style?: React.CSSProperties; menuObjid?: number; // πŸ†• λΆ€λͺ¨ ν™”λ©΄μ˜ 메뉴 OBJID } export function TabsWidget({ component, className, style, menuObjid }: TabsWidgetProps) { const { tabs = [], defaultTab, orientation = "horizontal", variant = "default", allowCloseable = false, persistSelection = false, } = component; console.log("🎨 TabsWidget λ Œλ”λ§:", { componentId: component.id, tabs, tabsLength: tabs.length, component, }); const storageKey = `tabs-${component.id}-selected`; // 초기 선택 νƒ­ κ²°μ • const getInitialTab = () => { if (persistSelection && typeof window !== "undefined") { const saved = localStorage.getItem(storageKey); if (saved && tabs.some((t) => t.id === saved)) { return saved; } } return defaultTab || tabs[0]?.id || ""; }; const [selectedTab, setSelectedTab] = useState(getInitialTab()); const [visibleTabs, setVisibleTabs] = useState(tabs); const [loadingScreens, setLoadingScreens] = useState>({}); const [screenLayouts, setScreenLayouts] = useState>({}); // μ»΄ν¬λ„ŒνŠΈ νƒ­ λͺ©λ‘ λ³€κ²½ μ‹œ 동기화 useEffect(() => { setVisibleTabs(tabs.filter((tab) => !tab.disabled)); }, [tabs]); // μ„ νƒλœ νƒ­ λ³€κ²½ μ‹œ localStorage에 μ €μž₯ useEffect(() => { if (persistSelection && typeof window !== "undefined") { localStorage.setItem(storageKey, selectedTab); } }, [selectedTab, persistSelection, storageKey]); // 초기 λ‘œλ“œ μ‹œ μ„ νƒλœ νƒ­μ˜ ν™”λ©΄ 뢈러였기 useEffect(() => { const currentTab = visibleTabs.find((t) => t.id === selectedTab); console.log("πŸ”„ 초기 νƒ­ λ‘œλ“œ:", { selectedTab, currentTab, hasScreenId: !!currentTab?.screenId, screenId: currentTab?.screenId, }); if (currentTab && currentTab.screenId && !screenLayouts[currentTab.screenId]) { console.log("πŸ“₯ 초기 ν™”λ©΄ λ‘œλ”© μ‹œμž‘:", currentTab.screenId); loadScreenLayout(currentTab.screenId); } }, [selectedTab, visibleTabs]); // ν™”λ©΄ λ ˆμ΄μ•„μ›ƒ λ‘œλ“œ const loadScreenLayout = async (screenId: number) => { if (screenLayouts[screenId]) { console.log("βœ… 이미 λ‘œλ“œλœ ν™”λ©΄:", screenId); return; // 이미 λ‘œλ“œλ¨ } console.log("πŸ“₯ ν™”λ©΄ λ ˆμ΄μ•„μ›ƒ λ‘œλ”© μ‹œμž‘:", screenId); setLoadingScreens((prev) => ({ ...prev, [screenId]: true })); try { const { apiClient } = await import("@/lib/api/client"); const response = await apiClient.get(`/screen-management/screens/${screenId}/layout`); console.log("πŸ“¦ API 응닡:", { screenId, success: response.data.success, hasData: !!response.data.data }); if (response.data.success && response.data.data) { console.log("βœ… ν™”λ©΄ λ ˆμ΄μ•„μ›ƒ λ‘œλ“œ μ™„λ£Œ:", screenId); setScreenLayouts((prev) => ({ ...prev, [screenId]: response.data.data })); } else { console.error("❌ ν™”λ©΄ λ ˆμ΄μ•„μ›ƒ λ‘œλ“œ μ‹€νŒ¨ - success false"); } } catch (error) { console.error(`❌ ν™”λ©΄ λ ˆμ΄μ•„μ›ƒ λ‘œλ“œ μ‹€νŒ¨ ${screenId}:`, error); } finally { setLoadingScreens((prev) => ({ ...prev, [screenId]: false })); } }; // νƒ­ λ³€κ²½ ν•Έλ“€λŸ¬ const handleTabChange = (tabId: string) => { console.log("πŸ”„ νƒ­ λ³€κ²½:", tabId); setSelectedTab(tabId); // ν•΄λ‹Ή νƒ­μ˜ ν™”λ©΄ λ‘œλ“œ const tab = visibleTabs.find((t) => t.id === tabId); console.log("πŸ” μ„ νƒλœ νƒ­ 정보:", { tab, hasScreenId: !!tab?.screenId, screenId: tab?.screenId }); if (tab && tab.screenId && !screenLayouts[tab.screenId]) { console.log("πŸ“₯ νƒ­ λ³€κ²½ μ‹œ ν™”λ©΄ λ‘œλ”©:", tab.screenId); loadScreenLayout(tab.screenId); } }; // νƒ­ λ‹«κΈ° ν•Έλ“€λŸ¬ const handleCloseTab = (tabId: string, e: React.MouseEvent) => { e.stopPropagation(); const updatedTabs = visibleTabs.filter((tab) => tab.id !== tabId); setVisibleTabs(updatedTabs); // 닫은 탭이 μ„ νƒλœ νƒ­μ΄μ—ˆλ‹€λ©΄ λ‹€μŒ νƒ­ 선택 if (selectedTab === tabId && updatedTabs.length > 0) { setSelectedTab(updatedTabs[0].id); } }; // νƒ­ μŠ€νƒ€μΌ 클래슀 const getTabsListClass = () => { const baseClass = orientation === "vertical" ? "flex-col" : ""; const variantClass = variant === "pills" ? "bg-muted p-1 rounded-lg" : variant === "underline" ? "border-b" : "bg-muted p-1"; return `${baseClass} ${variantClass}`; }; if (visibleTabs.length === 0) { console.log("⚠️ λ³΄μ΄λŠ” 탭이 μ—†μŒ"); return (

탭이 μ—†μŠ΅λ‹ˆλ‹€

); } console.log("🎨 TabsWidget μ΅œμ’… λ Œλ”λ§:", { visibleTabsCount: visibleTabs.length, selectedTab, screenLayoutsKeys: Object.keys(screenLayouts), loadingScreensKeys: Object.keys(loadingScreens), }); return (
{visibleTabs.map((tab) => (
{tab.label} {allowCloseable && ( )}
))}
{visibleTabs.map((tab) => ( {tab.screenId ? ( loadingScreens[tab.screenId] ? (
ν™”λ©΄ λ‘œλ”© 쀑...
) : screenLayouts[tab.screenId] ? ( (() => { const layoutData = screenLayouts[tab.screenId]; const { components = [], screenResolution } = layoutData; console.log("🎯 λ Œλ”λ§ν•  ν™”λ©΄ 데이터:", { screenId: tab.screenId, componentsCount: components.length, screenResolution, }); const designWidth = screenResolution?.width || 1920; const designHeight = screenResolution?.height || 1080; return (
{components.map((component: any) => ( ))}
); })() ) : (

화면을 뢈러올 수 μ—†μŠ΅λ‹ˆλ‹€

) ) : (

μ—°κ²°λœ 화면이 μ—†μŠ΅λ‹ˆλ‹€

)}
))}
); }