njhaveri's picture
Fast API/React version
868e135
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;