// public/js/dashboard.js $(document).ready(function() { function fetchDashboardStats() { $.ajax({ url: base_url + '/api/dashboard/stats', method: 'GET', dataType: 'json', success: function(response) { // 1. Update the Grand Totals // toLocaleString() adds thousands separators for large numbers $('#grand-total').text(response.summary.total.toLocaleString()); $('#grand-active').text(response.summary.active.toLocaleString()); $('#grand-inactive').text(response.summary.inactive.toLocaleString()); // 2. Clear the loading spinner let container = $('#service-cards-container'); container.empty(); // 3. Generate Individual Service Cards if (response.services.length === 0) { container.html('
No subscription services configured yet.
'); return; } response.services.forEach(function(service) { // Handle edge cases where total is 0 to avoid division by zero let activeRate = service.total_subscribers > 0 ? Math.round((service.active_subscribers / service.total_subscribers) * 100) : 0; let cardHtml = `
${service.name}
Total ${service.total_subscribers.toLocaleString()}
Active ${service.active_subscribers.toLocaleString()}
Active Rate ${activeRate}%
`; container.append(cardHtml); }); }, error: function(xhr) { $('#loading-services').html(`
Failed to load dashboard statistics. Please try refreshing the page.
`); // Set fallback text for the totals $('#grand-total, #grand-active, #grand-inactive').text('Error'); } }); } // Initialize the fetch fetchDashboardStats(); // Todo: Refresh data every 5 minutes (300000 ms) automatically without page reload // setInterval(fetchDashboardStats, 300000); $('#syncTriggerBtn').on('click', function() { let btn = $(this); let icon = $('#syncIcon'); let text = $('#syncText'); // Disable button and add spinning effect btn.prop('disabled', true); icon.addClass('spinner-border spinner-border-sm'); text.text('Syncing...'); $.ajax({ url: base_url + '/api/subscriptions/sync', method: 'POST', data: { _token: $('meta[name="csrf-token"]').attr('content') }, success: function(response) { // Use SweetAlert2 for a clean success alert Swal.fire({ icon: 'success', title: 'Synchronized!', text: response.message, timer: 2000, showConfirmButton: false }); // Refresh dashboard data instantly to reflect updated counts fetchDashboardStats(); }, error: function(xhr) { let errorMsg = xhr.responseJSON && xhr.responseJSON.message ? xhr.responseJSON.message : 'An unexpected error occurred during synchronization.'; Swal.fire({ icon: 'error', title: 'Sync Failed', text: errorMsg }); }, complete: function() { // Restore button state btn.prop('disabled', false); icon.removeClass('spinner-border spinner-border-sm'); text.text('Sync Now'); } }); }); });