fullstuckdev's picture
Upload 25 files
2341446 verified
"use client"
import { useState, useRef } from 'react'
import { Box, Typography, Button, CircularProgress, Chip, Stack } from '@mui/material'
import UploadFileIcon from '@mui/icons-material/UploadFile'
import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile'
interface FileUploadProps {
onDocumentsLoaded: (documents: { text: string }[]) => void;
}
export default function FileUpload({ onDocumentsLoaded }: FileUploadProps) {
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const [uploadedFiles, setUploadedFiles] = useState<string[]>([])
const fileInputRef = useRef<HTMLInputElement>(null)
const handleButtonClick = () => {
fileInputRef.current?.click()
}
const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
const files = e.target.files
if (!files?.length) return
setLoading(true)
setError(null)
try {
const formData = new FormData()
const fileNames: string[] = []
Array.from(files).forEach(file => {
formData.append('files', file)
fileNames.push(file.name)
})
const response = await fetch('/api/upload', {
method: 'POST',
body: formData,
})
if (!response.ok) {
const errorData = await response.json()
throw new Error(errorData.error || 'Upload failed')
}
const data = await response.json()
setUploadedFiles(prev => [...prev, ...fileNames])
onDocumentsLoaded(data.documents)
} catch (err) {
console.error('Upload error:', err)
setError(err instanceof Error ? err.message : 'Failed to process files. Please try again.')
} finally {
setLoading(false)
if (fileInputRef.current) {
fileInputRef.current.value = ''
}
}
}
return (
<Box>
<Typography variant="subtitle1" sx={{ mb: 1, color: 'text.primary' }}>
Upload Documents
</Typography>
<Typography variant="body2" sx={{ mb: 2, color: 'text.secondary' }}>
You can upload multiple PDF and Word documents at once
</Typography>
{uploadedFiles.length > 0 && (
<Box sx={{ mb: 3 }}>
<Typography variant="body2" sx={{ mb: 1, color: 'text.secondary' }}>
{uploadedFiles.length} {uploadedFiles.length === 1 ? 'file' : 'files'} uploaded
</Typography>
<Stack direction="row" spacing={1} sx={{ flexWrap: 'wrap', gap: 1 }}>
{uploadedFiles.map((fileName, index) => (
<Chip
key={index}
icon={<InsertDriveFileIcon />}
label={fileName}
variant="outlined"
sx={{
backgroundColor: 'rgba(37, 99, 235, 0.1)',
borderColor: 'rgba(37, 99, 235, 0.2)',
'& .MuiChip-icon': {
color: 'primary.main',
}
}}
/>
))}
</Stack>
</Box>
)}
<input
ref={fileInputRef}
type="file"
onChange={handleFileUpload}
accept=".pdf,.doc,.docx"
multiple
style={{ display: 'none' }}
disabled={loading}
/>
<Button
variant="outlined"
fullWidth
onClick={handleButtonClick}
disabled={loading}
startIcon={loading ? <CircularProgress size={20} /> : <UploadFileIcon />}
sx={{
py: 3,
borderStyle: 'dashed',
borderWidth: 2,
backgroundColor: 'rgba(255, 255, 255, 0.8)',
'&:hover': {
borderColor: 'primary.main',
backgroundColor: 'rgba(37, 99, 235, 0.04)',
}
}}
>
{loading ? 'Processing...' : 'Click to upload PDF or Word documents'}
</Button>
{error && (
<Typography color="error" sx={{ mt: 2, fontSize: '0.875rem' }}>
{error}
</Typography>
)}
</Box>
)
}