From 10f90dc68dec42e9a64e081cc0dce6a484447290 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Tue, 29 Jul 2025 11:48:59 +0000
Subject: (대표님, 박서영, 최겸) document-list-only, gtc, vendorDocu,
 docu-list-rule
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../gtc-clauses/table/preview-document-dialog.tsx  | 115 ++++++++++++++++++---
 1 file changed, 99 insertions(+), 16 deletions(-)

(limited to 'lib/gtc-contract/gtc-clauses/table/preview-document-dialog.tsx')

diff --git a/lib/gtc-contract/gtc-clauses/table/preview-document-dialog.tsx b/lib/gtc-contract/gtc-clauses/table/preview-document-dialog.tsx
index 29ab1b5a..3639c0f3 100644
--- a/lib/gtc-contract/gtc-clauses/table/preview-document-dialog.tsx
+++ b/lib/gtc-contract/gtc-clauses/table/preview-document-dialog.tsx
@@ -12,7 +12,8 @@ import {
   Loader2, 
   FileText, 
   RefreshCw,
-  Settings 
+  Settings,
+  AlertCircle
 } from "lucide-react"
 import { toast } from "sonner"
 
@@ -35,6 +36,7 @@ export function PreviewDocumentDialog({
   const [isGenerating, setIsGenerating] = React.useState(false)
   const [documentGenerated, setDocumentGenerated] = React.useState(false)
   const [viewerInstance, setViewerInstance] = React.useState<any>(null)
+  const [hasError, setHasError] = React.useState(false)
 
   // 조항 통계 계산
   const stats = React.useMemo(() => {
@@ -52,38 +54,84 @@ export function PreviewDocumentDialog({
 
   const handleGeneratePreview = async () => {
     setIsGenerating(true)
+    setHasError(false)
+    setDocumentGenerated(false)
+    
     try {
-      // 잠시 후 문서 생성 완료로 설정 (실제로는 뷰어에서 처리)
-      setTimeout(() => {
+      // 실제로는 ClausePreviewViewer에서 문서 생성을 처리하므로
+      // 여기서는 상태만 관리
+      console.log("🚀 문서 미리보기 생성 시작")
+      
+      // ClausePreviewViewer가 완전히 로드될 때까지 기다림
+      await new Promise(resolve => setTimeout(resolve, 2000))
+      
+      if (!hasError) {
         setDocumentGenerated(true)
-        setIsGenerating(false)
         toast.success("문서 미리보기가 생성되었습니다.")
-      }, 1500)
+      }
     } catch (error) {
-      setIsGenerating(false)
+      console.error("문서 생성 중 오류:", error)
+      setHasError(true)
       toast.error("문서 생성 중 오류가 발생했습니다.")
+    } finally {
+      setIsGenerating(false)
     }
   }
 
   const handleExportDocument = () => {
     if (viewerInstance) {
-      // PDFTron의 다운로드 기능 실행
-      viewerInstance.UI.downloadPdf({
-        filename: `${document?.title || 'GTC계약서'}_미리보기.pdf`
-      })
-      toast.success("문서가 다운로드됩니다.")
+      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 && !documentGenerated && !isGenerating) {
-      handleGeneratePreview()
+    if (!props.open) {
+      setDocumentGenerated(false)
+      setIsGenerating(false)
+      setHasError(false)
+      setViewerInstance(null)
     }
   }, [props.open])
 
@@ -107,9 +155,15 @@ export function PreviewDocumentDialog({
               <FileText className="h-4 w-4" />
               <span className="font-medium">{document?.title || 'GTC 계약서'}</span>
               <Badge variant="outline">{stats.total}개 조항</Badge>
+              {hasError && (
+                <Badge variant="destructive" className="gap-1">
+                  <AlertCircle className="h-3 w-3" />
+                  오류 발생
+                </Badge>
+              )}
             </div>
             <div className="flex items-center gap-2">
-              {documentGenerated && (
+              {documentGenerated && !hasError && (
                 <>
                   <Button
                     variant="outline"
@@ -117,19 +171,31 @@ export function PreviewDocumentDialog({
                     onClick={handleRegenerateDocument}
                     disabled={isGenerating}
                   >
-                    <RefreshCw className="mr-2 h-3 w-3" />
+                    <RefreshCw className={`mr-2 h-3 w-3 ${isGenerating ? 'animate-spin' : ''}`} />
                     재생성
                   </Button>
                   <Button
                     variant="outline"
                     size="sm"
                     onClick={handleExportDocument}
+                    disabled={!viewerInstance}
                   >
                     <Download className="mr-2 h-3 w-3" />
                     PDF 다운로드
                   </Button>
                 </>
               )}
+              {hasError && (
+                <Button
+                  variant="default"
+                  size="sm"
+                  onClick={handleRegenerateDocument}
+                  disabled={isGenerating}
+                >
+                  <RefreshCw className={`mr-2 h-3 w-3 ${isGenerating ? 'animate-spin' : ''}`} />
+                  다시 시도
+                </Button>
+              )}
             </div>
           </div>
 
@@ -164,6 +230,21 @@ export function PreviewDocumentDialog({
               <p className="text-sm text-muted-foreground">
                 {stats.total}개의 조항을 배치하고 있습니다.
               </p>
+              <p className="text-xs text-gray-400 mt-2">
+                초기화에 시간이 걸릴 수 있습니다...
+              </p>
+            </div>
+          ) : hasError ? (
+            <div className="absolute inset-0 flex flex-col items-center justify-center bg-muted/10">
+              <AlertCircle className="h-12 w-12 text-destructive mb-4" />
+              <p className="text-lg font-medium mb-2 text-destructive">문서 생성 실패</p>
+              <p className="text-sm text-muted-foreground mb-4 text-center max-w-md">
+                문서 생성 중 오류가 발생했습니다. 네트워크 연결이나 파일 권한을 확인해주세요.
+              </p>
+              <Button onClick={handleRegenerateDocument} disabled={isGenerating}>
+                <RefreshCw className="mr-2 h-4 w-4" />
+                다시 시도
+              </Button>
             </div>
           ) : documentGenerated ? (
             <ClausePreviewViewer
@@ -171,6 +252,8 @@ export function PreviewDocumentDialog({
               document={document}
               instance={viewerInstance}
               setInstance={setViewerInstance}
+              onSuccess={handleViewerSuccess}
+              onError={handleViewerError}
             />
           ) : (
             <div className="absolute inset-0 flex flex-col items-center justify-center bg-muted/10">
-- 
cgit v1.2.3

