import React from "react"; import Image from "next/image"; import { X, Upload, Image as ImageIcon, FileText, File as FileIcon } from "lucide-react"; export interface PendingFile { file: File; preview?: string; } interface FileUploadProps { files: PendingFile[]; onFilesChange: (files: PendingFile[]) => void; accept?: string; multiple?: boolean; disabled?: boolean; label?: string; required?: boolean; description?: string; showImagePreview?: boolean; maxSizeMB?: number; } export default function FileUpload({ files, onFilesChange, accept, multiple = true, disabled = false, label = "파일 첨부", required = false, description = "이미지, PDF, 문서 등 모든 파일 형식 지원", showImagePreview = false, maxSizeMB, }: FileUploadProps) { const getFileIcon = (fileType: string) => { if (fileType.startsWith("image/")) { return ImageIcon; } else if (fileType.includes("pdf")) { return FileText; } else { return FileIcon; } }; const isImage = (fileType: string) => { return fileType.startsWith("image/"); }; const handleFileChange = (e: React.ChangeEvent) => { const selectedFiles = e.target.files; if (!selectedFiles || selectedFiles.length === 0) return; let newFiles = Array.from(selectedFiles); // 파일 크기 검사 if (maxSizeMB) { const maxSize = maxSizeMB * 1024 * 1024; const oversizedFiles = newFiles.filter((f) => f.size > maxSize); if (oversizedFiles.length > 0) { alert( `파일 크기는 ${maxSizeMB}MB를 초과할 수 없습니다: ${oversizedFiles.map((f) => f.name).join(", ")}` ); newFiles = newFiles.filter((f) => f.size <= maxSize); if (newFiles.length === 0) return; } } const newPendingFiles: PendingFile[] = newFiles.map((file) => ({ file, preview: file.type.startsWith("image/") ? URL.createObjectURL(file) : undefined, })); onFilesChange([...files, ...newPendingFiles]); // input 초기화 e.target.value = ""; }; const removeFile = (index: number) => { const file = files[index]; if (file.preview) { URL.revokeObjectURL(file.preview); } onFilesChange(files.filter((_, i) => i !== index)); }; return (
{/* 파일 목록 */} {files.length > 0 && (

선택된 파일 ({files.length})

{/* 이미지 미리보기 그리드 */} {showImagePreview ? (
{files.map((pf, index) => (
{pf.preview ? ( {`Preview ) : (
)}
))}
) : ( /* 파일 리스트 */
{files.map((pf, index) => { const FileIconComponent = getFileIcon(pf.file.type); return (
{isImage(pf.file.type) ? ( ) : ( )}

{pf.file.name}

{(pf.file.size / 1024).toFixed(1)} KB

); })}
)}
)}
); }