- 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); |