"use client"; 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"; 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)); } toastMessage.success("Template File 업로드 완료!"); } catch (err) { console.error(err); toast({ title: "Error", description: "파일 업로드 중 오류가 발생했습니다.", variant: "destructive", }); } finally { setIsUploading(false); setUploadProgress(0); setSelectedFiles([]) } }; 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}% 업로드 중...
); };