From 26365ef08588d53b8c5d9c7cfaefb244536e6743 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Mon, 24 Nov 2025 10:41:46 +0900
Subject: (김준회) 돌체 재개발 - 2차: 업로드 개선, 다운로드 오류 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
lib/dolce/dialogs/add-detail-drawing-dialog.tsx | 129 +++++++++++++++---------
1 file changed, 82 insertions(+), 47 deletions(-)
(limited to 'lib/dolce/dialogs/add-detail-drawing-dialog.tsx')
diff --git a/lib/dolce/dialogs/add-detail-drawing-dialog.tsx b/lib/dolce/dialogs/add-detail-drawing-dialog.tsx
index 290a226b..34d06368 100644
--- a/lib/dolce/dialogs/add-detail-drawing-dialog.tsx
+++ b/lib/dolce/dialogs/add-detail-drawing-dialog.tsx
@@ -1,7 +1,6 @@
"use client";
-import { useState, useCallback } from "react";
-import { useDropzone } from "react-dropzone";
+import { useState } from "react";
import {
Dialog,
DialogContent,
@@ -22,8 +21,11 @@ import {
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Upload, X, FileIcon, Info } from "lucide-react";
import { toast } from "sonner";
-import { UnifiedDwgReceiptItem, editDetailDwgReceipt, uploadFilesToDetailDrawing } from "../actions";
+import { UnifiedDwgReceiptItem, editDetailDwgReceipt } from "../actions";
import { v4 as uuidv4 } from "uuid";
+import { useFileUploadWithProgress } from "../hooks/use-file-upload-with-progress";
+import { uploadFilesWithProgress } from "../utils/upload-with-progress";
+import { FileUploadProgressList } from "../components/file-upload-progress-list";
interface AddDetailDrawingDialogProps {
open: boolean;
@@ -80,30 +82,26 @@ export function AddDetailDrawingDialog({
const [drawingUsage, setDrawingUsage] = useState("");
const [registerKind, setRegisterKind] = useState("");
const [revision, setRevision] = useState("");
- const [files, setFiles] = useState([]);
const [isSubmitting, setIsSubmitting] = useState(false);
- // 파일 드롭 핸들러
- const onDrop = useCallback((acceptedFiles: File[]) => {
- setFiles((prev) => [...prev, ...acceptedFiles]);
- }, []);
-
- const { getRootProps, getInputProps, isDragActive } = useDropzone({
- onDrop,
- multiple: true,
- });
-
- // 파일 제거
- const removeFile = (index: number) => {
- setFiles((prev) => prev.filter((_, i) => i !== index));
- };
+ // 파일 업로드 훅 사용 (진행도 추적)
+ const {
+ fileProgresses,
+ files,
+ removeFile,
+ clearFiles,
+ updateFileProgress,
+ getRootProps,
+ getInputProps,
+ isDragActive,
+ } = useFileUploadWithProgress();
// 폼 초기화
const resetForm = () => {
setDrawingUsage("");
setRegisterKind("");
setRevision("");
- setFiles([]);
+ clearFiles();
};
// 제출
@@ -169,16 +167,27 @@ export function AddDetailDrawingDialog({
if (files.length > 0) {
toast.info(`${files.length}개 파일 업로드를 진행합니다...`);
- const formData = new FormData();
- formData.append("uploadId", uploadId);
- formData.append("userId", userId);
- formData.append("fileCount", String(files.length));
-
- files.forEach((file, index) => {
- formData.append(`file_${index}`, file);
+ // 모든 파일 상태를 uploading으로 변경
+ files.forEach((_, index) => {
+ updateFileProgress(index, 0, "uploading");
});
- const uploadResult = await uploadFilesToDetailDrawing(formData);
+ const uploadResult = await uploadFilesWithProgress({
+ uploadId,
+ userId,
+ files,
+ callbacks: {
+ onProgress: (fileIndex, progress) => {
+ updateFileProgress(fileIndex, progress, "uploading");
+ },
+ onFileComplete: (fileIndex) => {
+ updateFileProgress(fileIndex, 100, "completed");
+ },
+ onFileError: (fileIndex, error) => {
+ updateFileProgress(fileIndex, 0, "error", error);
+ },
+ },
+ });
if (uploadResult.success) {
toast.success(`상세도면 추가 및 ${uploadResult.uploadedCount}개 파일 업로드 완료`);
@@ -189,8 +198,10 @@ export function AddDetailDrawingDialog({
toast.success("상세도면이 추가되었습니다");
}
+ // API 호출 성공 시 무조건 다이얼로그 닫기 (파일 업로드 성공 여부와 무관)
resetForm();
onComplete();
+ onOpenChange(false);
} else {
toast.error("상세도면 추가에 실패했습니다");
}
@@ -318,7 +329,7 @@ export function AddDetailDrawingDialog({
파일을 드래그하거나 클릭하여 선택
- 여러 파일을 한 번에 업로드할 수 있습니다
+ 여러 파일을 한 번에 업로드할 수 있습니다 (최대 1GB/파일)
@@ -337,25 +348,49 @@ export function AddDetailDrawingDialog({
{/* 선택된 파일 목록 */}
{files.length > 0 && (
- {files.map((file, index) => (
-
-
- {file.name}
-
- {(file.size / 1024).toFixed(2)} KB
-
-
-
- ))}
+ {isSubmitting ? (
+ // 업로드 중: 진행도 표시
+
+ ) : (
+ // 대기 중: 삭제 버튼 표시
+ <>
+
+
+ 선택된 파일 ({files.length}개)
+
+
+
+
+ {files.map((file, index) => (
+
+
+
+
{file.name}
+
+ {(file.size / 1024 / 1024).toFixed(2)} MB
+
+
+
+
+ ))}
+
+ >
+ )}
)}
--
cgit v1.2.3