document.addEventListener('DOMContentLoaded', function() { // Initialize variables let currentPage = 1; let totalPages = parseInt(document.getElementById('totalPages').textContent) || 1; let isFetching = false; // Get filter elements const eventTypeFilter = document.getElementById('eventTypeFilter'); const dateRangeFilter = document.getElementById('dateRangeFilter'); const userFilter = document.getElementById('userFilter'); const clearFiltersBtn = document.getElementById('clearFilters'); // Get pagination elements const prevPageBtn = document.getElementById('prevPage'); const nextPageBtn = document.getElementById('nextPage'); const currentPageSpan = document.getElementById('currentPage'); const totalPagesSpan = document.getElementById('totalPages'); const eventsTableBody = document.getElementById('eventsTableBody'); // Event details modal const eventDetailsModal = document.getElementById('eventDetailsModal'); const eventDetailsContent = document.getElementById('eventDetailsContent'); // Function to update URL with current filters function updateURL() { const params = new URLSearchParams(window.location.search); params.set('tab', 'events'); params.set('page', currentPage); params.set('event_type', eventTypeFilter.value); params.set('date_range', dateRangeFilter.value); params.set('user_id', userFilter.value); window.history.replaceState({}, '', `${window.location.pathname}?${params.toString()}`); } // Function to fetch filtered events function fetchEvents() { if (isFetching) return; isFetching = true; // Show loading state eventsTableBody.innerHTML = 'Loading...'; const params = new URLSearchParams({ tab: 'events', page: currentPage, event_type: eventTypeFilter.value, date_range: dateRangeFilter.value, user_id: userFilter.value, 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('eventsTableBody'); if (newTableBody) { eventsTableBody.innerHTML = newTableBody.innerHTML; // Update pagination const newCurrentPage = parseInt(doc.getElementById('currentPage').textContent) || 1; const newTotalPages = parseInt(doc.getElementById('totalPages').textContent) || 1; currentPage = newCurrentPage; totalPages = newTotalPages; currentPageSpan.textContent = currentPage; totalPagesSpan.textContent = totalPages; // Update pagination buttons prevPageBtn.disabled = currentPage <= 1; nextPageBtn.disabled = currentPage >= totalPages; // Update URL updateURL(); } else { console.error('Could not find events table in response'); eventsTableBody.innerHTML = 'Error loading events'; } }) .catch(error => { console.error('Error fetching events:', error); eventsTableBody.innerHTML = 'Error loading events'; }) .finally(() => { isFetching = false; }); } // Function to load event details function loadEventDetails(eventId) { console.log('Loading details for event:', eventId); fetch(`/api/events/${eventId}`) .then(response => { console.log('Response status:', response.status); return response.json(); }) .then(data => { console.log('Received event data:', data); // Format the details for display const formattedDetails = {}; // Handle details separately if (data.details) { if (typeof data.details === 'object') { formattedDetails['Details'] = JSON.stringify(data.details, null, 2); } else { formattedDetails['Details'] = data.details; } } else { formattedDetails['Details'] = 'No additional details'; } // Convert to formatted string const detailsText = Object.entries(formattedDetails) .map(([key, value]) => `${key}: ${value}`) .join('\n\n'); console.log('Formatted details:', detailsText); eventDetailsContent.textContent = detailsText; }) .catch(error => { console.error('Error loading event details:', error); eventDetailsContent.textContent = 'Error loading event details. Please try again.'; }); } // Add event listeners for filters with debounce let filterTimeout; function debouncedFetch() { clearTimeout(filterTimeout); filterTimeout = setTimeout(() => { currentPage = 1; // Reset to first page when filters change fetchEvents(); }, 300); } eventTypeFilter.addEventListener('change', debouncedFetch); dateRangeFilter.addEventListener('change', debouncedFetch); userFilter.addEventListener('change', debouncedFetch); // Event listener for clear filters clearFiltersBtn.addEventListener('click', function() { eventTypeFilter.value = ''; dateRangeFilter.value = '24h'; userFilter.value = ''; currentPage = 1; fetchEvents(); }); // Event listeners for pagination prevPageBtn.addEventListener('click', function() { if (currentPage > 1) { currentPage--; fetchEvents(); } }); nextPageBtn.addEventListener('click', function() { if (currentPage < totalPages) { currentPage++; fetchEvents(); } }); // Event listener for event details modal eventDetailsModal.addEventListener('show.bs.modal', function(event) { const button = event.relatedTarget; const eventId = button.getAttribute('data-event-id'); loadEventDetails(eventId); }); // Initialize filters from URL parameters const urlParams = new URLSearchParams(window.location.search); eventTypeFilter.value = urlParams.get('event_type') || ''; dateRangeFilter.value = urlParams.get('date_range') || '24h'; userFilter.value = urlParams.get('user_id') || ''; currentPage = parseInt(urlParams.get('page')) || 1; // Initial fetch if filters are set if (eventTypeFilter.value || dateRangeFilter.value !== '24h' || userFilter.value) { fetchEvents(); } });