ERP-node/frontend/lib/registry/DynamicLayoutRenderer.tsx

111 lines
3.4 KiB
TypeScript

"use client";
import React from "react";
import { LayoutComponent, ComponentData } from "@/types/screen";
import { LayoutRegistry } from "./LayoutRegistry";
export interface DynamicLayoutRendererProps {
layout: LayoutComponent;
allComponents: ComponentData[];
isDesignMode?: boolean;
isSelected?: boolean;
onClick?: (e: React.MouseEvent) => void;
onZoneClick?: (zoneId: string, e: React.MouseEvent) => void;
onComponentDrop?: (zoneId: string, component: ComponentData, e: React.DragEvent) => void;
onDragStart?: (e: React.DragEvent) => void;
onDragEnd?: (e: React.DragEvent) => void;
onUpdateLayout?: (updatedLayout: LayoutComponent) => void; // 레이아웃 업데이트 콜백
className?: string;
style?: React.CSSProperties;
}
export const DynamicLayoutRenderer: React.FC<DynamicLayoutRendererProps> = ({
layout,
allComponents,
isDesignMode = false,
isSelected = false,
onClick,
onZoneClick,
onComponentDrop,
onDragStart,
onDragEnd,
onUpdateLayout,
className,
style,
...restProps
}) => {
console.log("🎯 DynamicLayoutRenderer:", {
layoutId: layout.id,
layoutType: layout.layoutType,
zonesCount: layout.zones.length,
allComponentsCount: allComponents.length,
isDesignMode,
isSelected,
});
// 레지스트리에서 레이아웃 정의 조회
const layoutDefinition = LayoutRegistry.getLayout(layout.layoutType);
if (!layoutDefinition) {
console.warn(`⚠️ 등록되지 않은 레이아웃 타입: ${layout.layoutType}`);
// 폴백 렌더링 - 기본 플레이스홀더
return (
<div
className={`flex h-full w-full items-center justify-center rounded border-2 border-dashed border-gray-300 bg-gray-50 p-4 ${className || ""}`}
style={style}
onClick={onClick}
>
<div className="text-center">
<div className="mb-2 text-sm font-medium text-gray-600">{layout.label || `레이아웃 ${layout.id}`}</div>
<div className="text-xs text-gray-400"> : {layout.layoutType}</div>
</div>
</div>
);
}
// 레이아웃 컴포넌트 가져오기
const LayoutComponent = layoutDefinition.component;
// 레이아웃 렌더링 실행
try {
return (
<LayoutComponent
layout={layout}
allComponents={allComponents}
isDesignMode={isDesignMode}
isSelected={isSelected}
onClick={onClick}
onZoneClick={onZoneClick}
onComponentDrop={onComponentDrop}
onDragStart={onDragStart}
onDragEnd={onDragEnd}
onUpdateLayout={onUpdateLayout}
className={className}
style={style}
{...restProps}
/>
);
} catch (error) {
console.error(`❌ 레이아웃 렌더링 실패 (${layout.layoutType}):`, error);
// 오류 발생 시 폴백 렌더링
return (
<div
className={`flex h-full w-full items-center justify-center rounded border-2 border-red-300 bg-red-50 p-4 ${className || ""}`}
style={style}
onClick={onClick}
>
<div className="text-center">
<div className="mb-2 text-sm font-medium text-red-600"> </div>
<div className="text-xs text-red-400">
{layout.layoutType}: {error instanceof Error ? error.message : "알 수 없는 오류"}
</div>
</div>
</div>
);
}
};
export default DynamicLayoutRenderer;