Spaces:
Sleeping
Sleeping
File size: 5,032 Bytes
7a1c9d6 102c540 7a1c9d6 102c540 7a1c9d6 102c540 7a1c9d6 102c540 7a1c9d6 102c540 7a1c9d6 102c540 7a1c9d6 102c540 7a1c9d6 102c540 7a1c9d6 102c540 7a1c9d6 102c540 d62d58c 102c540 7a1c9d6 102c540 7a1c9d6 47bd0d6 102c540 47bd0d6 102c540 47bd0d6 102c540 7a1c9d6 102c540 47bd0d6 102c540 47bd0d6 102c540 47bd0d6 102c540 47bd0d6 102c540 47bd0d6 102c540 47bd0d6 102c540 47bd0d6 102c540 7a1c9d6 |
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 134 135 136 137 138 139 140 141 142 143 144 |
import React, { useState } from 'react';
import axios from 'axios';
import { Button } from './ui/button';
import { Input } from './ui/input';
const FileUpload = ({ sessionId, onUploadSuccess }) => {
const [file, setFile] = useState(null);
const [isUploading, setIsUploading] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
const [progress, setProgress] = useState(0);
const handleFileChange = (e) => {
const selectedFile = e.target.files[0];
setFile(selectedFile);
setErrorMessage('');
};
const handleUpload = async (e) => {
e.preventDefault();
if (!file) {
setErrorMessage('Please select a file to upload');
return;
}
setIsUploading(true);
setProgress(0);
setErrorMessage('');
const formData = new FormData();
formData.append('file', file);
formData.append('session_id', sessionId);
try {
const response = await axios.post('/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: (progressEvent) => {
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
setProgress(percentCompleted);
}
});
if (response.data.status === 'success') {
setIsUploading(false);
onUploadSuccess(
file.name,
response.data.document_description || 'No description available',
response.data.suggested_questions || []
);
} else {
setIsUploading(false);
setErrorMessage(response.data.message || 'Upload failed');
}
} catch (error) {
setIsUploading(false);
setErrorMessage(error.response?.data?.message || 'Error uploading file');
console.error('Error:', error);
}
};
return (
<div className="mx-auto max-w-md rounded-lg border border-border bg-card p-6 shadow-sm transition-colors duration-300">
<div className="mb-6 text-center">
<div className="mx-auto w-16 h-16 mb-4 rounded-full bg-primary/10 flex items-center justify-center">
<span role="img" aria-label="upload" className="text-3xl">📄</span>
</div>
<h2 className="text-xl font-semibold mb-2">Upload Document</h2>
<p className="text-sm text-muted-foreground">
Upload a document to start chatting with AI about its contents ✨
</p>
</div>
<form onSubmit={handleUpload} className="flex flex-col gap-4">
<div className="grid w-full items-center gap-1.5">
<label htmlFor="file-upload" className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 flex items-center gap-1.5">
<span role="img" aria-label="document" className="text-base">📋</span>
<span>Select Document</span>
</label>
<Input
id="file-upload"
type="file"
onChange={handleFileChange}
disabled={isUploading}
accept=".pdf,.txt,.doc,.docx"
className="cursor-pointer transition-colors duration-300"
/>
{file && (
<p className="mt-1 text-xs text-muted-foreground flex items-center gap-1">
<span role="img" aria-label="check" className="text-green-500">✅</span>
<span>Selected: {file.name}</span>
</p>
)}
</div>
{errorMessage && (
<div className="mb-4 rounded-md bg-destructive/15 p-3 text-sm text-destructive flex items-start gap-2">
<span role="img" aria-label="error" className="mt-0.5">⚠️</span>
<span>{errorMessage}</span>
</div>
)}
{isUploading && (
<div className="mb-4">
<div className="mb-1 flex justify-between text-xs">
<span className="flex items-center gap-1">
<span role="img" aria-label="upload" className="text-xs">📤</span>
<span>Uploading...</span>
</span>
<span>{progress}%</span>
</div>
<div className="h-2 w-full overflow-hidden rounded-full bg-secondary">
<div
className="h-full bg-primary transition-all duration-300"
style={{ width: `${progress}%` }}
/>
</div>
</div>
)}
<Button
type="submit"
disabled={isUploading || !file}
className="w-full transition-colors duration-300 flex items-center justify-center gap-2"
>
{isUploading ? (
<>
<span>Processing...</span>
<span role="img" aria-label="processing" className="animate-pulse">⏳</span>
</>
) : (
<>
<span>Upload Document</span>
<span role="img" aria-label="upload">🚀</span>
</>
)}
</Button>
</form>
</div>
);
};
export default FileUpload; |