diff options
Diffstat (limited to 'lib/gtc-contract/gtc-clauses/table/preview-document-dialog.tsx')
| -rw-r--r-- | lib/gtc-contract/gtc-clauses/table/preview-document-dialog.tsx | 115 |
1 files changed, 99 insertions, 16 deletions
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"> |
