157 lines
4.5 KiB
TypeScript
157 lines
4.5 KiB
TypeScript
"use client";
|
|
|
|
/**
|
|
* ComponentPreviewPanel.tsx — 범용 컴포넌트 미리보기 패널
|
|
*
|
|
* 모든 컴포넌트 타입의 미리보기를 통일된 레이아웃(회색 그리드 + 가운데 배치)으로 제공.
|
|
* 카드/테이블 전용 패널을 대체하는 단일 진입점.
|
|
*/
|
|
|
|
import React, { useCallback, useMemo } from "react";
|
|
import { Eye } from "lucide-react";
|
|
import type { ComponentConfig } from "@/types/report";
|
|
import type { QueryResult } from "../renderers/types";
|
|
|
|
import { TextRenderer } from "../renderers/TextRenderer";
|
|
import { ImageRenderer } from "../renderers/ImageRenderer";
|
|
import { DividerRenderer } from "../renderers/DividerRenderer";
|
|
import { SignatureRenderer, StampRenderer } from "../renderers/SignatureRenderer";
|
|
import { PageNumberRenderer } from "../renderers/PageNumberRenderer";
|
|
import { CardRenderer } from "../renderers/CardRenderer";
|
|
import { CalculationRenderer } from "../renderers/CalculationRenderer";
|
|
import { BarcodeCanvasRenderer } from "../renderers/BarcodeCanvasRenderer";
|
|
import { CheckboxRenderer } from "../renderers/CheckboxRenderer";
|
|
import { TableRenderer } from "../renderers/TableRenderer";
|
|
|
|
interface ComponentPreviewPanelProps {
|
|
component: ComponentConfig;
|
|
}
|
|
|
|
const DUMMY_LAYOUT_CONFIG = {
|
|
pages: [{ page_id: "preview_page", page_order: 1 }],
|
|
};
|
|
|
|
export function ComponentPreviewPanel({ component }: ComponentPreviewPanelProps) {
|
|
const dummyGetQueryResult = useCallback(
|
|
(): QueryResult | null => null,
|
|
[],
|
|
);
|
|
|
|
const previewWidth = useMemo(
|
|
() => Math.min(component.width || 700, 700),
|
|
[component.width],
|
|
);
|
|
|
|
const previewHeight = useMemo(
|
|
() => Math.min(component.height || 400, 550),
|
|
[component.height],
|
|
);
|
|
|
|
const renderContent = () => {
|
|
switch (component.type) {
|
|
case "text":
|
|
case "label":
|
|
return (
|
|
<TextRenderer
|
|
component={component}
|
|
getQueryResult={dummyGetQueryResult}
|
|
displayValue={component.content || component.text || "텍스트 미리보기"}
|
|
/>
|
|
);
|
|
|
|
case "image":
|
|
return <ImageRenderer component={component} />;
|
|
|
|
case "divider":
|
|
return <DividerRenderer component={component} />;
|
|
|
|
case "signature":
|
|
return <SignatureRenderer component={component} />;
|
|
|
|
case "stamp":
|
|
return <StampRenderer component={component} />;
|
|
|
|
case "pageNumber":
|
|
return (
|
|
<PageNumberRenderer
|
|
component={component}
|
|
currentPageId="preview_page"
|
|
layoutConfig={DUMMY_LAYOUT_CONFIG}
|
|
/>
|
|
);
|
|
|
|
case "card":
|
|
return (
|
|
<CardRenderer
|
|
component={component}
|
|
getQueryResult={dummyGetQueryResult}
|
|
/>
|
|
);
|
|
|
|
case "table":
|
|
return (
|
|
<TableRenderer
|
|
component={component}
|
|
getQueryResult={dummyGetQueryResult}
|
|
/>
|
|
);
|
|
|
|
case "calculation":
|
|
return (
|
|
<CalculationRenderer
|
|
component={component}
|
|
getQueryResult={dummyGetQueryResult}
|
|
/>
|
|
);
|
|
|
|
case "barcode":
|
|
return (
|
|
<BarcodeCanvasRenderer
|
|
component={component}
|
|
getQueryResult={dummyGetQueryResult}
|
|
/>
|
|
);
|
|
|
|
case "checkbox":
|
|
return (
|
|
<CheckboxRenderer
|
|
component={component}
|
|
getQueryResult={dummyGetQueryResult}
|
|
/>
|
|
);
|
|
|
|
default:
|
|
return (
|
|
<div className="flex h-full w-full items-center justify-center text-sm text-gray-400">
|
|
미리보기를 지원하지 않는 컴포넌트입니다.
|
|
</div>
|
|
);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="flex shrink-0 flex-col items-center gap-4 p-5">
|
|
<div className="w-full">
|
|
<div className="mb-1 flex items-center gap-2 text-sm font-semibold text-gray-700">
|
|
<Eye className="h-4 w-4 text-blue-600" />
|
|
미리보기 (저장 전 상태)
|
|
</div>
|
|
<p className="text-xs text-muted-foreground">
|
|
실제 데이터는 저장 후 확인 가능합니다.
|
|
</p>
|
|
</div>
|
|
<div className="flex min-h-[600px] w-full items-center justify-center overflow-auto rounded-xl border border-gray-200 bg-gray-100 p-8">
|
|
<div
|
|
className="overflow-hidden rounded-lg border border-gray-300 bg-white shadow-sm"
|
|
style={{
|
|
width: previewWidth,
|
|
minHeight: previewHeight,
|
|
}}
|
|
>
|
|
{renderContent()}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|