From 8547034e6d82e4d1184f35af2dbff67180d89dc8 Mon Sep 17 00:00:00 2001 From: joonhoekim <26rote@gmail.com> Date: Wed, 26 Nov 2025 18:09:18 +0900 Subject: (김준회) dolce: 동기화 기능 추가, 로컬 다운로드, 삭제 추가, 동기화 dialog 개선 등 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dialogs/upload-files-to-detail-dialog-v2.tsx | 247 +++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 lib/dolce-v2/dialogs/upload-files-to-detail-dialog-v2.tsx (limited to 'lib/dolce-v2/dialogs/upload-files-to-detail-dialog-v2.tsx') diff --git a/lib/dolce-v2/dialogs/upload-files-to-detail-dialog-v2.tsx b/lib/dolce-v2/dialogs/upload-files-to-detail-dialog-v2.tsx new file mode 100644 index 00000000..c59f6d78 --- /dev/null +++ b/lib/dolce-v2/dialogs/upload-files-to-detail-dialog-v2.tsx @@ -0,0 +1,247 @@ +"use client"; + +import * as React from "react"; +import { useState } from "react"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { Button } from "@/components/ui/button"; +import { Alert, AlertDescription } from "@/components/ui/alert"; +import { Upload, FolderOpen, Loader2, X, FileText, AlertCircle } from "lucide-react"; +import { toast } from "sonner"; +import { useTranslation } from "@/i18n/client"; +import { useFileUploadWithProgress } from "@/lib/dolce/hooks/use-file-upload-with-progress"; +import { uploadFilesToDetailDrawingV2 } from "@/lib/dolce-v2/actions"; + +interface UploadFilesToDetailDialogV2Props { + open: boolean; + onOpenChange: (open: boolean) => void; + uploadId: string; + drawingNo: string; + revNo: string; + // [추가] 메타데이터 저장을 위한 추가 정보 + drawingName?: string; + discipline?: string; + registerKind?: string; + + userId: string; + projectNo?: string; // V2에서는 projectNo 필요 (Sync List 조회 인덱스용) + vendorCode?: string; // V2: 동기화 필터링용 + onUploadComplete?: () => void; + lng: string; +} + +export function UploadFilesToDetailDialogV2({ + open, + onOpenChange, + uploadId, + drawingNo, + revNo, + drawingName, + discipline, + registerKind, + userId, + projectNo, + vendorCode, + onUploadComplete, + lng, +}: UploadFilesToDetailDialogV2Props) { + const { t } = useTranslation(lng, "dolce"); + const [isUploading, setIsUploading] = useState(false); + + // 파일 업로드 훅 사용 (UI용) + const { + files: selectedFiles, + removeFile, + clearFiles, + getRootProps, + getInputProps, + isDragActive, + } = useFileUploadWithProgress(); + + // 다이얼로그 닫을 때 초기화 + React.useEffect(() => { + if (!open) { + clearFiles(); + } + }, [open, clearFiles]); + + // 업로드 처리 + const handleUpload = async () => { + if (selectedFiles.length === 0) { + toast.error(t("uploadFilesDialog.selectFilesError")); + return; + } + + setIsUploading(true); + + try { + const formData = new FormData(); + formData.append("uploadId", uploadId); + formData.append("userId", userId); + formData.append("fileCount", String(selectedFiles.length)); + if (projectNo) formData.append("projectNo", projectNo); + if (vendorCode) formData.append("vendorCode", vendorCode); + + // 메타데이터 추가 + formData.append("drawingNo", drawingNo); + formData.append("revNo", revNo); + if (drawingName) formData.append("drawingName", drawingName); + if (discipline) formData.append("discipline", discipline); + if (registerKind) formData.append("registerKind", registerKind); + + selectedFiles.forEach((file, index) => { + formData.append(`file_${index}`, file); + }); + + const result = await uploadFilesToDetailDrawingV2(formData); + + if (result.success) { + toast.success(t("uploadFilesDialog.uploadSuccess", { count: selectedFiles.length })); + onOpenChange(false); + onUploadComplete?.(); + } else { + toast.error(result.error || t("uploadFilesDialog.uploadError")); + } + } catch (error) { + console.error("업로드 실패:", error); + toast.error( + error instanceof Error ? error.message : t("uploadFilesDialog.uploadErrorMessage") + ); + } finally { + setIsUploading(false); + } + }; + + return ( + + + + {t("uploadFilesDialog.title")} + + {t("uploadFilesDialog.description", { drawingNo, revNo })} + + + +
+ {/* 안내 메시지 */} + + + + {t("uploadFilesDialog.alertMessage")} + + + + {/* 파일 선택 영역 */} +
+ +
+ +

+ {isDragActive + ? t("uploadFilesDialog.dropHereText") + : t("uploadFilesDialog.dragDropText")} +

+

+ {t("uploadFilesDialog.fileInfo")} +

+
+
+ + {/* 선택된 파일 목록 */} + {selectedFiles.length > 0 && ( +
+ <> +
+

+ {t("uploadFilesDialog.selectedFiles", { count: selectedFiles.length })} +

+ +
+
+ {selectedFiles.map((file, index) => ( +
+
+ +
+

{file.name}

+

+ {(file.size / 1024 / 1024).toFixed(2)} MB +

+
+
+ +
+ ))} +
+ +
+ )} +
+ + + + + +
+
+ ); +} -- cgit v1.2.3