- Fixed critical security vulnerability with incorrect capability checks - Fixed hardcoded redirect path from /community-login/ to /training-login/ - Moved dashboard shortcode registration to centralized location - Fixed duplicate class loading with proper singleton checks - Fixed incorrect edit URLs in dashboard - Removed debug HTML comments from production templates - Moved inline CSS to external stylesheets for better maintainability - Added caching mechanism for dashboard statistics queries (1 hour cache) - Implemented pagination JavaScript handlers for AJAX navigation - Added comprehensive error handling and logging throughout - Fixed role-based access control (checking roles not capabilities) - Improved performance with cached database queries
		
			
				
	
	
		
			203 lines
		
	
	
		
			No EOL
		
	
	
		
			7.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			203 lines
		
	
	
		
			No EOL
		
	
	
		
			7.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  * HVAC Trainer Dashboard JavaScript
 | |
|  * 
 | |
|  * Handles dynamic filtering of events table and other interactive features.
 | |
|  */
 | |
| (function($) {
 | |
|     'use strict';
 | |
| 
 | |
|     // Initialize the dashboard when DOM is ready
 | |
|     $(document).ready(function() {
 | |
|         initEventFilters();
 | |
|         initPaginationHandlers();
 | |
|     });
 | |
| 
 | |
|     /**
 | |
|      * Initialize event filters to work without page reload
 | |
|      */
 | |
|     function initEventFilters() {
 | |
|         // Get the events table wrapper element
 | |
|         const $eventsTableWrapper = $('.hvac-events-table-wrapper');
 | |
|         
 | |
|         // Add click handler to filter links
 | |
|         $('.hvac-event-filters a').on('click', function(e) {
 | |
|             e.preventDefault(); // Prevent default link behavior (page reload)
 | |
|             
 | |
|             // Get the status filter from the link URL
 | |
|             const url = new URL($(this).attr('href'), window.location.origin);
 | |
|             const status = url.searchParams.get('event_status') || 'all';
 | |
|             
 | |
|             // Update active class
 | |
|             $('.hvac-event-filters a').removeClass('hvac-filter-active ast-button-primary').addClass('ast-button-secondary');
 | |
|             $(this).addClass('hvac-filter-active ast-button-primary').removeClass('ast-button-secondary');
 | |
|             
 | |
|             // Show loading indicator
 | |
|             $eventsTableWrapper.append('<div class="hvac-loading">Filtering events...</div>');
 | |
|             
 | |
|             // Make AJAX request to get filtered events
 | |
|             $.ajax({
 | |
|                 url: hvac_dashboard.ajax_url,
 | |
|                 type: 'POST',
 | |
|                 data: {
 | |
|                     action: 'hvac_filter_events',
 | |
|                     status: status,
 | |
|                     nonce: hvac_dashboard.nonce
 | |
|                 },
 | |
|                 success: function(response) {
 | |
|                     if (response.success) {
 | |
|                         // Replace the table HTML with the filtered results
 | |
|                         $eventsTableWrapper.html(response.data.html);
 | |
|                         
 | |
|                         // Update the URL without reloading the page
 | |
|                         if (history.pushState) {
 | |
|                             const newUrl = status === 'all' 
 | |
|                                 ? removeURLParameter(window.location.href, 'event_status')
 | |
|                                 : addURLParameter(window.location.href, 'event_status', status);
 | |
|                             window.history.pushState({ path: newUrl }, '', newUrl);
 | |
|                         }
 | |
|                     } else {
 | |
|                         // Show error message
 | |
|                         $eventsTableWrapper.find('.hvac-loading').remove();
 | |
|                         $eventsTableWrapper.append('<div class="hvac-error">Error loading events: ' + response.data.message + '</div>');
 | |
|                     }
 | |
|                 },
 | |
|                 error: function() {
 | |
|                     // Show error message
 | |
|                     $eventsTableWrapper.find('.hvac-loading').remove();
 | |
|                     $eventsTableWrapper.append('<div class="hvac-error">Error communicating with server.</div>');
 | |
|                 }
 | |
|             });
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Helper function to add a URL parameter
 | |
|      */
 | |
|     function addURLParameter(url, key, value) {
 | |
|         const re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
 | |
|         const separator = url.indexOf('?') !== -1 ? "&" : "?";
 | |
|         
 | |
|         if (url.match(re)) {
 | |
|             return url.replace(re, '$1' + key + "=" + value + '$2');
 | |
|         } else {
 | |
|             return url + separator + key + "=" + value;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Helper function to remove a URL parameter
 | |
|      */
 | |
|     function removeURLParameter(url, parameter) {
 | |
|         const urlParts = url.split('?');
 | |
|         if (urlParts.length < 2) {
 | |
|             return url;
 | |
|         }
 | |
|         
 | |
|         const urlBase = urlParts[0];
 | |
|         const queryString = urlParts[1];
 | |
|         const prefix = encodeURIComponent(parameter) + '=';
 | |
|         const parts = queryString.split(/[&;]/g);
 | |
|         
 | |
|         // Reverse iteration to safely remove items
 | |
|         for (let i = parts.length; i-- > 0;) {
 | |
|             if (parts[i].lastIndexOf(prefix, 0) !== -1) {
 | |
|                 parts.splice(i, 1);
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         const newQueryString = parts.join('&');
 | |
|         return newQueryString.length > 0 ? urlBase + '?' + newQueryString : urlBase;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Initialize pagination handlers for events table
 | |
|      */
 | |
|     function initPaginationHandlers() {
 | |
|         // Delegate click handlers to handle dynamically loaded content
 | |
|         $(document).on('click', '.hvac-events-table-wrapper .pagination-links a', function(e) {
 | |
|             e.preventDefault();
 | |
|             
 | |
|             const $link = $(this);
 | |
|             const page = $link.data('page');
 | |
|             
 | |
|             if (!page || $link.hasClass('disabled')) {
 | |
|                 return;
 | |
|             }
 | |
|             
 | |
|             loadEventsPage(page);
 | |
|         });
 | |
|         
 | |
|         // Handle page number input
 | |
|         $(document).on('keypress', '.hvac-events-table-wrapper .current-page', function(e) {
 | |
|             if (e.which === 13) { // Enter key
 | |
|                 e.preventDefault();
 | |
|                 const page = parseInt($(this).val());
 | |
|                 const maxPage = parseInt($(this).closest('.pagination-links').find('.total-pages').text());
 | |
|                 
 | |
|                 if (page && page > 0 && page <= maxPage) {
 | |
|                     loadEventsPage(page);
 | |
|                 }
 | |
|             }
 | |
|         });
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Load a specific page of events
 | |
|      */
 | |
|     function loadEventsPage(page) {
 | |
|         const $eventsTableWrapper = $('.hvac-events-table-wrapper');
 | |
|         
 | |
|         // Get current filter status
 | |
|         const $activeFilter = $('.hvac-event-filters .hvac-filter-active');
 | |
|         const filterUrl = $activeFilter.length ? $activeFilter.attr('href') : '';
 | |
|         const url = new URL(filterUrl || window.location.href, window.location.origin);
 | |
|         const status = url.searchParams.get('event_status') || 'all';
 | |
|         
 | |
|         // Show loading indicator
 | |
|         $eventsTableWrapper.append('<div class="hvac-loading">Loading page...</div>');
 | |
|         
 | |
|         // Make AJAX request to get the requested page
 | |
|         $.ajax({
 | |
|             url: hvac_dashboard.ajax_url,
 | |
|             type: 'POST',
 | |
|             data: {
 | |
|                 action: 'hvac_filter_events',
 | |
|                 status: status,
 | |
|                 page: page,
 | |
|                 nonce: hvac_dashboard.nonce
 | |
|             },
 | |
|             success: function(response) {
 | |
|                 if (response.success) {
 | |
|                     // Replace the table HTML with the new page
 | |
|                     $eventsTableWrapper.html(response.data.html);
 | |
|                     
 | |
|                     // Update the URL with the new page number
 | |
|                     if (history.pushState) {
 | |
|                         let newUrl = window.location.href;
 | |
|                         if (page > 1) {
 | |
|                             newUrl = addURLParameter(newUrl, 'paged', page);
 | |
|                         } else {
 | |
|                             newUrl = removeURLParameter(newUrl, 'paged');
 | |
|                         }
 | |
|                         window.history.pushState({ path: newUrl }, '', newUrl);
 | |
|                     }
 | |
|                     
 | |
|                     // Scroll to top of table
 | |
|                     $('html, body').animate({
 | |
|                         scrollTop: $eventsTableWrapper.offset().top - 100
 | |
|                     }, 300);
 | |
|                 } else {
 | |
|                     // Show error message
 | |
|                     $eventsTableWrapper.find('.hvac-loading').remove();
 | |
|                     $eventsTableWrapper.append('<div class="hvac-error">Error loading page: ' + response.data.message + '</div>');
 | |
|                 }
 | |
|             },
 | |
|             error: function() {
 | |
|                 // Show error message
 | |
|                 $eventsTableWrapper.find('.hvac-loading').remove();
 | |
|                 $eventsTableWrapper.append('<div class="hvac-error">Error communicating with server.</div>');
 | |
|             }
 | |
|         });
 | |
|     }
 | |
| 
 | |
| })(jQuery); |