document.addEventListener('DOMContentLoaded', () => { const container = document.getElementById('active-projects-container') const tabLink = document.querySelector('a[href="#active-projects"]') const tabPane = document.getElementById('active-projects') if (!container || !tabPane) return let isLoaded = false let isLoading = false function loadActiveProjects() { if (isLoaded || isLoading) return isLoading = true // show loading only if tab is visible if (tabPane.classList.contains('active')) { container.innerHTML = '

Loading...

' } fetch('/admin/active-projects') .then(res => res.json()) .then(data => { container.innerHTML = renderTable(data) isLoaded = true }) .catch(() => { container.innerHTML = '

Failed to load active projects

' }) .finally(() => { isLoading = false }) } // preload immediately when /admin page opens loadActiveProjects() // ensure data is loaded when tab is opened if (tabLink) { tabLink.addEventListener('shown.bs.tab', () => { if (!isLoaded) loadActiveProjects() }) } }) function renderTable(data) { if (!Array.isArray(data) || data.length === 0) { return `
Great news! No projects are currently being edited.
` } const rows = data.map(project => { const owner = project.owner || {} const users = project.activeUsers || [] const usersHtml = users.length ? `` : 'None detected' return ` ${project.name} ${owner.name || 'Unknown'} ${ owner.email ? `${owner.email}` : 'N/A' } ${usersHtml} ${project.connectionCount} ` }).join('') return `

${data.length} project(s) currently being edited

${rows}
Project Name Owner Owner Email Active Users Connections
` }