"use client"; import { useRef, useState } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { uploadedFileSchema, UPLOAD_RULES, type UploadKind, type UploadedFileMetadata, } from "@/lib/validations/upload"; type FileUploadProps = { kind: UploadKind; onUploaded: (files: UploadedFileMetadata[]) => void; id?: string; multiple?: boolean; label?: string; helperText?: string; }; const defaultLabels: Record = { image: "Image", audio: "Audio", }; export default function FileUpload({ kind, onUploaded, id, multiple = false, label, helperText, }: FileUploadProps) { const inputRef = useRef(null); const [isUploading, setIsUploading] = useState(false); const [error, setError] = useState(null); const rules = UPLOAD_RULES[kind]; const fieldId = id ?? `file-upload-${kind}`; async function handleFiles(selectedFiles: File[]) { setError(null); setIsUploading(true); try { const uploaded: UploadedFileMetadata[] = []; for (const file of selectedFiles) { if (!rules.mimeTypes.includes(file.type) || file.size > rules.maxBytes) { throw new Error(`Unsupported or oversized ${kind} file.`); } const body = new FormData(); body.set("kind", kind); body.set("file", file); const response = await fetch("/api/upload", { method: "POST", body }); const payload: unknown = await response.json(); if (!response.ok) { const message = typeof payload === "object" && payload !== null && "error" in payload ? String(payload.error) : "The file could not be uploaded."; throw new Error(message); } const parsed = uploadedFileSchema.safeParse(payload); if (!parsed.success) { throw new Error("The upload response was invalid."); } uploaded.push(parsed.data); } onUploaded(uploaded); } catch (uploadError) { setError(uploadError instanceof Error ? uploadError.message : "The file could not be uploaded."); } finally { setIsUploading(false); if (inputRef.current) { inputRef.current.value = ""; } } } return (
{ void handleFiles(Array.from(event.target.files ?? [])); }} /> {isUploading ? ( ) : null}

{helperText ?? `Maximum ${Math.round(rules.maxBytes / (1024 * 1024))} MB.`}

{error ?

{error}

: null}
); }