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;