From 3e47b8275454452324e3b6a7607f2db361110b0e Mon Sep 17 00:00:00 2001 From: rlaks5757 Date: Mon, 31 Mar 2025 17:23:48 +0900 Subject: Report -> Vendor Document 문구 수정, Upload Dialog Design Layout 변경 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form-data-report-temp-upload-dialog.tsx | 453 ++++++++++++--------- 1 file changed, 255 insertions(+), 198 deletions(-) (limited to 'components/form-data/form-data-report-temp-upload-dialog.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 69df704e..32273415 100644 --- a/components/form-data/form-data-report-temp-upload-dialog.tsx +++ b/components/form-data/form-data-report-temp-upload-dialog.tsx @@ -10,7 +10,7 @@ import React, { import { useToast } from "@/hooks/use-toast"; import { toast as toastMessage } from "sonner"; import prettyBytes from "pretty-bytes"; -import { X, Loader2, Download, Delete, Trash2 } from "lucide-react"; +import { X, Loader2, Download, Delete, Trash2, BookDown } from "lucide-react"; import ExcelJS from "exceljs"; import { saveAs } from "file-saver"; import { Badge } from "@/components/ui/badge"; @@ -54,6 +54,13 @@ import { AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; import { getReportTempList, uploadReportTemp, @@ -88,77 +95,7 @@ export const FormDataReportTempUploadDialog: FC< uploaderType, }) => { const { toast } = useToast(); - const [selectedFiles, setSelectedFiles] = useState([]); - const [isUploading, setIsUploading] = useState(false); - const [uploadProgress, setUploadProgress] = useState(0); - const [prevReportTemp, setPrevReportTemp] = useState( - [] - ); - - useEffect(() => { - updateReportTempList(packageId, formId, setPrevReportTemp); - }, [packageId, formId]); - - // 드롭존 - 파일 드랍 처리 - 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); - updateReportTempList(packageId, formId, setPrevReportTemp); - setOpen(false); - } - }; + const [tabValue, setTabValue] = useState<"upload" | "uploaded">("upload"); const downloadTempFile = async () => { try { @@ -253,115 +190,214 @@ export const FormDataReportTempUploadDialog: FC< - Report Template Upload + Vendor Document Template - 사용하시고자 하는 Report Template(.docx)를 업로드 하여주시기 - 바랍니다. + {/* 사용하시고자 하는 Vendor Document Template(.docx)를 업로드 + 하여주시기 바랍니다. */} -
- - - - - - - - sample_template_file.docx - - - - Download - - - - - - - - report_variable_list.xlsx - - - - Download - - - - -
-
- - - updateReportTempList(packageId, formId, setPrevReportTemp) - } - /> -
- -
- - - {({ maxSize }) => ( - <> - - -
- -
- 파일을 여기에 드롭하세요 - - 또는 클릭하여 파일을 선택하세요. 최대 크기:{" "} - {maxSize ? prettyBytes(maxSize) : "무제한"} - -
-
-
- - - )} -
-
- - {selectedFiles.length > 0 && ( -
-
-
- 선택된 파일 ({selectedFiles.length}) -
- {selectedFiles.length}개 파일 + +
+ + setTabValue("upload")}> + Upload Template File + + setTabValue("uploaded")} + > + Uploaded Template File List + + +
+ + + + + + + + + + + + + + + + + +
- - -
- )} - - {isUploading && } - - - - + + + + + + +
); }; +interface TempUploadTabProps { + packageId: number; + formId: number; + uploaderType: string; +} + +const TempUploadTab: FC = ({ + 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; @@ -374,7 +410,7 @@ const UploadFileItem: FC = ({ isUploading, }) => { return ( - + {selectedFiles.map((file, index) => ( @@ -418,33 +454,11 @@ const UploadProgressBox: FC<{ uploadProgress: number }> = ({ ); }; -const generateFileName = ( - packageId: number, - formId: number, - originalFileName: string, - index: number, - totalFiles: number -) => { - // Get the file extension - const extension = originalFileName.split(".").pop() || ""; - - // Base name without extension - const baseName = `${packageId}_${formId}`; - - // For multiple files, add a suffix - if (totalFiles > 1) { - return `${baseName}_${index + 1}.${extension}`; - } - - // For a single file, no suffix needed - return `${baseName}.${extension}`; -}; - type UpdateReportTempList = ( packageId: number, formId: number, setPrevReportTemp: Dispatch> -) => void; +) => Promise; const updateReportTempList: UpdateReportTempList = async ( packageId, @@ -458,11 +472,13 @@ const updateReportTempList: UpdateReportTempList = async ( interface UploadedTempFiles { prevReportTemp: VendorDataReportTemps[]; updateReportTempList: () => void; + isLoading: boolean; } const UploadedTempFiles: FC = ({ prevReportTemp, updateReportTempList, + isLoading, }) => { const { toast } = useToast(); @@ -484,7 +500,7 @@ const UploadedTempFiles: FC = ({ toastMessage.success("Template File 다운로드 완료!"); } catch (err) { - console.error(err) + console.error(err); toast({ title: "Error", description: "Template File 다운로드 중 오류가 발생했습니다.", @@ -512,9 +528,17 @@ const UploadedTempFiles: FC = ({ } }; + if (isLoading) { + return ( +
+ +
+ ); + } + return ( - - + + {prevReportTemp.map((c) => { const { fileName, filePath, id } = c; @@ -567,3 +591,36 @@ const UploadedTempFiles: FC = ({ ); }; + +interface TempUploadedTabProps { + packageId: number; + formId: number; +} + +const TempUploadedTab: FC = ({ packageId, formId }) => { + const [prevReportTemp, setPrevReportTemp] = useState( + [] + ); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + const getTempFiles = async () => { + await updateReportTempList(packageId, formId, setPrevReportTemp); + setIsLoading(false); + }; + + getTempFiles(); + }, [packageId, formId]); + return ( +
+ + + updateReportTempList(packageId, formId, setPrevReportTemp) + } + isLoading={isLoading} + /> +
+ ); +}; -- cgit v1.2.3