'use client'; import { FileUpload, FileUploadDropzone, FileUploadItem, FileUploadItemDelete, FileUploadItemMetadata, FileUploadItemPreview, FileUploadItemProgress, FileUploadList, FileUploadTrigger, type FileUploadProps, } from '@/components/file-upload'; import { Button } from '@/components/ui/button'; import { useUploadAgentFile } from '@/hooks/use-agent-request'; import { Upload, X } from 'lucide-react'; import * as React from 'react'; import { toast } from 'sonner'; type FileUploadDirectUploadProps = { value: Record | Record[]; onChange(value: Record[]): void; maxFiles?: number; }; export function FileUploadDirectUpload({ value, onChange, maxFiles, }: FileUploadDirectUploadProps) { const [files, setFiles] = React.useState([]); const uploadedFilesRef = React.useRef[]>( Array.isArray(value) ? value : value ? [value] : [], ); const { uploadAgentFile } = useUploadAgentFile(); const onUpload: NonNullable = React.useCallback( async (files, { onSuccess, onError }) => { try { const uploadPromises = files.map(async (file) => { const handleError = (error?: any) => { onError( file, error instanceof Error ? error : new Error('Upload failed'), ); }; try { const ret = await uploadAgentFile([file]); if (ret.code === 0) { onSuccess(file); uploadedFilesRef.current = [ ...uploadedFilesRef.current, ret.data, ]; onChange(uploadedFilesRef.current); } else { handleError(); } } catch (error) { handleError(error); } }); // Wait for all uploads to complete await Promise.all(uploadPromises); } catch (error) { // This handles any error that might occur outside the individual upload processes console.error('Unexpected error during upload:', error); } }, [onChange, uploadAgentFile], ); const onFileReject = React.useCallback((file: File, message: string) => { toast(message, { description: `"${file.name.length > 20 ? `${file.name.slice(0, 20)}...` : file.name}" has been rejected`, }); }, []); const handleFilesChange = React.useCallback( (newFiles: File[]) => { // Find removed files and update uploadedFilesRef const removedFiles = files.filter((f) => !newFiles.includes(f)); if (removedFiles.length > 0) { const removedIndices = removedFiles.map((f) => files.indexOf(f)); uploadedFilesRef.current = uploadedFilesRef.current.filter( (_, idx) => !removedIndices.includes(idx), ); onChange(uploadedFilesRef.current); } setFiles(newFiles); }, [files, onChange], ); return ( 1)} >

Drag & drop files here

Or click to browse (max {(maxFiles ?? 5) as number} files)

{files.map((file, index) => (
))}
); }