"use client";
import React from "react";
import { ComponentData, WebType } from "@/types/screen";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
// import { Checkbox } from "@/components/ui/checkbox";
// import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import {
Database,
Type,
Hash,
List,
AlignLeft,
CheckSquare,
Radio,
Calendar,
Code,
Building,
File,
Group,
ChevronDown,
ChevronRight,
} from "lucide-react";
interface RealtimePreviewProps {
component: ComponentData;
isSelected?: boolean;
onClick?: (e?: React.MouseEvent) => void;
onDragStart?: (e: React.DragEvent) => void;
onDragEnd?: () => void;
onGroupToggle?: (groupId: string) => void; // 그룹 접기/펼치기
children?: React.ReactNode; // 그룹 내 자식 컴포넌트들
}
// 웹 타입에 따른 위젯 렌더링
const renderWidget = (component: ComponentData) => {
const { widgetType, label, placeholder, required, readonly, columnName, style } = component;
// 디버깅: 실제 widgetType 값 확인
console.log("RealtimePreview - widgetType:", widgetType, "columnName:", columnName);
// 사용자가 테두리를 설정했는지 확인
const hasCustomBorder = style && (style.borderWidth || style.borderStyle || style.borderColor || style.border);
// 기본 테두리 제거 여부 결정 - Shadcn UI 기본 border 클래스를 덮어쓰기
const borderClass = hasCustomBorder ? "!border-0" : "";
const commonProps = {
placeholder: placeholder || `입력하세요...`,
disabled: readonly,
required: required,
className: `w-full h-full ${borderClass}`,
};
switch (widgetType) {
case "text":
case "email":
case "tel":
return ;
case "number":
case "decimal":
return ;
case "date":
case "datetime":
return ;
case "select":
case "dropdown":
return (
);
case "textarea":
case "text_area":
return ;
case "boolean":
case "checkbox":
return (
);
case "radio":
return (
);
case "code":
return (
);
case "entity":
return (
);
case "file":
return (
);
default:
return ;
}
};
// 위젯 타입 아이콘
const getWidgetIcon = (widgetType: WebType | undefined) => {
switch (widgetType) {
case "text":
case "email":
case "tel":
return ;
case "number":
case "decimal":
return ;
case "date":
case "datetime":
return ;
case "select":
case "dropdown":
return
;
case "textarea":
case "text_area":
return ;
case "boolean":
case "checkbox":
return ;
case "radio":
return ;
case "code":
return ;
case "entity":
return ;
case "file":
return ;
default:
return ;
}
};
export const RealtimePreview: React.FC = ({
component,
isSelected = false,
onClick,
onDragStart,
onDragEnd,
children,
onGroupToggle,
}) => {
const { type, label, tableName, columnName, widgetType, size, style } = component;
// 사용자가 테두리를 설정했는지 확인
const hasCustomBorder = style && (style.borderWidth || style.borderStyle || style.borderColor || style.border);
// 기본 선택 테두리는 사용자 테두리가 없을 때만 적용
const defaultRingClass = hasCustomBorder
? ""
: isSelected
? "ring-opacity-50 ring-2 ring-blue-500"
: "hover:ring-opacity-50 hover:ring-1 hover:ring-gray-300";
// 사용자 테두리가 있을 때 선택 상태 표시를 위한 스타일
const selectionStyle =
hasCustomBorder && isSelected
? {
boxShadow: "0 0 0 2px rgba(59, 130, 246, 0.5)", // 외부 그림자로 선택 표시
...style,
}
: style;
// 라벨 스타일 계산
const shouldShowLabel = component.style?.labelDisplay !== false && (component.label || component.style?.labelText);
const labelText = component.style?.labelText || component.label || "";
// 라벨 하단 여백 값 추출 (px 단위 숫자로 변환)
const labelMarginBottomValue = parseInt(component.style?.labelMarginBottom || "4px", 10);
const labelStyle: React.CSSProperties = {
fontSize: component.style?.labelFontSize || "12px",
color: component.style?.labelColor || "#374151",
fontWeight: component.style?.labelFontWeight || "500",
fontFamily: component.style?.labelFontFamily || "inherit",
textAlign: component.style?.labelTextAlign || "left",
backgroundColor: component.style?.labelBackgroundColor || "transparent",
padding: component.style?.labelPadding || "0",
borderRadius: component.style?.labelBorderRadius || "0",
};
return (
{
e.stopPropagation();
onClick?.(e);
}}
draggable
onDragStart={onDragStart}
onDragEnd={onDragEnd}
onMouseDown={(e) => {
// 드래그 시작을 위한 마우스 다운 이벤트
e.stopPropagation();
}}
>
{/* 라벨 표시 */}
{shouldShowLabel && (
{labelText}
{component.required && *}
)}
{/* 컴포넌트 내용 */}
{type === "container" && (
)}
{type === "group" && (
{/* 그룹 박스/헤더 제거: 투명 컨테이너 */}
{children}
)}
{type === "widget" && (
{/* 위젯 본체 - 실제 웹 위젯처럼 보이도록 */}
{renderWidget(component)}
)}
);
};
export default RealtimePreview;