Spaces:
Running
Running
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; | |