Spaces:
Running
Running
File size: 4,364 Bytes
868e135 |
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 |
import React, { useState } from 'react';
function App() {
const [file, setFile] = useState<File | null>(null);
const [question, setQuestion] = useState('');
const [answer, setAnswer] = useState('');
const [context, setContext] = useState<string[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [uploadStatus, setUploadStatus] = useState('');
const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
if (!e.target.files?.length) return;
const uploadedFile = e.target.files[0];
setFile(uploadedFile);
setIsLoading(true);
setUploadStatus('Processing...');
const formData = new FormData();
formData.append('file', uploadedFile);
try {
const response = await fetch('/api/upload', {
method: 'POST',
body: formData,
});
const data = await response.json();
console.log('File uploaded:', data);
setUploadStatus(`Processing ${uploadedFile.name} done. You can now ask questions!`);
} catch (error) {
console.error('Error uploading file:', error);
setUploadStatus('Error processing file. Please try again.');
} finally {
setIsLoading(false);
}
};
const handleAskQuestion = async (e: React.FormEvent) => {
e.preventDefault();
if (!question.trim()) return;
setIsLoading(true);
setAnswer('');
setContext([]);
try {
const response = await fetch('/api/ask', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query: question }),
});
const data = await response.json();
setAnswer(data.answer);
setContext(data.context || []);
} catch (error) {
console.error('Error asking question:', error);
setAnswer('Error getting answer. Please try again.');
} finally {
setIsLoading(false);
}
};
return (
<div className="container mx-auto p-4 max-w-4xl">
<h1 className="text-3xl font-bold mb-8">Document Q&A</h1>
<div className="mb-8">
<div className="text-center mb-4">
{!file && (
<p className="text-lg">Please upload a Text or PDF file to begin!</p>
)}
</div>
<label className="block text-sm font-medium mb-2">
Upload Document (PDF/TXT)
</label>
<input
type="file"
accept=".pdf,.txt"
onChange={handleFileUpload}
className="block w-full text-sm border rounded-lg cursor-pointer"
/>
{uploadStatus && (
<p className="mt-2 text-sm text-gray-600">{uploadStatus}</p>
)}
</div>
<form onSubmit={handleAskQuestion} className="mb-8">
<div className="mb-4">
<label className="block text-sm font-medium mb-2">
Ask a Question
</label>
<input
type="text"
value={question}
onChange={(e) => setQuestion(e.target.value)}
className="w-full p-2 border rounded-lg"
placeholder="Type your question here..."
disabled={!file || isLoading}
/>
</div>
<button
type="submit"
disabled={!file || !question || isLoading}
className="bg-blue-500 text-white px-4 py-2 rounded-lg disabled:opacity-50"
>
{isLoading ? 'Loading...' : 'Ask'}
</button>
</form>
{answer && (
<div className="mb-8">
<h2 className="text-xl font-semibold mb-4">Answer:</h2>
<p className="p-4 bg-gray-100 rounded-lg whitespace-pre-wrap">{answer}</p>
</div>
)}
{context.length > 0 && (
<div>
<h2 className="text-xl font-semibold mb-2">Source Excerpts:</h2>
<p className="text-sm text-gray-600 mb-4">Below are the relevant excerpts from your document that were used to generate the answer:</p>
<div className="space-y-2">
{context.map((text, index) => (
<div key={index} className="p-4 bg-gray-50 rounded-lg border border-gray-200">
<p className="text-sm text-gray-500 mb-1">Excerpt {index + 1}:</p>
<p className="text-sm">{text}</p>
</div>
))}
</div>
</div>
)}
</div>
);
}
export default App;
|