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;