"use client"; import { useState, useEffect, useCallback } from "react"; import { useSearchParams } from "next/navigation"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Plus, RefreshCw, Search, Smartphone, Eye, Settings, LayoutGrid, GitBranch, } from "lucide-react"; import { PopDesigner } from "@/components/pop/designer"; import { ScrollToTop } from "@/components/common/ScrollToTop"; import { ScreenDefinition } from "@/types/screen"; import { screenApi } from "@/lib/api/screen"; import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"; import CreateScreenModal from "@/components/screen/CreateScreenModal"; import { Badge } from "@/components/ui/badge"; import { cn } from "@/lib/utils"; import { PopCategoryTree, PopScreenPreview, PopScreenFlowView, PopScreenSettingModal, } from "@/components/pop/management"; import { PopScreenGroup } from "@/lib/api/popScreenGroup"; // ============================================================ // 타입 정의 // ============================================================ type Step = "list" | "design"; type DevicePreview = "mobile" | "tablet"; type RightPanelView = "preview" | "flow"; // ============================================================ // 메인 컴포넌트 // ============================================================ export default function PopScreenManagementPage() { const searchParams = useSearchParams(); // 단계 및 화면 상태 const [currentStep, setCurrentStep] = useState("list"); const [selectedScreen, setSelectedScreen] = useState(null); const [selectedGroup, setSelectedGroup] = useState(null); const [stepHistory, setStepHistory] = useState(["list"]); // 화면 데이터 const [screens, setScreens] = useState([]); const [loading, setLoading] = useState(true); const [searchTerm, setSearchTerm] = useState(""); // POP 레이아웃 존재 화면 ID const [popLayoutScreenIds, setPopLayoutScreenIds] = useState>(new Set()); // UI 상태 const [isCreateOpen, setIsCreateOpen] = useState(false); const [isSettingModalOpen, setIsSettingModalOpen] = useState(false); const [devicePreview, setDevicePreview] = useState("tablet"); const [rightPanelView, setRightPanelView] = useState("preview"); // ============================================================ // 데이터 로드 // ============================================================ const loadScreens = useCallback(async () => { try { setLoading(true); const [result, popScreenIds] = await Promise.all([ screenApi.getScreens({ page: 1, size: 1000, searchTerm: "" }), screenApi.getScreenIdsWithPopLayout(), ]); if (result.data && result.data.length > 0) { setScreens(result.data); } setPopLayoutScreenIds(new Set(popScreenIds)); } catch (error) { console.error("POP 화면 목록 로드 실패:", error); } finally { setLoading(false); } }, []); useEffect(() => { loadScreens(); }, [loadScreens]); // 화면 목록 새로고침 이벤트 리스너 useEffect(() => { const handleScreenListRefresh = () => { console.log("POP 화면 목록 새로고침 이벤트 수신"); loadScreens(); }; window.addEventListener("screen-list-refresh", handleScreenListRefresh); return () => { window.removeEventListener("screen-list-refresh", handleScreenListRefresh); }; }, [loadScreens]); // URL 쿼리 파라미터로 화면 디자이너 자동 열기 useEffect(() => { const openDesignerId = searchParams.get("openDesigner"); if (openDesignerId && screens.length > 0) { const screenId = parseInt(openDesignerId, 10); const targetScreen = screens.find((s) => s.screenId === screenId); if (targetScreen) { setSelectedScreen(targetScreen); setCurrentStep("design"); setStepHistory(["list", "design"]); } } }, [searchParams, screens]); // ============================================================ // 핸들러 // ============================================================ const goToNextStep = (nextStep: Step) => { setStepHistory((prev) => [...prev, nextStep]); setCurrentStep(nextStep); }; const goToStep = (step: Step) => { setCurrentStep(step); const stepIndex = stepHistory.findIndex((s) => s === step); if (stepIndex !== -1) { setStepHistory(stepHistory.slice(0, stepIndex + 1)); } }; // 화면 선택 const handleScreenSelect = (screen: ScreenDefinition) => { setSelectedScreen(screen); setSelectedGroup(null); }; // 그룹 선택 const handleGroupSelect = (group: PopScreenGroup | null) => { setSelectedGroup(group); // 그룹 선택 시 화면 선택 해제하지 않음 (미리보기 유지) }; // 화면 디자인 모드 진입 const handleDesignScreen = (screen: ScreenDefinition) => { setSelectedScreen(screen); goToNextStep("design"); }; // POP 화면 미리보기 (새 탭에서 열기) const handlePreviewScreen = (screen: ScreenDefinition) => { const previewUrl = `/pop/screens/${screen.screenId}?preview=true&device=${devicePreview}`; window.open(previewUrl, "_blank", "width=800,height=900"); }; // 화면 설정 모달 열기 const handleOpenSettings = () => { if (selectedScreen) { setIsSettingModalOpen(true); } }; // ============================================================ // 필터링된 데이터 // ============================================================ // POP 레이아웃이 있는 화면만 필터링 const popScreens = screens.filter((screen) => popLayoutScreenIds.has(screen.screenId)); // 검색어 필터링 const filteredScreens = popScreens.filter((screen) => { if (!searchTerm) return true; return ( screen.screenName.toLowerCase().includes(searchTerm.toLowerCase()) || screen.screenCode.toLowerCase().includes(searchTerm.toLowerCase()) ); }); const popScreenCount = popLayoutScreenIds.size; // ============================================================ // 디자인 모드 // ============================================================ const isDesignMode = currentStep === "design"; if (isDesignMode && selectedScreen) { return (
goToStep("list")} onScreenUpdate={(updatedFields) => { setSelectedScreen({ ...selectedScreen, ...updatedFields, }); }} />
); } // ============================================================ // 목록 모드 렌더링 // ============================================================ return (
{/* 페이지 헤더 */}

POP 화면 관리

모바일/태블릿

POP 화면을 카테고리별로 관리하고 모바일/태블릿에 최적화된 화면을 설계합니다

{/* 메인 콘텐츠 */} {popScreenCount === 0 ? ( // POP 화면이 없을 때 빈 상태 표시

POP 화면이 없습니다

아직 생성된 POP 화면이 없습니다.
"새 POP 화면" 버튼을 클릭하여 모바일/태블릿용 화면을 만들어보세요.

) : (
{/* 왼쪽: 카테고리 트리 + 화면 목록 */}
{/* 검색 */}
setSearchTerm(e.target.value)} className="pl-9 h-9" />
POP 화면 {popScreenCount}개
{/* 카테고리 트리 */}
{/* 오른쪽: 미리보기 / 화면 흐름 */}
{/* 오른쪽 패널 헤더 */}
setRightPanelView(v as RightPanelView)}> 미리보기 화면 흐름 {selectedScreen && (
)}
{/* 오른쪽 패널 콘텐츠 */}
{rightPanelView === "preview" ? ( ) : ( )}
)} {/* 화면 생성 모달 */} { setIsCreateOpen(open); if (!open) loadScreens(); }} onCreated={() => { setIsCreateOpen(false); loadScreens(); }} isPop={true} /> {/* 화면 설정 모달 */} { if (selectedScreen) { setSelectedScreen({ ...selectedScreen, ...updatedFields }); } loadScreens(); }} /> {/* Scroll to Top 버튼 */}
); }