"use client"; import { useState, useEffect } from "react"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Badge } from "@/components/ui/badge"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { FileText, Layers, GitBranch, Plus, Trash2, GripVertical, Loader2, Save, } from "lucide-react"; import { toast } from "sonner"; import { ScreenDefinition } from "@/types/screen"; import { screenApi } from "@/lib/api/screen"; import { PopScreenGroup, getPopScreenGroups } from "@/lib/api/popScreenGroup"; import { PopScreenFlowView } from "./PopScreenFlowView"; // ============================================================ // 타입 정의 // ============================================================ interface PopScreenSettingModalProps { open: boolean; onOpenChange: (open: boolean) => void; screen: ScreenDefinition | null; onSave?: (updatedScreen: Partial) => void; } interface SubScreenItem { id: string; name: string; type: "modal" | "drawer" | "fullscreen"; triggerFrom?: string; } // ============================================================ // 메인 컴포넌트 // ============================================================ export function PopScreenSettingModal({ open, onOpenChange, screen, onSave, }: PopScreenSettingModalProps) { const [activeTab, setActiveTab] = useState("overview"); const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); // 개요 탭 상태 const [screenName, setScreenName] = useState(""); const [screenDescription, setScreenDescription] = useState(""); const [selectedCategoryId, setSelectedCategoryId] = useState(""); const [screenIcon, setScreenIcon] = useState(""); // 하위 화면 탭 상태 const [subScreens, setSubScreens] = useState([]); // 카테고리 목록 const [categories, setCategories] = useState([]); // 초기 데이터 로드 useEffect(() => { if (!open || !screen) return; // 화면 정보 설정 setScreenName(screen.screenName || ""); setScreenDescription(screen.description || ""); setScreenIcon(""); setSelectedCategoryId(""); // 카테고리 목록 로드 loadCategories(); // 레이아웃에서 하위 화면 정보 로드 loadLayoutData(); }, [open, screen]); const loadCategories = async () => { try { const data = await getPopScreenGroups(); setCategories(data.filter((g) => g.hierarchy_path?.startsWith("POP/"))); } catch (error) { console.error("카테고리 로드 실패:", error); } }; const loadLayoutData = async () => { if (!screen) return; try { setLoading(true); const layout = await screenApi.getLayoutPop(screen.screenId); if (layout && layout.subScreens) { setSubScreens( layout.subScreens.map((sub: any) => ({ id: sub.id || `sub-${Date.now()}`, name: sub.name || "", type: sub.type || "modal", triggerFrom: sub.triggerFrom || "main", })) ); } else { setSubScreens([]); } } catch (error) { console.error("레이아웃 로드 실패:", error); setSubScreens([]); } finally { setLoading(false); } }; // 하위 화면 추가 const addSubScreen = () => { const newSubScreen: SubScreenItem = { id: `sub-${Date.now()}`, name: `새 모달 ${subScreens.length + 1}`, type: "modal", triggerFrom: "main", }; setSubScreens([...subScreens, newSubScreen]); }; // 하위 화면 삭제 const removeSubScreen = (id: string) => { setSubScreens(subScreens.filter((s) => s.id !== id)); }; // 하위 화면 업데이트 const updateSubScreen = (id: string, field: keyof SubScreenItem, value: string) => { setSubScreens( subScreens.map((s) => (s.id === id ? { ...s, [field]: value } : s)) ); }; // 저장 const handleSave = async () => { if (!screen) return; try { setSaving(true); // 화면 기본 정보 업데이트 const screenUpdate: Partial = { screenName, description: screenDescription, }; // 레이아웃에 하위 화면 정보 저장 const currentLayout = await screenApi.getLayoutPop(screen.screenId); const updatedLayout = { ...currentLayout, version: "pop-1.0", subScreens: subScreens, // flow 배열 자동 생성 (메인 → 각 서브) flow: subScreens.map((sub) => ({ from: sub.triggerFrom || "main", to: sub.id, })), }; await screenApi.saveLayoutPop(screen.screenId, updatedLayout); toast.success("화면 설정이 저장되었습니다."); onSave?.(screenUpdate); onOpenChange(false); } catch (error) { console.error("저장 실패:", error); toast.error("저장에 실패했습니다."); } finally { setSaving(false); } }; if (!screen) return null; return ( POP 화면 설정 {screen.screenName} ({screen.screenCode}) 개요 하위 화면 {subScreens.length > 0 && ( {subScreens.length} )} 화면 흐름 {/* 개요 탭 */} {loading ? (
) : (
setScreenName(e.target.value)} placeholder="화면 이름" className="h-8 text-xs sm:h-10 sm:text-sm" />