From cc2c3def63f47063d4fa8b01f9f61eafdd52805c Mon Sep 17 00:00:00 2001 From: rlaks5757 Date: Tue, 1 Apr 2025 11:58:20 +0900 Subject: template-upload-dialog component 세분화 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form-data/form-data-report-temp-upload-tab.tsx | 225 +++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 components/form-data/form-data-report-temp-upload-tab.tsx (limited to 'components/form-data/form-data-report-temp-upload-tab.tsx') diff --git a/components/form-data/form-data-report-temp-upload-tab.tsx b/components/form-data/form-data-report-temp-upload-tab.tsx new file mode 100644 index 00000000..c09ade28 --- /dev/null +++ b/components/form-data/form-data-report-temp-upload-tab.tsx @@ -0,0 +1,225 @@ +"use client"; + +import React, { FC, useState } from "react"; +import { useToast } from "@/hooks/use-toast"; +import prettyBytes from "pretty-bytes"; +import { X, Loader2 } from "lucide-react"; +import { Badge } from "@/components/ui/badge"; +import { DialogFooter } from "@/components/ui/dialog"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { Label } from "@/components/ui/label"; +import { Button } from "@/components/ui/button"; +import { + Dropzone, + DropzoneDescription, + DropzoneInput, + DropzoneTitle, + DropzoneUploadIcon, + DropzoneZone, +} from "@/components/ui/dropzone"; +import { + FileList, + FileListAction, + FileListDescription, + FileListHeader, + FileListIcon, + FileListInfo, + FileListItem, + FileListName, +} from "@/components/ui/file-list"; +import { uploadReportTemp } from "@/lib/forms/services"; + +// 최대 파일 크기 설정 (3000MB) +const MAX_FILE_SIZE = 3000000; + +interface FormDataReportTempUploadTabProps { + packageId: number; + formId: number; + uploaderType: string; +} + +export const FormDataReportTempUploadTab: FC< + FormDataReportTempUploadTabProps +> = ({ packageId, formId, uploaderType }) => { + const { toast } = useToast(); + const [selectedFiles, setSelectedFiles] = useState([]); + const [isUploading, setIsUploading] = useState(false); + const [uploadProgress, setUploadProgress] = useState(0); + + // 드롭존 - 파일 드랍 처리 + const handleDropAccepted = (acceptedFiles: File[]) => { + const newFiles = [...selectedFiles, ...acceptedFiles]; + setSelectedFiles(newFiles); + }; + + // 드롭존 - 파일 거부(에러) 처리 + const handleDropRejected = (fileRejections: any[]) => { + fileRejections.forEach((rejection) => { + toast({ + variant: "destructive", + title: "File Error", + description: `${rejection.file.name}: ${ + rejection.errors[0]?.message || "Upload failed" + }`, + }); + }); + }; + + // 파일 제거 핸들러 + const removeFile = (index: number) => { + const updatedFiles = [...selectedFiles]; + updatedFiles.splice(index, 1); + setSelectedFiles(updatedFiles); + }; + + const submitData = async () => { + setIsUploading(true); + setUploadProgress(0); + try { + const totalFiles = selectedFiles.length; + let successCount = 0; + + for (let i = 0; i < totalFiles; i++) { + const file = selectedFiles[i]; + + const formData = new FormData(); + formData.append("file", file); + formData.append("customFileName", file.name); + formData.append("uploaderType", uploaderType); + + await uploadReportTemp(packageId, formId, formData); + + successCount++; + setUploadProgress(Math.round((successCount / totalFiles) * 100)); + } + } catch (err) { + console.error(err); + toast({ + title: "Error", + description: "파일 업로드 중 오류가 발생했습니다.", + variant: "destructive", + }); + } finally { + setIsUploading(false); + setUploadProgress(0); + } + }; + + return ( + <> +
+ + + {({ maxSize }) => ( + <> + + +
+ +
+ 파일을 여기에 드롭하세요 + + 또는 클릭하여 파일을 선택하세요. 최대 크기:{" "} + {maxSize ? prettyBytes(maxSize) : "무제한"} + +
+
+
+ + + )} +
+
+ + {selectedFiles.length > 0 && ( +
+
+
+ 선택된 파일 ({selectedFiles.length}) +
+ {selectedFiles.length}개 파일 +
+ + + +
+ )} + + {isUploading && } + + + + + ); +}; + +interface UploadFileItemProps { + selectedFiles: File[]; + removeFile: (index: number) => void; + isUploading: boolean; +} + +const UploadFileItem: FC = ({ + selectedFiles, + removeFile, + isUploading, +}) => { + return ( + + {selectedFiles.map((file, index) => ( + + + + + {file.name} + + {prettyBytes(file.size)} + + + removeFile(index)} + disabled={isUploading} + > + + Remove + + + + ))} + + ); +}; + +const UploadProgressBox: FC<{ uploadProgress: number }> = ({ + uploadProgress, +}) => { + return ( +
+
+ + {uploadProgress}% 업로드 중... +
+
+
+
+
+ ); +}; -- cgit v1.2.3 From d8a70fa8802ad066fee68aca54df7fa41461a841 Mon Sep 17 00:00:00 2001 From: rlaks5757 Date: Wed, 2 Apr 2025 11:53:44 +0900 Subject: sample_temp_download_icon, var_list_download_icon 변경 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form-data/form-data-report-temp-upload-dialog.tsx | 18 +++++++++++------- .../form-data/form-data-report-temp-upload-tab.tsx | 7 +++++-- components/form-data/temp-download-btn.tsx | 9 +++++++-- components/form-data/var-list-download-btn.tsx | 9 +++++++-- public/icons/temp_sample_icon.svg | 4 ++++ public/icons/var_list_icon.svg | 4 ++++ 6 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 public/icons/temp_sample_icon.svg create mode 100644 public/icons/var_list_icon.svg (limited to 'components/form-data/form-data-report-temp-upload-tab.tsx') diff --git a/components/form-data/form-data-report-temp-upload-dialog.tsx b/components/form-data/form-data-report-temp-upload-dialog.tsx index 51fe5aca..74cfe7c3 100644 --- a/components/form-data/form-data-report-temp-upload-dialog.tsx +++ b/components/form-data/form-data-report-temp-upload-dialog.tsx @@ -72,21 +72,25 @@ export const FormDataReportTempUploadDialog: FC< - +
+ +
- +
- +
+ +
- +
diff --git a/components/form-data/form-data-report-temp-upload-tab.tsx b/components/form-data/form-data-report-temp-upload-tab.tsx index c09ade28..5e6179a8 100644 --- a/components/form-data/form-data-report-temp-upload-tab.tsx +++ b/components/form-data/form-data-report-temp-upload-tab.tsx @@ -2,6 +2,7 @@ import React, { FC, useState } from "react"; import { useToast } from "@/hooks/use-toast"; +import { toast as toastMessage } from "sonner"; import prettyBytes from "pretty-bytes"; import { X, Loader2 } from "lucide-react"; import { Badge } from "@/components/ui/badge"; @@ -92,6 +93,7 @@ export const FormDataReportTempUploadTab: FC< successCount++; setUploadProgress(Math.round((successCount / totalFiles) * 100)); } + toastMessage.success("Template File 업로드 완료!"); } catch (err) { console.error(err); toast({ @@ -102,11 +104,12 @@ export const FormDataReportTempUploadTab: FC< } finally { setIsUploading(false); setUploadProgress(0); + setSelectedFiles([]) } }; return ( - <> +
- +
); }; diff --git a/components/form-data/temp-download-btn.tsx b/components/form-data/temp-download-btn.tsx index 01fff569..a5f963e4 100644 --- a/components/form-data/temp-download-btn.tsx +++ b/components/form-data/temp-download-btn.tsx @@ -1,9 +1,9 @@ "use client"; import React from "react"; +import Image from "next/image"; import { useToast } from "@/hooks/use-toast"; import { toast as toastMessage } from "sonner"; -import { Download } from "lucide-react"; import { saveAs } from "file-saver"; import { Button } from "@/components/ui/button"; import { getReportTempFileData } from "@/lib/forms/services"; @@ -34,7 +34,12 @@ export const TempDownloadBtn = () => { aria-label="Template Sample Download" onClick={downloadTempFile} > - + Template Sample Download Icon ); }; diff --git a/components/form-data/var-list-download-btn.tsx b/components/form-data/var-list-download-btn.tsx index 964844ce..19bb26f9 100644 --- a/components/form-data/var-list-download-btn.tsx +++ b/components/form-data/var-list-download-btn.tsx @@ -1,9 +1,9 @@ "use client"; import React, { FC } from "react"; +import Image from "next/image"; import { useToast } from "@/hooks/use-toast"; import { toast as toastMessage } from "sonner"; -import { BookDown } from "lucide-react"; import ExcelJS from "exceljs"; import { saveAs } from "file-saver"; import { Button } from "@/components/ui/button"; @@ -99,7 +99,12 @@ export const VarListDownloadBtn: FC = ({ aria-label="Variable List Download" onClick={downloadReportVarList} > - + Template Sample Download Icon ); }; diff --git a/public/icons/temp_sample_icon.svg b/public/icons/temp_sample_icon.svg new file mode 100644 index 00000000..4bf9aa6f --- /dev/null +++ b/public/icons/temp_sample_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/icons/var_list_icon.svg b/public/icons/var_list_icon.svg new file mode 100644 index 00000000..792b67be --- /dev/null +++ b/public/icons/var_list_icon.svg @@ -0,0 +1,4 @@ + + + + -- cgit v1.2.3