'use client' import { useState, useEffect, useCallback } from 'react' import type { Collection, IndexedDocument, IndexedDocumentsData, DocumentContent } from '../types' const API_BASE = process.env.NEXT_PUBLIC_KLAUSUR_SERVICE_URL || 'http://localhost:8086' interface DocumentsTabProps { collections: Collection[] } function DocumentsTab({ collections }: DocumentsTabProps) { const [documents, setDocuments] = useState(null) const [loading, setLoading] = useState(true) const [selectedCollection, setSelectedCollection] = useState('bp_nibis_eh') const [yearFilter, setYearFilter] = useState('') const [subjectFilter, setSubjectFilter] = useState('') const [currentPage, setCurrentPage] = useState(0) const [deleting, setDeleting] = useState(null) const [deleteConfirm, setDeleteConfirm] = useState(null) const [viewingDoc, setViewingDoc] = useState(null) const [loadingContent, setLoadingContent] = useState(false) const pageSize = 20 const fetchDocuments = useCallback(async () => { setLoading(true) try { const params = new URLSearchParams({ collection: selectedCollection, limit: pageSize.toString(), offset: (currentPage * pageSize).toString(), }) if (yearFilter) params.append('year', yearFilter) if (subjectFilter) params.append('subject', subjectFilter) const res = await fetch(`${API_BASE}/api/v1/admin/rag/files/indexed?${params}`) if (res.ok) { const data = await res.json() setDocuments(data) } } catch (err) { console.error('Failed to fetch documents:', err) } finally { setLoading(false) } }, [selectedCollection, yearFilter, subjectFilter, currentPage]) useEffect(() => { fetchDocuments() }, [fetchDocuments]) const handleDelete = async (docId: string, deleteSource: boolean = false) => { setDeleting(docId) try { const params = new URLSearchParams() if (deleteSource) params.append('delete_source', 'true') const res = await fetch( `${API_BASE}/api/v1/admin/rag/files/${selectedCollection}/${encodeURIComponent(docId)}?${params}`, { method: 'DELETE' } ) if (res.ok) { // Refresh the list await fetchDocuments() setDeleteConfirm(null) } } catch (err) { console.error('Failed to delete document:', err) } finally { setDeleting(null) } } const handleViewDocument = async (docId: string) => { setLoadingContent(true) try { const res = await fetch( `${API_BASE}/api/v1/admin/rag/files/${selectedCollection}/${encodeURIComponent(docId)}/content` ) if (res.ok) { const data = await res.json() setViewingDoc(data) } } catch (err) { console.error('Failed to load document content:', err) } finally { setLoadingContent(false) } } const handleDownloadPdf = (docId: string) => { window.open( `${API_BASE}/api/v1/admin/rag/files/${selectedCollection}/${encodeURIComponent(docId)}/download`, '_blank' ) } return (

Indexierte Dokumente

Übersicht aller indexierten Dokumente mit Möglichkeit zum Löschen

{/* Filters */}
{documents && ( <>
)}
{documents && (
{documents.total_documents ?? documents.totalCount} Dokumente {(documents.total_chunks ?? 0).toLocaleString()} Chunks
)}
{/* Documents List */} {loading ? (
) : documents && documents.documents.length > 0 ? (
{documents.documents.map((doc) => ( ))}
Jahr Fach Niveau Typ Chunks Vorschau Aktionen
{doc.year || '-'} {doc.subject || '-'} {doc.niveau || '-'} {doc.doc_type || '-'} {doc.chunk_count} {doc.sample_text || '-'} {deleteConfirm === doc.doc_id ? (
) : (
)}
{/* Pagination */} {documents.pagination && (
Zeige {documents.pagination.offset + 1} bis{' '} {Math.min(documents.pagination.offset + pageSize, documents.total_documents ?? documents.totalCount)} von{' '} {documents.total_documents ?? documents.totalCount}
)}
) : (

Keine Dokumente gefunden

{yearFilter || subjectFilter ? 'Keine Dokumente mit den gewählten Filtern.' : 'Diese Sammlung enthält noch keine indexierten Dokumente.'}

)} {/* Document Viewer Modal */} {(viewingDoc || loadingContent) && (
{/* Header */}

{viewingDoc?.metadata?.filename || 'Dokument'}

{viewingDoc?.metadata && (
{viewingDoc.metadata.year && {viewingDoc.metadata.year}} {viewingDoc.metadata.subject && {viewingDoc.metadata.subject}} {viewingDoc.metadata.niveau && {viewingDoc.metadata.niveau}} {viewingDoc?.chunk_count} Chunks
)}
{viewingDoc && ( )}
{/* Content */}
{loadingContent ? (
) : viewingDoc ? (
                    {viewingDoc.text}
                  
) : null}
)}
) } // ============================================================================ // Search Tab // ============================================================================ export { DocumentsTab }