From 18954df6565108a469fb1608ea3715dd9bb1b02d Mon Sep 17 00:00:00 2001 From: dujinkim Date: Mon, 1 Sep 2025 09:12:09 +0000 Subject: (대표님) 구매 기본계약, gtc 개발 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gtc-vendor/preview-document-dialog.tsx | 272 +++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 lib/basic-contract/gtc-vendor/preview-document-dialog.tsx (limited to 'lib/basic-contract/gtc-vendor/preview-document-dialog.tsx') diff --git a/lib/basic-contract/gtc-vendor/preview-document-dialog.tsx b/lib/basic-contract/gtc-vendor/preview-document-dialog.tsx new file mode 100644 index 00000000..78ddc7f7 --- /dev/null +++ b/lib/basic-contract/gtc-vendor/preview-document-dialog.tsx @@ -0,0 +1,272 @@ +"use client" + +import * as React from "react" +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog" +import { Button } from "@/components/ui/button" +import { Badge } from "@/components/ui/badge" +import { Separator } from "@/components/ui/separator" + +import { + Eye, + Download, + Loader2, + FileText, + RefreshCw, + Settings, + AlertCircle +} from "lucide-react" +import { toast } from "sonner" + +import { type GtcClauseTreeView } from "@/db/schema/gtc" +import { ClausePreviewViewer } from "./clause-preview-viewer" + +interface PreviewDocumentDialogProps + extends React.ComponentPropsWithRef { + clauses: GtcClauseTreeView[] + document: any + onExport?: () => void +} + +export function PreviewDocumentDialog({ + clauses, + document, + onExport, + ...props +}: PreviewDocumentDialogProps) { + const [isGenerating, setIsGenerating] = React.useState(false) + const [documentGenerated, setDocumentGenerated] = React.useState(false) + const [viewerInstance, setViewerInstance] = React.useState(null) + const [hasError, setHasError] = React.useState(false) + + // 조항 통계 계산 + const stats = React.useMemo(() => { + const activeClausesCount = clauses.filter(c => c.isActive !== false).length + const topLevelCount = clauses.filter(c => !c.parentId && c.isActive !== false).length + const hasContentCount = clauses.filter(c => c.content && c.isActive !== false).length + + return { + total: activeClausesCount, + topLevel: topLevelCount, + withContent: hasContentCount, + withoutContent: activeClausesCount - hasContentCount + } + }, [clauses]) + + const handleGeneratePreview = async () => { + setIsGenerating(true) + setHasError(false) + setDocumentGenerated(false) + + try { + // 실제로는 ClausePreviewViewer에서 문서 생성을 처리하므로 + // 여기서는 상태만 관리 + console.log("🚀 문서 미리보기 생성 시작") + + // ClausePreviewViewer가 완전히 로드될 때까지 기다림 + await new Promise(resolve => setTimeout(resolve, 2000)) + + if (!hasError) { + setDocumentGenerated(true) + toast.success("문서 미리보기가 생성되었습니다.") + } + } catch (error) { + console.error("문서 생성 중 오류:", error) + setHasError(true) + toast.error("문서 생성 중 오류가 발생했습니다.") + } finally { + setIsGenerating(false) + } + } + + const handleExportDocument = () => { + if (viewerInstance) { + try { + // PDFTron의 다운로드 기능 실행 + viewerInstance.UI.downloadPdf({ + filename: `${document?.title || 'GTC계약서'}_미리보기.pdf` + }) + toast.success("PDF 다운로드가 시작됩니다.") + } catch (error) { + console.error("다운로드 오류:", error) + toast.error("다운로드 중 오류가 발생했습니다.") + } + } else { + toast.error("뷰어가 준비되지 않았습니다.") + } + } + + const handleRegenerateDocument = () => { + console.log("🔄 문서 재생성 시작") + setDocumentGenerated(false) + setHasError(false) + handleGeneratePreview() + } + + const handleViewerSuccess = React.useCallback(() => { + setDocumentGenerated(true) + setIsGenerating(false) + setHasError(false) + }, []) + + const handleViewerError = React.useCallback(() => { + setHasError(true) + setIsGenerating(false) + setDocumentGenerated(false) + }, []) + + // 다이얼로그가 열릴 때 자동으로 미리보기 생성 + React.useEffect(() => { + if (props.open && !documentGenerated && !isGenerating && !hasError) { + const timer = setTimeout(() => { + handleGeneratePreview() + }, 300) // 다이얼로그 애니메이션 후 시작 + + return () => clearTimeout(timer) + } + }, [props.open, documentGenerated, isGenerating, hasError]) + + // 다이얼로그가 닫힐 때 상태 초기화 + React.useEffect(() => { + if (!props.open) { + setDocumentGenerated(false) + setIsGenerating(false) + setHasError(false) + setViewerInstance(null) + } + }, [props.open]) + + return ( + + + + + + 문서 미리보기 + + + 현재 조항들을 기반으로 생성된 문서를 미리보기합니다. + + + + {/* 문서 정보 및 통계 */} +
+
+
+ + {document?.title || 'GTC 계약서'} + {stats.total}개 조항 + {hasError && ( + + + 오류 발생 + + )} +
+
+ {documentGenerated && !hasError && ( + <> + + {/* */} + + )} + {hasError && ( + + )} +
+
+ +
+
+
{stats.total}
+
총 조항
+
+
+
{stats.topLevel}
+
최상위 조항
+
+
+
{stats.withContent}
+
내용 있음
+
+
+
{stats.withoutContent}
+
제목만
+
+
+
+ + + + {/* PDFTron 뷰어 영역 */} +
+ {isGenerating ? ( +
+ +

문서 생성 중...

+

+ {stats.total}개의 조항을 배치하고 있습니다. +

+

+ 초기화에 시간이 걸릴 수 있습니다... +

+
+ ) : hasError ? ( +
+ +

문서 생성 실패

+

+ 문서 생성 중 오류가 발생했습니다. 네트워크 연결이나 파일 권한을 확인해주세요. +

+ +
+ ) : documentGenerated ? ( + + ) : ( +
+ +

문서 미리보기 준비 중

+ +
+ )} +
+
+
+ ) +} \ No newline at end of file -- cgit v1.2.3