import React, { useState, useEffect } from "react"; import { DocumentChunk } from "../contracts/tool_outputs.js"; import { FileText, Search, ExternalLink, RefreshCw } from "lucide-react"; import { useLanguage } from "../context/LanguageContext.js"; import { getBackendUrl } from "../utils/api.js"; const COUNTRIES = ["SAU", "ARE", "EGY", "USA", "DEU", "JPN", "BRA", "CHN"]; export const DocumentLibraryView: React.FC = () => { const { language, t } = useLanguage(); const isAr = language === "ar"; const [query, setQuery] = useState(isAr ? "الميزانية العامة والدين السيادي" : "sovereign debt budget"); const [debouncedQuery, setDebouncedQuery] = useState(query); const [selectedCountry, setSelectedCountry] = useState("SAU"); const [alpha, setAlpha] = useState(0.6); const [documents, setDocuments] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); useEffect(() => { const id = setTimeout(() => setDebouncedQuery(query), 500); return () => clearTimeout(id); }, [query]); useEffect(() => { if (!debouncedQuery.trim()) return; const controller = new AbortController(); setLoading(true); setError(""); const params = new URLSearchParams({ query: debouncedQuery, alpha: String(alpha), country: selectedCountry }); fetch(`${getBackendUrl()}/api/rag/documents?${params}`, { signal: controller.signal }) .then(async (res) => { const json = await res.json().catch(() => ({})); if (!res.ok) throw new Error(json.error || `HTTP ${res.status}`); setDocuments(Array.isArray(json) ? json : []); }) .catch((err: Error) => { if (err.name !== "AbortError") setError(err.message); }) .finally(() => setLoading(false)); return () => controller.abort(); }, [debouncedQuery, selectedCountry, alpha]); return (

{t.documents.title}

{t.documents.subtitle}

setQuery(e.target.value)} placeholder={t.documents.searchPlaceholder} className="w-full bg-slate-900 border border-slate-800 rounded-lg ps-9 pe-3 py-1.5 text-xs text-slate-200 focus:outline-none focus:border-purple-500" />
{isAr ? "وزن العنوان مقابل النص" : "Title vs body weight"} {alpha.toFixed(1)}
setAlpha(parseFloat(e.target.value))} className="w-full accent-purple-400 cursor-pointer" />
{loading && (
{isAr ? "جارٍ البحث..." : "Searching..."}
)} {error &&
{error}
} {!loading && !error && documents.length === 0 && (
{t.documents.noDocsFound}
)}
{documents.map((doc) => (
[{doc.chunk_id}] {doc.source_authority} {new Date(doc.publication_timestamp).toLocaleDateString(isAr ? "ar-SA" : "en-US")}
{isAr ? "الصلة" : "Relevance"}: {doc.score ?? 0} {doc.url && }

{doc.title}

{doc.content}

))}
); };