"use client"; import React from "react"; import { ComponentData, WebType, WidgetComponent } from "@/types/screen"; import { DynamicComponentRenderer } from "@/lib/registry/DynamicComponentRenderer"; import { Database, Type, Hash, List, AlignLeft, CheckSquare, Radio, Calendar, Code, Building, File, } from "lucide-react"; // 컴포넌트 렌더러들 자동 등록 import "@/lib/registry/components"; interface RealtimePreviewProps { component: ComponentData; isSelected?: boolean; isDesignMode?: boolean; // 편집 모드 여부 onClick?: (e?: React.MouseEvent) => void; onDragStart?: (e: React.DragEvent) => void; onDragEnd?: () => void; onGroupToggle?: (groupId: string) => void; // 그룹 접기/펼치기 children?: React.ReactNode; // 그룹 내 자식 컴포넌트들 selectedScreen?: any; onZoneComponentDrop?: (e: React.DragEvent, zoneId: string, layoutId: string) => void; // 존별 드롭 핸들러 onZoneClick?: (zoneId: string) => void; // 존 클릭 핸들러 onConfigChange?: (config: any) => void; // 설정 변경 핸들러 } // 동적 위젯 타입 아이콘 (레지스트리에서 조회) const getWidgetIcon = (widgetType: WebType | undefined): React.ReactNode => { if (!widgetType) return ; const iconMap: Record = { text: Aa, number: , decimal: , date: , datetime: , select: , dropdown: , textarea: , boolean: , checkbox: , radio: , code: , entity: , file: , email: @, tel: , button: BTN, }; return iconMap[widgetType] || ; }; export const RealtimePreviewDynamic: React.FC = ({ component, isSelected = false, isDesignMode = true, // 기본값은 편집 모드 onClick, onDragStart, onDragEnd, onGroupToggle, children, selectedScreen, onZoneComponentDrop, onZoneClick, onConfigChange, }) => { const { id, type, position, size, style: componentStyle } = component; // 선택 상태에 따른 스타일 (z-index 낮춤 - 패널과 모달보다 아래) const selectionStyle = isSelected ? { outline: "2px solid #3b82f6", outlineOffset: "2px", zIndex: 30, // 패널(z-50)과 모달(z-50)보다 낮게 설정 } : {}; // 컴포넌트 기본 스타일 - 레이아웃은 항상 맨 아래 const baseStyle = { left: `${position.x}px`, top: `${position.y}px`, width: component.componentConfig?.type === "table-list" ? `${Math.max(size?.width || 400, 400)}px` // table-list는 최소 400px : `${size?.width || 100}px`, height: component.componentConfig?.type === "table-list" ? `${Math.max(size?.height || 300, 300)}px` // table-list는 최소 300px : `${size?.height || 36}px`, zIndex: component.type === "layout" ? 1 : position.z || 2, // 레이아웃은 z-index 1, 다른 컴포넌트는 2 이상 ...componentStyle, }; const handleClick = (e: React.MouseEvent) => { e.stopPropagation(); onClick?.(e); }; const handleDragStart = (e: React.DragEvent) => { e.stopPropagation(); onDragStart?.(e); }; const handleDragEnd = () => { onDragEnd?.(); }; return (
{/* 동적 컴포넌트 렌더링 */}
{/* 선택된 컴포넌트 정보 표시 */} {isSelected && (
{type === "widget" && (
{getWidgetIcon((component as WidgetComponent).widgetType)} {(component as WidgetComponent).widgetType || "widget"}
)} {type !== "widget" && (
{component.componentConfig?.type || type}
)}
)}
); }; // 기존 RealtimePreview와의 호환성을 위한 export export { RealtimePreviewDynamic as RealtimePreview }; export default RealtimePreviewDynamic;