"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; } export function TabsWidget({ component, className, style }: 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]); // ํ™”๋ฉด ๋ ˆ์ด์•„์›ƒ ๋กœ๋“œ const loadScreenLayout = async (screenId: number) => { if (screenLayouts[screenId]) { return; // ์ด๋ฏธ ๋กœ๋“œ๋จ } setLoadingScreens((prev) => ({ ...prev, [screenId]: true })); try { const response = await fetch(`/api/screen-management/screens/${screenId}/layout`); if (response.ok) { const data = await response.json(); if (data.success && data.data) { setScreenLayouts((prev) => ({ ...prev, [screenId]: data.data })); } } } catch (error) { console.error(`Failed to load screen layout ${screenId}:`, error); } finally { setLoadingScreens((prev) => ({ ...prev, [screenId]: false })); } }; // ํƒญ ๋ณ€๊ฒฝ ํ•ธ๋“ค๋Ÿฌ const handleTabChange = (tabId: string) => { setSelectedTab(tabId); // ํ•ด๋‹น ํƒญ์˜ ํ™”๋ฉด ๋กœ๋“œ const tab = visibleTabs.find((t) => t.id === tabId); if (tab && tab.screenId && !screenLayouts[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) { return (

ํƒญ์ด ์—†์Šต๋‹ˆ๋‹ค

); } return ( {visibleTabs.map((tab) => (
{tab.label} {allowCloseable && ( )}
))}
{visibleTabs.map((tab) => ( {tab.screenId ? ( loadingScreens[tab.screenId] ? (
ํ™”๋ฉด ๋กœ๋”ฉ ์ค‘...
) : screenLayouts[tab.screenId] ? (
) : (

ํ™”๋ฉด์„ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค

) ) : (

์—ฐ๊ฒฐ๋œ ํ™”๋ฉด์ด ์—†์Šต๋‹ˆ๋‹ค

)}
))}
); }