File size: 4,636 Bytes
69524c2
 
 
 
 
 
 
 
 
 
ab11183
69524c2
320a9c2
69524c2
 
 
 
 
 
 
 
 
 
 
 
320a9c2
 
 
69524c2
 
 
 
 
 
 
320a9c2
69524c2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f962ed0
69524c2
 
 
 
 
 
 
f962ed0
69524c2
 
 
 
 
f962ed0
69524c2
 
 
 
 
 
 
 
 
 
f962ed0
69524c2
 
 
 
 
f962ed0
69524c2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { useState, useEffect } from 'react';
import { 
  FileText, 
  MessageSquare, 
  Calendar, 
  Layers, 
  Clock,
  ExternalLink,
  Search
} from 'lucide-react';
import { fetchDocuments } from '../api';

export default function DocsLibrary({ token, onSelectChat, onLogout }) {
  const [documents, setDocuments] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [searchTerm, setSearchTerm] = useState('');

  const loadDocs = async () => {
    setLoading(true);
    try {
      const data = await fetchDocuments(token);
      setDocuments(data.documents);
    } catch (err) {
      setError('Failed to load library');
      if (err.status === 401 && onLogout) {
        onLogout();
      }
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    if (token) loadDocs();
  }, [token, onLogout]);

  const filteredDocs = documents.filter(doc => 
    doc.filename.toLowerCase().includes(searchTerm.toLowerCase()) ||
    doc.session_title?.toLowerCase().includes(searchTerm.toLowerCase())
  );

  return (
    <div className="library-container">
      <div className="library-header-actions">
        <div className="search-bar">
          <Search size={18} />
          <input 
            type="text" 
            placeholder="Search documents or chats..." 
            value={searchTerm}
            onChange={(e) => setSearchTerm(e.target.value)}
          />
        </div>
        <div className="stats-header">
           <div className="stat-chip">
             <FileText size={14} />
             <span>{documents.length} Documents</span>
           </div>
        </div>
      </div>

      {error && <div className="error-banner">{error}</div>}

      <div className="library-grid-view">
        {loading ? (
          <div className="library-loader">
             <div className="loader-ring"></div>
             <p>Scanning your secure storage...</p>
          </div>
        ) : filteredDocs.length === 0 ? (
          <div className="empty-library">
            <FileText size={64} style={{ opacity: 0.2, marginBottom: '1rem' }} />
            <h3>No documents found</h3>
            <p>Upload documents in a chat to see them here.</p>
          </div>
        ) : (
          <div className="library-table-wrapper">
            <table className="library-table">
              <thead>
                <tr>
                  <th>Document</th>
                  <th>Upload Date</th>
                  <th>Source Chat</th>
                  <th>Scale</th>
                  <th>Efficiency</th>
                </tr>
              </thead>
              <tbody>
                {filteredDocs.map((doc) => (
                  <tr key={doc.id || doc.filename}>
                    <td data-label="Document">
                      <div className="doc-primary-cell">
                        <div className="doc-icon-small">
                          <FileText size={16} />
                        </div>
                        <span className="doc-name">{doc.filename}</span>
                      </div>
                    </td>
                    <td data-label="Upload Date">
                      <div className="metadata-cell">
                        <Calendar size={14} />
                        <span>{new Date(doc.date).toLocaleDateString()}</span>
                      </div>
                    </td>
                    <td data-label="Source Chat">
                      {doc.session_id ? (
                        <button className="chat-link-btn" onClick={() => onSelectChat(doc.session_id)}>
                          <MessageSquare size={14} />
                          <span>{doc.session_title}</span>
                          <ExternalLink size={12} className="hover-only" />
                        </button>
                      ) : (
                        <span className="text-muted">No Session</span>
                      )}
                    </td>
                    <td data-label="Scale">
                      <div className="metadata-cell">
                        <Layers size={14} />
                        <span>{doc.chunks} Chunks</span>
                      </div>
                    </td>
                    <td data-label="Efficiency">
                      <div className="metadata-cell">
                        <Clock size={14} />
                        <span>{doc.embed_time}s</span>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    </div>
  );
}