/** * V2 레이아웃 변환 유틸리티 * * 기존 LayoutData ↔ V2 LayoutData 변환 */ import { ComponentV2, LayoutV2, getComponentUrl, getComponentTypeFromUrl, getDefaultsByUrl, mergeComponentConfig, extractCustomConfig } from "@/lib/schemas/componentConfig"; // 기존 ComponentData 타입 (간략화) interface LegacyComponentData { id: string; componentType?: string; widgetType?: string; type?: string; position?: { x: number; y: number }; size?: { width: number; height: number }; componentConfig?: Record; [key: string]: any; } interface LegacyLayoutData { components: LegacyComponentData[]; gridSettings?: any; screenResolution?: any; metadata?: any; } // ============================================ // V2 → Legacy 변환 (로드 시) // ============================================ export function convertV2ToLegacy(v2Layout: LayoutV2 | null): LegacyLayoutData | null { if (!v2Layout || !v2Layout.components) { return null; } const components: LegacyComponentData[] = v2Layout.components.map((comp) => { const componentType = getComponentTypeFromUrl(comp.url); const defaults = getDefaultsByUrl(comp.url); const mergedConfig = mergeComponentConfig(defaults, comp.overrides); return { id: comp.id, componentType: componentType, widgetType: componentType, type: "component", position: comp.position, size: comp.size, componentConfig: mergedConfig, // 기존 구조 호환을 위한 추가 필드 label: mergedConfig.label || componentType, style: {}, parentId: null, gridColumns: 12, gridRowIndex: 0, }; }); return { components, gridSettings: { enabled: true, size: 20, color: "#d1d5db", opacity: 0.5, snapToGrid: true, columns: 12, gap: 16, padding: 16, }, screenResolution: { width: 1920, height: 1080, }, }; } // ============================================ // Legacy → V2 변환 (저장 시) // ============================================ export function convertLegacyToV2(legacyLayout: LegacyLayoutData): LayoutV2 { const components: ComponentV2[] = legacyLayout.components.map((comp, index) => { // 컴포넌트 타입 결정 const componentType = comp.componentType || comp.widgetType || comp.type || "unknown"; const url = getComponentUrl(componentType); // 기본값 가져오기 const defaults = getDefaultsByUrl(url); // 현재 설정에서 차이값만 추출 const fullConfig = comp.componentConfig || {}; const overrides = extractCustomConfig(fullConfig, defaults); return { id: comp.id, url: url, position: comp.position || { x: 0, y: 0 }, size: comp.size || { width: 100, height: 100 }, displayOrder: index, overrides: overrides, }; }); return { version: "2.0", components, updatedAt: new Date().toISOString(), }; } // ============================================ // V2 레이아웃 유효성 검사 // ============================================ export function isValidV2Layout(data: any): data is LayoutV2 { return ( data && typeof data === "object" && data.version === "2.0" && Array.isArray(data.components) ); } // ============================================ // 기존 레이아웃인지 확인 // ============================================ export function isLegacyLayout(data: any): boolean { return ( data && typeof data === "object" && Array.isArray(data.components) && data.version !== "2.0" ); }