"use client"; import { Loader2, Paperclip } from "lucide-react"; import { ChangeEvent, useState } from "react"; import { buttonVariants } from "./button"; import { cn } from "./lib/utils"; export interface FileUploaderProps { config?: { inputId?: string; fileSizeLimit?: number; allowedExtensions?: string[]; checkExtension?: (extension: string) => string | null; disabled: boolean; }; onFileUpload: (file: File) => Promise; onFileError?: (errMsg: string) => void; } const DEFAULT_INPUT_ID = "fileInput"; const DEFAULT_FILE_SIZE_LIMIT = 1024 * 1024 * 50; // 50 MB export default function FileUploader({ config, onFileUpload, onFileError, }: FileUploaderProps) { const [uploading, setUploading] = useState(false); const inputId = config?.inputId || DEFAULT_INPUT_ID; const fileSizeLimit = config?.fileSizeLimit || DEFAULT_FILE_SIZE_LIMIT; const allowedExtensions = config?.allowedExtensions; const defaultCheckExtension = (extension: string) => { if (allowedExtensions && !allowedExtensions.includes(extension)) { return `无效的文件类型。请选择一个以下格式的文件: ${allowedExtensions!.join( ",", )}`; } return null; }; const checkExtension = config?.checkExtension ?? defaultCheckExtension; const isFileSizeExceeded = (file: File) => { return file.size > fileSizeLimit; }; const resetInput = () => { const fileInput = document.getElementById(inputId) as HTMLInputElement; fileInput.value = ""; }; const onFileChange = async (e: ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; setUploading(true); await handleUpload(file); resetInput(); setUploading(false); }; const handleUpload = async (file: File) => { const onFileUploadError = onFileError || window.alert; const fileExtension = file.name.split(".").pop() || ""; const extensionFileError = checkExtension(fileExtension); if (extensionFileError) { return onFileUploadError(extensionFileError); } if (isFileSizeExceeded(file)) { return onFileUploadError( `文件尺寸超标。请选择不大于 ${fileSizeLimit / 1024 / 1024} MB 的文件。`, ); } await onFileUpload(file); }; return (
); }