"use client" import { FileUploader } from "@common/components"; import { Button } from '@common/components/ui'; import { handleUpload } from "@/components/lib/utils"; import { useId, useState } from 'react'; import type { HttpResponse, Upload } from "tus-js-client"; interface FileUploadFormProps { onSubmit?: (files: string, year: string, quarter: string, code: string, id: string) => void; onFileSelect?: (file: File | null, atflCd: string | null, atflId: string | null) => void; // 파일 선택 시 호출될 콜백 추가 showButton?: boolean; // 버튼 표시 여부 (기본값 true) showPreview?: boolean; // 파일명 프리뷰 표시 여부 accept?: string; // 파일 형식 지정 fileIdx?: number; // 부모가 어떤 FileUploadForm인지 구분하기 위한 인덱스 } const FileUploadForm = ({ onSubmit, onFileSelect, showButton = true, showPreview = false, accept = ".jpeg, .jpg, .png", fileIdx // props에서 fileIdx 받기 }: FileUploadFormProps) => { const [internalAtflCd, setInternalAtflCd] = useState(null); const [internalAtflId, setInternalAtflId] = useState(null); const [currentFile, setCurrentFile] = useState(null); // 현재 선택된 파일을 저장할 상태 const [fileName, setFileName] = useState(''); const [files, setFiles] = useState(null); const [upload, setUpload] = useState(null); const uniqueId = useId(); // 각 FileUploadForm 인스턴스에 대한 고유 ID 생성 // FileUploader 컴포넌트를 강제로 재마운트하기 위한 key 상태 추가 const [uploaderKey, setUploaderKey] = useState(0); const quater = [{ text: '1분기', val: '1' }, { text: '2분기', val: '2' }, { text: '3분기', val: '3' }, { text: '4분기', val: '4' }]; // 현재 년도부터 10년 전까지의 년도 옵션 생성 const yearOptions = Array.from({ length: 10 }, (_, i) => { const year = new Date().getFullYear() - i; return { text: `${year}년`, val: year.toString() }; }); const [selectedYear, setSelectedYear] = useState(yearOptions[0]?.val || ''); const [selectedQuarter, setSelectedQuarter] = useState(quater[0]?.val || ''); function registFile() { console.log(files?.[0]?.name) if (!currentFile) { alert('파일을 선택해주세요.'); return; } if (!selectedYear) { alert('등록년도를 선택해주세요.'); return; } if (!selectedQuarter) { alert('분기를 선택해주세요.'); return; } const fileNm = currentFile.name; if (onSubmit && files && currentFile) { // Promise로 handleUpload 완료를 기다림 handleUploadWithResponse(files, currentFile) .then(({ atflCd, atflId }) => { // 업로드 완료 후 onSubmit 실행 onSubmit(fileNm, selectedYear, selectedQuarter, atflCd || '', atflId || ''); // UI 초기화 setFiles(null); setFileName(''); setUploaderKey(prev => prev + 1); }) .catch((error) => { console.error('파일 업로드 실패:', error); alert('파일 업로드 중 오류가 발생했습니다.'); }); } } // handleUpload를 Promise로 감싸는 헬퍼 함수 function handleUploadWithResponse(files: FileList, file: File): Promise<{ atflCd: string | null, atflId: string | null }> { return new Promise((resolve, reject) => { const uploadResponseHandler = async (res: HttpResponse) => { try { const fileInfo = res.getHeader("X-File-Info"); if (!fileInfo) { resolve({ atflCd: null, atflId: null }); return; } const { atflCd: newAtflCd, atflId: newAtflId } = JSON.parse(fileInfo) ?? {}; console.log(`FileUploadForm (idx: ${fileIdx ?? 'N/A'}) - Upload completed:`, newAtflCd, newAtflId); // 내부 상태도 업데이트 (다른 용도로 사용할 수 있음) setInternalAtflCd(newAtflCd); setInternalAtflId(newAtflId); setFileName(file.name); if (onFileSelect) { onFileSelect(file, newAtflCd, newAtflId); } // Promise 완료 resolve({ atflCd: newAtflCd, atflId: newAtflId }); } catch (error) { reject(error); } }; const uploadErrorHandler = (error: Error) => { console.error('Upload failed:', error); reject(error); }; // 기존 handleUpload 유틸리티 사용 (수정하지 않음) handleUpload(files, { handleUploadStart: setUpload, handleSuccess: setUpload, handleResponse: uploadResponseHandler, }); }); } return (
{/* 컴포넌트 루트 div */}
{/* 카드 스타일링 */}
{/* FileUploader와 Button을 정렬하는 메인 flex 컨테이너 */}
{/* FileUploader의 너비와 오른쪽 여백을 제어하는 컨테이너 */} { const selectedFiles = e.target.files; if (!selectedFiles || selectedFiles.length === 0) { setFiles(null); setCurrentFile(null); setInternalAtflCd(null); setInternalAtflId(null); if (onFileSelect) { onFileSelect(null, null, null); // 파일 선택 취소 시 null 전달 } return; } const firstFile = selectedFiles[0]; if (!firstFile) return; // 타입스크립트 undefined 가능성 제거 setFiles(selectedFiles); setFileName(firstFile.name); setCurrentFile(firstFile); if (onFileSelect) { onFileSelect(firstFile, internalAtflCd, internalAtflId); } }} customPreview={ showPreview ? (
{files && files.length > 0 ? fileName : "파일을 선택하세요."}
) : null } />
{showButton ? ( // showButton이 true일 때만 버튼 렌더링 ) : null}
) } export default FileUploadForm