const API_BASE = "/api/v1/client"; // Format time function function formatTime(seconds) { if (!seconds) return 'No Record Found'; const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); if (hours > 0) { return `${hours}h ${minutes}m`; } else if (minutes > 0) { return `${minutes}m`; } else { return 'Just started'; } } const vaModal = document.getElementById('vaModal'); function openVAModal(va) { // Set basic VA info document.getElementById('modalVAName').textContent = va.name; // Set projects const projects = va.projects || []; document.getElementById('projectsCountBadge').textContent = projects.length; const projectsTableBody = document.getElementById('modalProjectsTableBody'); const noProjectsMessage = document.getElementById('modalNoProjects'); if (projects.length > 0) { projectsTableBody.innerHTML = projects.map(project => createProjectTableRow(project)).join(''); projectsTableBody.style.display = ''; noProjectsMessage.style.display = 'none'; } else { projectsTableBody.innerHTML = ''; projectsTableBody.style.display = 'none'; noProjectsMessage.style.display = 'block'; } // Set action button const modalActions = document.getElementById('modalActions'); const viewSessionBtn = document.getElementById('viewSessionBtn'); if (va.isCurrentlyActive && va.lastProjectId) { viewSessionBtn.href = `/live/${va.lastProjectId}/${va.id}`; modalActions.style.display = 'block'; } else { modalActions.style.display = 'none'; } // Show modal vaModal.style.display = 'flex'; document.body.style.overflow = 'hidden'; } function closeVAModal() { vaModal.style.display = 'none'; document.body.style.overflow = 'auto'; } // Create project table row for modal function createProjectTableRow(project) { const statusClass = project.isCurrentlyWorking ? 'active' : 'inactive'; const statusText = project.isCurrentlyWorking ? 'Working' : 'Not Active'; return `
${project.name}
$${project.hourlyRate}/hr ${project.totalWorkedTime}
${statusText}
`; } // Create VA table row for main table function createVATableRow(va) { const statusClass = va.isCurrentlyActive ? 'active' : 'inactive'; const statusText = va.isCurrentlyActive ? 'Active' : 'Inactive'; const activeProject = va?.lastProject?.name ? va.lastProject.name : '-'; const workedTime = formatTime(va.currentSessionDuration); const projectsAssigned = va.projectsAssigned || 0; const viewLink = va.isCurrentlyActive ? `Live Tracking` : '

Logs

'; return `
${statusText}
${va.name}
${va.email || 'N/A'}
${activeProject} ${projectsAssigned} Projects ${workedTime} ${viewLink} `; } // Load dashboard data async function loadDashboardData() { try { const response = await fetchWithAuth(`${API_BASE}/dashboard`); if (!response) return; const result = await response.json(); if (result.success) { const data = result.data; const summary = result.summary; // Update stats cards document.getElementById('activeVaCount').textContent = summary.activeVAs || 0; document.getElementById('totalVaCount').textContent = summary.totalVAs || 0; document.getElementById('totalProjects').textContent = summary.totalProjects || 0; // Update VA list count document.getElementById('vaListCount').textContent = `${summary.totalVAs || 0} VAs`; // Update VA table const vaTableBody = document.getElementById('vaTableBody'); const vaEmptyState = document.getElementById('vaEmptyState'); const allVAs = data.allVAs || []; if (allVAs.length > 0) { vaTableBody.innerHTML = allVAs.map(va => createVATableRow(va)).join(''); vaTableBody.style.display = ''; vaEmptyState.style.display = 'none'; // Store VA data globally for modal access window.vaData = allVAs; // Add click event listeners to VA rows document.querySelectorAll('.va-row').forEach((row, index) => { row.addEventListener('click', function (e) { // Don't open modal if clicking on view link if (!e.target.closest('.view-link')) { const va = allVAs[index]; openVAModal(va); } }); }); } else { vaTableBody.innerHTML = ''; vaTableBody.style.display = 'none'; vaEmptyState.style.display = 'block'; } } else { console.error('Failed to load dashboard data:', result.message); showError('Failed to load dashboard data'); } } catch (error) { console.error('Error loading dashboard data:', error); showError('Error loading dashboard data'); } } // Show error message function showError(message) { const vaTableBody = document.getElementById('vaTableBody'); const vaEmptyState = document.getElementById('vaEmptyState'); vaTableBody.style.display = 'none'; vaEmptyState.innerHTML = `

Error

${message}

`; vaEmptyState.style.display = 'block'; } // Close modal when clicking outside vaModal.addEventListener('click', (e) => { if (e.target === vaModal) { closeVAModal(); } }); // Close modal with escape key document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && vaModal.style.display === 'flex') { closeVAModal(); } }); // Optional: Auto-refresh data every 30 seconds setInterval(loadDashboardData, 30000); // Logout Modal Functions function openLogoutModal() { const modal = document.getElementById('logoutModal'); modal.style.display = 'flex'; document.body.style.overflow = 'hidden'; } function closeLogoutModal() { const modal = document.getElementById('logoutModal'); modal.style.display = 'none'; document.body.style.overflow = 'auto'; } document.addEventListener('DOMContentLoaded', function () { // Load dashboard data loadDashboardData(); // Mobile menu toggle const menuToggle = document.querySelector('.mobile-menu-button'); const sidebar = document.querySelector('.dashboard-sidebar'); menuToggle.addEventListener('click', () => { sidebar.classList.toggle('active'); }); // Close modal with escape key document.addEventListener('keydown', function (e) { if (e.key === 'Escape') { closeLogoutModal(); } }); document.getElementById('logoutModal').addEventListener('click', function (e) { if (e.target === this) { closeLogoutModal(); } }); // Logout button - opens confirmation modal instead of directly logging out document.getElementById('logoutButton').addEventListener('click', openLogoutModal); // Confirm logout button document.getElementById('confirmLogoutBtn').addEventListener('click', handleLogout); });