"use client"; import { useState, useEffect } from "react"; import { cn } from "@/lib/utils"; import { Smartphone, Tablet, Loader2, ExternalLink, RefreshCw } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { ScreenDefinition } from "@/types/screen"; import { screenApi } from "@/lib/api/screen"; // ============================================================ // 타입 정의 // ============================================================ type DeviceType = "mobile" | "tablet"; interface PopScreenPreviewProps { screen: ScreenDefinition | null; className?: string; } // 디바이스 프레임 크기 // 모바일: 세로(portrait), 태블릿: 가로(landscape) 디폴트 const DEVICE_SIZES = { mobile: { width: 375, height: 667 }, // iPhone SE 기준 (세로) tablet: { width: 1024, height: 768 }, // iPad 기준 (가로) }; // ============================================================ // 메인 컴포넌트 // ============================================================ export function PopScreenPreview({ screen, className }: PopScreenPreviewProps) { const [deviceType, setDeviceType] = useState("tablet"); const [loading, setLoading] = useState(false); const [hasLayout, setHasLayout] = useState(false); const [key, setKey] = useState(0); // iframe 새로고침용 // 레이아웃 존재 여부 확인 useEffect(() => { if (!screen) { setHasLayout(false); return; } const checkLayout = async () => { try { setLoading(true); const layout = await screenApi.getLayoutPop(screen.screenId); // v2 레이아웃: sections는 객체 (Record) // v1 레이아웃: sections는 배열 if (layout) { const isV2 = layout.version === "pop-2.0"; const hasSections = isV2 ? layout.sections && Object.keys(layout.sections).length > 0 : layout.sections && Array.isArray(layout.sections) && layout.sections.length > 0; setHasLayout(hasSections); } else { setHasLayout(false); } } catch { setHasLayout(false); } finally { setLoading(false); } }; checkLayout(); }, [screen]); // 미리보기 URL const previewUrl = screen ? `/pop/screens/${screen.screenId}?preview=true&device=${deviceType}` : null; // 새 탭에서 열기 const openInNewTab = () => { if (previewUrl) { const size = DEVICE_SIZES[deviceType]; window.open(previewUrl, "_blank", `width=${size.width + 40},height=${size.height + 80}`); } }; // iframe 새로고침 const refreshPreview = () => { setKey((prev) => prev + 1); }; const deviceSize = DEVICE_SIZES[deviceType]; // 미리보기 컨테이너에 맞게 스케일 조정 const scale = deviceType === "tablet" ? 0.5 : 0.6; return (
{/* 헤더 */}

미리보기

{screen && ( {screen.screenName} )}
{/* 디바이스 선택 */} setDeviceType(v as DeviceType)}> 모바일 태블릿 {screen && hasLayout && ( <> )}
{/* 미리보기 영역 */}
{!screen ? ( // 화면 미선택
{deviceType === "mobile" ? ( ) : ( )}

화면을 선택하면 미리보기가 표시됩니다.

) : loading ? ( // 로딩 중

레이아웃 확인 중...

) : !hasLayout ? ( // 레이아웃 없음
{deviceType === "mobile" ? ( ) : ( )}

POP 레이아웃이 없습니다.

화면을 더블클릭하여 설계 모드로 이동하세요.

) : ( // 디바이스 프레임 + iframe (심플한 테두리)