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()
}