document.addEventListener('DOMContentLoaded', function() { // Initialize variables let currentPage = 1; let totalPages = parseInt(document.getElementById('totalPages').textContent) || 1; let isFetching = false; // Get filter elements const notifTypeFilter = document.getElementById('notifTypeFilter'); const dateRangeFilter = document.getElementById('dateRangeFilter'); const clearFiltersBtn = document.getElementById('clearFilters'); const markAllReadBtn = document.getElementById('markAllRead'); // Get pagination elements const prevPageBtn = document.getElementById('prevPage'); const nextPageBtn = document.getElementById('nextPage'); const currentPageSpan = document.getElementById('currentPage'); const totalPagesSpan = document.getElementById('totalPages'); const notifsTableBody = document.getElementById('notifsTableBody'); // Notification details modal const notifDetailsModal = document.getElementById('notifDetailsModal'); const notifDetailsContent = document.getElementById('notifDetailsContent'); // Function to update URL with current filters function updateURL() { const params = new URLSearchParams(window.location.search); params.set('notif_type', notifTypeFilter.value); params.set('date_range', dateRangeFilter.value); params.set('page', currentPage); window.history.replaceState({}, '', `${window.location.pathname}?${params.toString()}`); } // Function to fetch notifications function fetchNotifications() { if (isFetching) return; isFetching = true; // Show loading state notifsTableBody.innerHTML = 'Loading...'; const params = new URLSearchParams({ notif_type: notifTypeFilter.value, date_range: dateRangeFilter.value, page: currentPage, ajax: 'true' }); fetch(`${window.location.pathname}?${params.toString()}`, { headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.text(); }) .then(html => { const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const newTableBody = doc.getElementById('notifsTableBody'); if (newTableBody) { notifsTableBody.innerHTML = newTableBody.innerHTML; // Update pagination const newCurrentPage = parseInt(doc.getElementById('currentPage').textContent); const newTotalPages = parseInt(doc.getElementById('totalPages').textContent); currentPage = newCurrentPage; totalPages = newTotalPages; currentPageSpan.textContent = currentPage; totalPagesSpan.textContent = totalPages; // Update pagination buttons prevPageBtn.disabled = currentPage === 1; nextPageBtn.disabled = currentPage === totalPages; // Update URL updateURL(); // Reattach event listeners attachEventListeners(); } else { console.error('Could not find notifications table in response'); notifsTableBody.innerHTML = 'Error loading notifications'; } }) .catch(error => { console.error('Error fetching notifications:', error); notifsTableBody.innerHTML = 'Error loading notifications'; }) .finally(() => { isFetching = false; }); } // Function to get notification type badge function getNotifTypeBadge(type) { const badges = { 'account_created': 'Account Created', 'password_reset': 'Password Reset', 'account_deleted': 'Account Deleted', 'account_updated': 'Account Updated', 'room_invite': 'Room Invite', 'room_invite_removed': 'Room Invite Removed', 'conversation_invite': 'Conversation Invite', 'conversation_invite_removed': 'Conversation Invite Removed', 'conversation_message': 'Conversation Message' }; return badges[type] || `${type}`; } // Function to load notification details function loadNotifDetails(notifId) { fetch(`/api/notifications/${notifId}`) .then(response => response.json()) .then(data => { const detailsContent = document.getElementById('notifDetailsContent'); if (data.details) { detailsContent.textContent = JSON.stringify(data.details, null, 2); } else { detailsContent.textContent = 'No additional details available'; } }) .catch(error => { console.error('Error loading notification details:', error); document.getElementById('notifDetailsContent').textContent = 'Error loading notification details'; }); } // Function to mark notification as read function markAsRead(notifId) { fetch(`/api/notifications/${notifId}/read`, { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest', 'Content-Type': 'application/json' } }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { if (data.success) { fetchNotifications(); } }) .catch(error => { console.error('Error marking notification as read:', error); }); } // Function to delete notification function deleteNotification(notifId) { if (!confirm('Are you sure you want to delete this notification?')) { return; } fetch(`/api/notifications/${notifId}`, { method: 'DELETE', headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { if (data.success) { fetchNotifications(); } }) .catch(error => { console.error('Error deleting notification:', error); }); } // Function to mark all notifications as read function markAllAsRead() { fetch('/api/notifications/mark-all-read', { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { if (data.success) { fetchNotifications(); } }) .catch(error => { console.error('Error marking all notifications as read:', error); }); } // Function to attach event listeners function attachEventListeners() { // Mark as read buttons document.querySelectorAll('.mark-read').forEach(btn => { btn.addEventListener('click', (e) => { const notifId = e.target.closest('.mark-read').dataset.notifId; markAsRead(notifId); }); }); // Delete buttons document.querySelectorAll('.delete-notif').forEach(btn => { btn.addEventListener('click', (e) => { const notifId = e.target.closest('.delete-notif').dataset.notifId; deleteNotification(notifId); }); }); // View details buttons document.querySelectorAll('[data-bs-target="#notifDetailsModal"]').forEach(btn => { btn.addEventListener('click', (e) => { const notifId = e.target.closest('[data-notif-id]').dataset.notifId; loadNotifDetails(notifId); }); }); } // Add event listeners for filters with debounce let filterTimeout; function debouncedFetch() { clearTimeout(filterTimeout); filterTimeout = setTimeout(() => { currentPage = 1; // Reset to first page when filters change fetchNotifications(); }, 300); } notifTypeFilter.addEventListener('change', debouncedFetch); dateRangeFilter.addEventListener('change', debouncedFetch); // Add event listener for clear filters clearFiltersBtn.addEventListener('click', () => { notifTypeFilter.value = ''; dateRangeFilter.value = '7d'; currentPage = 1; fetchNotifications(); }); // Add event listener for mark all as read markAllReadBtn.addEventListener('click', markAllAsRead); // Add event listeners for pagination prevPageBtn.addEventListener('click', () => { if (currentPage > 1) { currentPage--; fetchNotifications(); } }); nextPageBtn.addEventListener('click', () => { if (currentPage < totalPages) { currentPage++; fetchNotifications(); } }); // Initialize filters from URL parameters const params = new URLSearchParams(window.location.search); notifTypeFilter.value = params.get('notif_type') || ''; dateRangeFilter.value = params.get('date_range') || '7d'; currentPage = parseInt(params.get('page')) || 1; // Initial fetch if filters are set if (notifTypeFilter.value || dateRangeFilter.value !== '7d') { fetchNotifications(); } // Attach initial event listeners attachEventListeners(); });