Spaces:
Sleeping
Sleeping
File size: 3,803 Bytes
56fda74 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
import React, { useCallback, useState } from 'react';
import { useDropzone } from 'react-dropzone';
import {
Box,
Paper,
Typography,
CircularProgress,
Alert,
Button
} from '@mui/material';
import CloudUploadIcon from '@mui/icons-material/CloudUpload';
import axios from 'axios';
const FileUpload = ({ onUploadSuccess, onProcessingStart, onProcessingEnd }) => {
const [uploading, setUploading] = useState(false);
const [error, setError] = useState(null);
const [success, setSuccess] = useState(false);
const onDrop = useCallback(async (acceptedFiles) => {
if (acceptedFiles.length === 0) return;
const file = acceptedFiles[0];
// Check file type
if (!file.name.toLowerCase().endsWith('.txt') && !file.name.toLowerCase().endsWith('.pdf')) {
setError('Only .txt and .pdf files are allowed');
return;
}
// Check file size (2MB limit)
if (file.size > 2 * 1024 * 1024) {
setError('File size exceeds 2MB limit');
return;
}
setUploading(true);
setError(null);
setSuccess(false);
onProcessingStart();
const formData = new FormData();
formData.append('file', file);
try {
const response = await axios.post('http://localhost:8000/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
setSuccess(true);
onUploadSuccess(file.name);
} catch (err) {
console.error('Upload error:', err);
setError(err.response?.data?.detail || 'Error uploading file. Please try again.');
} finally {
setUploading(false);
onProcessingEnd();
}
}, [onUploadSuccess, onProcessingStart, onProcessingEnd]);
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
accept: {
'text/plain': ['.txt'],
'application/pdf': ['.pdf'],
},
maxSize: 2 * 1024 * 1024, // 2MB
multiple: false,
});
return (
<Paper
elevation={2}
sx={{
p: 3,
mb: 4,
border: '2px dashed',
borderColor: isDragActive ? 'primary.main' : 'grey.300',
backgroundColor: isDragActive ? 'action.hover' : 'background.paper',
transition: 'all 0.2s ease',
}}
>
<Box
{...getRootProps()}
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
cursor: 'pointer',
minHeight: '200px',
}}
>
<input {...getInputProps()} />
{uploading ? (
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
<CircularProgress size={60} sx={{ mb: 2 }} />
<Typography variant="body1">Processing your file...</Typography>
</Box>
) : (
<>
<CloudUploadIcon sx={{ fontSize: 60, color: 'primary.main', mb: 2 }} />
<Typography variant="h6" gutterBottom>
{isDragActive ? 'Drop the file here' : 'Drag & drop a file here, or click to select'}
</Typography>
<Typography variant="body2" color="text.secondary" align="center" sx={{ mb: 2 }}>
Supported formats: .txt, .pdf (max 2MB)
</Typography>
<Button variant="contained" color="primary">
Select File
</Button>
</>
)}
</Box>
{error && (
<Alert severity="error" sx={{ mt: 2 }}>
{error}
</Alert>
)}
{success && (
<Alert severity="success" sx={{ mt: 2 }}>
File uploaded successfully! You can now ask questions about the document.
</Alert>
)}
</Paper>
);
};
export default FileUpload; |