const API_URL = ( window.API_URL || localStorage.getItem("API_URL") || "https://rindhuja-intelligent-doc-api.hf.space" ).replace(/\/$/, "") const token = localStorage.getItem("token") const role = localStorage.getItem("role") const username = localStorage.getItem("username") || "Admin" const loginTime = localStorage.getItem("loginTime") const HISTORY_KEY = "ids_search_history" const DOC_COUNTER_KEY = "ids_document_counter" let isUploading = false if (!token) { window.location = "index.html" } if (role !== "admin") { window.location = "search.html" } document.addEventListener("DOMContentLoaded", initializeAdminDashboard) function initializeAdminDashboard() { bindAdminEvents() renderAdminSession() renderAdminSidebarHistory() renderAdminTopDocs() loadDocuments() loadStats() loadAnalytics() loadUsers() } function bindAdminEvents() { document.getElementById("adminLogoutButton")?.addEventListener("click", logout) document.getElementById("adminProfileButton")?.addEventListener("click", openAdminProfile) document.getElementById("closeAdminProfile")?.addEventListener("click", closeAdminProfile) document.getElementById("adminProfileOverlay")?.addEventListener("click", closeAdminProfile) } function logout() { localStorage.removeItem("token") localStorage.removeItem("role") localStorage.removeItem("username") localStorage.removeItem("loginTime") window.location = "index.html" } function openAdminProfile() { document.body.classList.add("drawer-open") } function closeAdminProfile() { document.body.classList.remove("drawer-open") } function getSearchHistory() { try { return JSON.parse(localStorage.getItem(HISTORY_KEY)) || [] } catch { return [] } } function getDocCounters() { try { return JSON.parse(localStorage.getItem(DOC_COUNTER_KEY)) || {} } catch { return {} } } function renderAdminSession() { document.getElementById("adminProfileAvatar").textContent = (username[0] || "A").toUpperCase() document.getElementById("adminProfileName").textContent = username document.getElementById("adminProfileRole").textContent = "Administrator" const history = getSearchHistory() const counters = getDocCounters() const details = document.getElementById("adminProfileDetails") details.innerHTML = `
${escapeHtml(username)}
Administrator
${(username[0] || "A").toUpperCase()}
Role in company: Admin Search records: ${history.length} Tracked docs: ${Object.keys(counters).length}
Admin details
Name: ${escapeHtml(username)}
Session started: ${escapeHtml(formatDateTime(loginTime))}
Document uploading: enabled
Analytics access: enabled
Every user details: available in dashboard
Admin related controls: active
` } function renderAdminSidebarHistory() { const history = getSearchHistory() const list = document.getElementById("adminHistoryList") document.getElementById("adminHistoryCount").textContent = history.length if (!history.length) { list.innerHTML = '
Search activity from the assistant view appears here.
' return } list.innerHTML = history.slice(0, 8).map(item => ` `).join("") } function renderAdminTopDocs() { const counters = Object.entries(getDocCounters()).sort((a, b) => b[1] - a[1]).slice(0, 8) const list = document.getElementById("adminTopDocsList") if (!counters.length) { list.innerHTML = '
Document popularity updates after search activity.
' return } list.innerHTML = counters.map(([name, count]) => ` `).join("") } async function uploadFile() { if (isUploading) return const fileInput = document.getElementById("fileInput") const uploadButton = document.querySelector(".upload-box .primary-btn") const selectedFile = fileInput.files[0] if (!selectedFile) { document.getElementById("uploadStatus").innerText = "Select a file before uploading." return } const maxUploadMb = 15 if (selectedFile.size > maxUploadMb * 1024 * 1024) { document.getElementById("uploadStatus").innerText = `File too large. Please upload a file below ${maxUploadMb} MB.` return } isUploading = true if (uploadButton) { uploadButton.disabled = true uploadButton.innerText = "Uploading..." } const formData = new FormData() formData.append("file", selectedFile) document.getElementById("uploadStatus").innerText = "Uploading document..." try { const res = await fetch(API_URL + "/upload", { method: "POST", headers: { Authorization: "Bearer " + token }, body: formData }) const raw = await res.text() let data = {} try { data = raw ? JSON.parse(raw) : {} } catch { data = { detail: raw || "Upload failed" } } document.getElementById("uploadStatus").innerText = data.message || data.detail || "Upload finished" if (res.ok) { fileInput.value = "" loadDocuments() loadStats() } else if (!data.message && !data.detail) { document.getElementById("uploadStatus").innerText = `Upload failed (HTTP ${res.status}).` } } catch { document.getElementById("uploadStatus").innerText = "Upload failed. Please retry." } finally { isUploading = false if (uploadButton) { uploadButton.disabled = false uploadButton.innerText = "Upload Document" } } } async function loadDocuments() { const res = await fetch(API_URL + "/documents", { headers: { Authorization: "Bearer " + token } }) const docs = await res.json() const container = document.getElementById("documents") document.getElementById("adminDocumentsCount").textContent = Array.isArray(docs) ? docs.length : 0 if (!Array.isArray(docs) || !docs.length) { container.innerHTML = '
No uploaded documents found.
' document.getElementById("adminSidebarDocuments").innerHTML = '
No uploaded documents found.
' return } container.innerHTML = docs.map(doc => `
${escapeHtml(doc.filename)} Uploaded by ${escapeHtml(doc.uploaded_by || "admin")} ${escapeHtml(doc.uploaded_at || "Recently uploaded")}
`).join("") document.getElementById("adminSidebarDocuments").innerHTML = docs.slice(0, 8).map(doc => ` `).join("") } async function deleteDoc(id) { await fetch(API_URL + "/documents/" + id, { method: "DELETE", headers: { Authorization: "Bearer " + token } }) loadDocuments() loadStats() } async function loadStats() { const res = await fetch(API_URL + "/admin/stats", { headers: { Authorization: "Bearer " + token } }) const data = await res.json() document.getElementById("statDocuments").textContent = data.documents ?? 0 document.getElementById("statChunks").textContent = data.chunks ?? 0 document.getElementById("statUsers").textContent = data.users ?? 0 document.getElementById("statQueries").textContent = data.queries ?? 0 } async function loadAnalytics() { const res = await fetch(API_URL + "/admin/analytics", { headers: { Authorization: "Bearer " + token } }) const data = await res.json() document.getElementById("analytics").innerHTML = `

Total queries

${data.total_queries ?? 0}

Top questions

${(data.top_questions || []).length ? data.top_questions.map(item => `
${escapeHtml(item.question)} ${item.count}
`).join("") : '
No query analytics yet.
'}

Most active users

${(data.active_users || []).length ? data.active_users.map(item => `
${escapeHtml(item.username)} ${item.count}
`).join("") : '
No user activity yet.
'}
` renderAdminSession() } async function loadUsers() { const res = await fetch(API_URL + "/admin/users", { headers: { Authorization: "Bearer " + token } }) const data = await res.json() const users = Array.isArray(data.users) ? data.users : [] document.getElementById("usersPanel").innerHTML = users.length ? users.map(user => `
${escapeHtml(user[1])} User ID: ${escapeHtml(user[0])} Role: ${escapeHtml(user[2])}
${escapeHtml(user[2])}
`).join("") : '
No user records available.
' renderAdminSession() } function escapeHtml(value) { return String(value ?? "") .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """) .replaceAll("'", "'") } function formatDateTime(value) { if (!value) return "Active session" const date = new Date(value) if (Number.isNaN(date.getTime())) return String(value) return date.toLocaleString() }