"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 "../hooks/use-file-upload-with-progress"; import { uploadFilesWithProgress, type UploadResult } from "../utils/upload-with-progress"; import { FileUploadProgressList } from "../components/file-upload-progress-list"; interface UploadFilesToDetailDialogProps { open: boolean; onOpenChange: (open: boolean) => void; uploadId: string; drawingNo: string; revNo: string; userId: string; onUploadComplete?: () => void; lng: string; } export function UploadFilesToDetailDialog({ open, onOpenChange, uploadId, drawingNo, revNo, userId, onUploadComplete, lng, }: UploadFilesToDetailDialogProps) { const { t } = useTranslation(lng, "dolce"); const [isUploading, setIsUploading] = useState(false); // 파일 업로드 훅 사용 (진행도 추적) const { fileProgresses, files: selectedFiles, removeFile, clearFiles, updateFileProgress, 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 { // 모든 파일 상태를 uploading으로 변경 selectedFiles.forEach((_, index) => { updateFileProgress(index, 0, "uploading"); }); // 진행도 추적 업로드 호출 const result: UploadResult = await uploadFilesWithProgress({ uploadId, userId, files: selectedFiles, callbacks: { onProgress: (fileIndex, progress) => { updateFileProgress(fileIndex, progress, "uploading"); }, onFileComplete: (fileIndex) => { updateFileProgress(fileIndex, 100, "completed"); }, onFileError: (fileIndex, error) => { updateFileProgress(fileIndex, 0, "error", error); }, }, }); if (result.success) { toast.success(t("uploadFilesDialog.uploadSuccess", { count: result.uploadedCount })); 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 && (
{isUploading ? ( // 업로드 중: 진행도 표시 ) : ( // 대기 중: 삭제 버튼 표시 <>

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

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

{file.name}

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

))}
)}
)}
); }