document.addEventListener('DOMContentLoaded', function() { loadStats(); checkAuthStatus(); setInterval(loadStats, 30000); }); function checkAuthStatus() { const token = localStorage.getItem('dashx_token'); if (token) { const navMenu = document.querySelector('.nav-menu'); if (navMenu) { navMenu.innerHTML = ` Dashboard Profile Logout `; } } } async function loadStats() { try { const totalUsersEl = document.getElementById('totalUsers'); const totalRequestsEl = document.getElementById('totalRequests'); const todayRequestsEl = document.getElementById('todayRequests'); if (totalUsersEl) { totalUsersEl.innerHTML = ''; } if (totalRequestsEl) { totalRequestsEl.innerHTML = ''; } if (todayRequestsEl) { todayRequestsEl.innerHTML = ''; } const response = await fetch('/api/stats', { method: 'GET', headers: { 'Content-Type': 'application/json' } }); if (response.ok) { const data = await response.json(); if (data.success && data.stats) { const stats = data.stats; if (totalUsersEl) { totalUsersEl.textContent = formatNumber(stats.totalUsers) || '0'; } if (totalRequestsEl) { totalRequestsEl.textContent = formatNumber(stats.totalRequests) || '0'; } if (todayRequestsEl) { todayRequestsEl.textContent = formatNumber(stats.todayRequests) || '0'; } animateNumbers(); } else { throw new Error(data.error || 'Failed to load stats'); } } else { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } } catch (error) { console.error('Error loading stats:', error); const totalUsersEl = document.getElementById('totalUsers'); const totalRequestsEl = document.getElementById('totalRequests'); const todayRequestsEl = document.getElementById('todayRequests'); if (totalUsersEl) totalUsersEl.textContent = '0'; if (totalRequestsEl) totalRequestsEl.textContent = '0'; if (todayRequestsEl) todayRequestsEl.textContent = '0'; } } function formatNumber(num) { if (typeof num !== 'number') return '0'; if (num >= 1000000) { return (num / 1000000).toFixed(1) + 'M'; } else if (num >= 1000) { return (num / 1000).toFixed(1) + 'K'; } return num.toLocaleString(); } function animateNumbers() { const numbers = document.querySelectorAll('.stat-number'); numbers.forEach(number => { if (number.textContent.includes('Error') || number.textContent.includes('fa-spin')) { return; } const finalText = number.textContent; let targetValue = 0; if (finalText.includes('K')) { targetValue = parseFloat(finalText) * 1000; } else if (finalText.includes('M')) { targetValue = parseFloat(finalText) * 1000000; } else { targetValue = parseInt(finalText.replace(/,/g, '')) || 0; } if (targetValue === 0) return; let current = 0; const increment = Math.max(1, Math.ceil(targetValue / 50)); number.textContent = '0'; const timer = setInterval(() => { current += increment; if (current >= targetValue) { current = targetValue; clearInterval(timer); number.textContent = finalText; } else { if (targetValue >= 1000000) { number.textContent = (current / 1000000).toFixed(1) + 'M'; } else if (targetValue >= 1000) { number.textContent = (current / 1000).toFixed(1) + 'K'; } else { number.textContent = current.toLocaleString(); } } }, 30); }); } function logout() { localStorage.removeItem('dashx_token'); localStorage.removeItem('dashx_user'); window.location.href = '/'; } function addLiveUpdates() { const statsCards = document.querySelectorAll('.stat-card'); statsCards.forEach(card => { card.addEventListener('mouseenter', () => { card.style.transform = 'translateY(-5px)'; card.style.boxShadow = '0 8px 25px rgba(0,0,0,0.15)'; }); card.addEventListener('mouseleave', () => { card.style.transform = 'translateY(0)'; card.style.boxShadow = '0 4px 12px rgba(0,0,0,0.1)'; }); }); } function addRefreshButton() { const refreshBtn = document.createElement('button'); refreshBtn.innerHTML = ''; refreshBtn.title = 'Refresh Statistics'; refreshBtn.style.cssText = ` position: fixed; bottom: 20px; right: 20px; width: 50px; height: 50px; border-radius: 50%; border: none; background: linear-gradient(45deg, #853030, #a64545); color: white; font-size: 1.2rem; cursor: pointer; box-shadow: 0 4px 12px rgba(133, 48, 48, 0.3); transition: all 0.3s ease; z-index: 1000; `; refreshBtn.addEventListener('click', () => { refreshBtn.style.transform = 'rotate(360deg)'; loadStats(); setTimeout(() => { refreshBtn.style.transform = 'rotate(0deg)'; }, 500); }); refreshBtn.addEventListener('mouseenter', () => { refreshBtn.style.transform = 'scale(1.1)'; refreshBtn.style.boxShadow = '0 6px 20px rgba(133, 48, 48, 0.4)'; }); refreshBtn.addEventListener('mouseleave', () => { refreshBtn.style.transform = 'scale(1)'; refreshBtn.style.boxShadow = '0 4px 12px rgba(133, 48, 48, 0.3)'; }); document.body.appendChild(refreshBtn); } function initializeEnhancements() { addLiveUpdates(); addRefreshButton(); } function addLoadingStates() { const style = document.createElement('style'); style.textContent = ` .loading-pulse { animation: pulse 1.5s ease-in-out infinite; } @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.5; } 100% { opacity: 1; } } .stat-card:hover .stat-number { transform: scale(1.05); transition: transform 0.2s ease; } `; document.head.appendChild(style); } function addKeyboardShortcuts() { document.addEventListener('keydown', (event) => { if (event.ctrlKey || event.metaKey) { switch (event.key) { case 'r': event.preventDefault(); loadStats(); break; case 'd': event.preventDefault(); if (localStorage.getItem('dashx_token')) { window.location.href = '/dashboard'; } break; } } if (event.key === 'F5') { event.preventDefault(); loadStats(); } }); } document.addEventListener('DOMContentLoaded', () => { setTimeout(() => { initializeEnhancements(); addLoadingStates(); addKeyboardShortcuts(); }, 1000); });