upskill-event-manager/assets/js/hvac-master-pending-approvals.js
Ben a74c273b1d feat: complete master trainer area audit and implementation
Systematic audit and implementation of missing Master Trainer functionality
with comprehensive WordPress best practices and security implementation.

## Features Implemented
- Master Events Overview (/master-trainer/events/) - KPI dashboard with filtering
- Import/Export Data Management (/master-trainer/import-export/) - CSV operations
- Communication Templates (/trainer/communication-templates/) - Professional templates
- Enhanced Announcements (/master-trainer/announcements/) - Dynamic shortcode integration
- Pending Approvals System (/master-trainer/pending-approvals/) - Workflow management

## Navigation & UX Improvements
- Removed redundant Events link from top-level navigation menu
- Reorganized administrative functions under Tools dropdown
- Enhanced navigation clarity and professional appearance
- Full responsive design with accessibility compliance

## Architecture & Security
- 5 new singleton manager classes following WordPress patterns
- Comprehensive role-based access control (hvac_master_trainer)
- Complete security implementation (nonces, sanitization, escaping)
- Performance optimizations with transient caching and conditional loading
- Professional error handling and user feedback systems

## Files Added (16 new files)
- 4 manager classes: Import/Export, Events Overview, Pending Approvals, Communication Templates
- 4 CSS files with responsive design and accessibility features
- 4 JavaScript files with AJAX functionality and error handling
- 2 new templates: Import/Export, Pending Approvals
- 2 enhanced templates: Events Overview, Communication Templates

## Files Modified (14 files)
- Core system integration in Plugin, Page Manager, Scripts/Styles classes
- Navigation system cleanup in Master Menu System
- Enhanced access control and role management
- Template updates for dynamic content integration

## Testing & Deployment
- Comprehensive testing with Playwright automation
- Successful staging deployment and verification
- All 5 missing pages now fully functional
- Navigation improvements verified working

Resolves master trainer area audit requirements with production-ready implementation.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-23 09:56:42 -03:00

428 lines
No EOL
17 KiB
JavaScript

/**
* HVAC Master Pending Approvals JavaScript
*
* Handles interactive functionality for the pending approvals interface
*/
(function($) {
'use strict';
window.HVAC_PendingApprovals = {
init: function() {
this.bindEvents();
this.initializeSelectors();
},
bindEvents: function() {
// Individual approve/reject buttons
$(document).on('click', '.hvac-approve-btn', this.handleIndividualApprove);
$(document).on('click', '.hvac-reject-btn', this.handleIndividualReject);
// Trainer name buttons (show details modal)
$(document).on('click', '.hvac-trainer-name-btn', this.handleShowDetails);
// Select all checkboxes
$(document).on('change', '#hvac-select-all, #hvac-header-select-all', this.handleSelectAll);
// Individual trainer checkboxes
$(document).on('change', '.hvac-trainer-select', this.handleTrainerSelect);
// Bulk action buttons
$(document).on('click', '#hvac-bulk-approve', this.handleBulkApprove);
$(document).on('click', '#hvac-bulk-reject', this.handleBulkReject);
// Modal controls
$(document).on('click', '.hvac-modal-close', this.hideModal);
$(document).on('click', '.hvac-modal', this.handleModalBackdropClick);
// Reason modal confirm button
$(document).on('click', '#hvac-confirm-reason-action', this.handleConfirmReasonAction);
// Bulk action modal confirm button
$(document).on('click', '#hvac-confirm-bulk-action', this.handleConfirmBulkAction);
// Filter form auto-submit on select changes
$(document).on('change', '#status_filter, #region_filter', function() {
$(this).closest('form').submit();
});
// ESC key to close modals
$(document).on('keydown', this.handleKeydown);
},
initializeSelectors: function() {
this.updateBulkActionButtons();
},
handleIndividualApprove: function(e) {
e.preventDefault();
const userId = $(this).data('user-id');
const trainerName = $(this).closest('tr').find('.hvac-trainer-name-btn').text();
HVAC_PendingApprovals.showReasonModal(userId, 'approve', 'Approve ' + trainerName);
},
handleIndividualReject: function(e) {
e.preventDefault();
const userId = $(this).data('user-id');
const trainerName = $(this).closest('tr').find('.hvac-trainer-name-btn').text();
HVAC_PendingApprovals.showReasonModal(userId, 'reject', 'Reject ' + trainerName);
},
handleShowDetails: function(e) {
e.preventDefault();
const userId = $(this).data('user-id');
HVAC_PendingApprovals.showTrainerDetails(userId);
},
handleSelectAll: function(e) {
const isChecked = $(this).is(':checked');
$('.hvac-trainer-select').prop('checked', isChecked);
// Sync both select-all checkboxes
$('#hvac-select-all, #hvac-header-select-all').prop('checked', isChecked);
HVAC_PendingApprovals.updateBulkActionButtons();
},
handleTrainerSelect: function(e) {
HVAC_PendingApprovals.updateBulkActionButtons();
// Update select-all checkboxes
const totalCheckboxes = $('.hvac-trainer-select').length;
const checkedCheckboxes = $('.hvac-trainer-select:checked').length;
$('#hvac-select-all, #hvac-header-select-all').prop('checked', totalCheckboxes === checkedCheckboxes);
},
handleBulkApprove: function(e) {
e.preventDefault();
const selectedIds = HVAC_PendingApprovals.getSelectedTrainerIds();
if (selectedIds.length === 0) {
alert('Please select trainers to approve.');
return;
}
HVAC_PendingApprovals.showBulkActionModal(selectedIds, 'approve');
},
handleBulkReject: function(e) {
e.preventDefault();
const selectedIds = HVAC_PendingApprovals.getSelectedTrainerIds();
if (selectedIds.length === 0) {
alert('Please select trainers to reject.');
return;
}
HVAC_PendingApprovals.showBulkActionModal(selectedIds, 'reject');
},
handleModalBackdropClick: function(e) {
if (e.target === this) {
HVAC_PendingApprovals.hideModal();
}
},
handleKeydown: function(e) {
if (e.key === 'Escape') {
HVAC_PendingApprovals.hideModal();
}
},
handleConfirmReasonAction: function(e) {
e.preventDefault();
const userId = $('#hvac-reason-user-id').val();
const action = $('#hvac-reason-action').val();
const reason = $('#hvac-approval-reason').val();
if (action === 'approve') {
HVAC_PendingApprovals.approveTrainer(userId, reason);
} else if (action === 'reject') {
HVAC_PendingApprovals.rejectTrainer(userId, reason);
}
HVAC_PendingApprovals.hideModal();
},
handleConfirmBulkAction: function(e) {
e.preventDefault();
const action = $('#hvac-bulk-action-type').val();
const reason = $('#hvac-bulk-reason').val();
const selectedIds = HVAC_PendingApprovals.getSelectedTrainerIds();
HVAC_PendingApprovals.performBulkAction(selectedIds, action, reason);
HVAC_PendingApprovals.hideModal();
},
showReasonModal: function(userId, action, title) {
$('#hvac-reason-modal-title').text(title);
$('#hvac-reason-user-id').val(userId);
$('#hvac-reason-action').val(action);
$('#hvac-approval-reason').val('');
// Update button text and color
const confirmBtn = $('#hvac-confirm-reason-action');
if (action === 'approve') {
confirmBtn.text('Approve').removeClass('hvac-btn-danger').addClass('hvac-btn-success');
} else {
confirmBtn.text('Reject').removeClass('hvac-btn-success').addClass('hvac-btn-danger');
}
this.showModal('#hvac-approval-reason-modal');
},
showBulkActionModal: function(userIds, action) {
const actionText = action === 'approve' ? 'approve' : 'reject';
const count = userIds.length;
$('#hvac-bulk-modal-title').text('Bulk ' + actionText.charAt(0).toUpperCase() + actionText.slice(1));
$('#hvac-bulk-action-type').val(action);
$('#hvac-bulk-reason').val('');
$('#hvac-bulk-action-message').text(`Are you sure you want to ${actionText} ${count} trainer(s)?`);
// Update button text and color
const confirmBtn = $('#hvac-confirm-bulk-action');
if (action === 'approve') {
confirmBtn.text('Approve All').removeClass('hvac-btn-danger').addClass('hvac-btn-success');
} else {
confirmBtn.text('Reject All').removeClass('hvac-btn-success').addClass('hvac-btn-danger');
}
this.showModal('#hvac-bulk-action-modal');
},
showTrainerDetails: function(userId) {
$('#hvac-trainer-details-content').html('Loading...');
this.showModal('#hvac-trainer-details-modal');
$.ajax({
url: hvac_ajax.ajax_url,
type: 'POST',
data: {
action: 'hvac_get_trainer_details',
user_id: userId,
nonce: hvac_ajax.nonce
},
success: function(response) {
if (response.success) {
$('#hvac-trainer-details-content').html(response.data.html);
} else {
$('#hvac-trainer-details-content').html('<p class="error">Failed to load trainer details: ' + response.data.message + '</p>');
}
},
error: function() {
$('#hvac-trainer-details-content').html('<p class="error">Failed to load trainer details. Please try again.</p>');
}
});
},
approveTrainer: function(userId, reason) {
this.showLoading();
$.ajax({
url: hvac_ajax.ajax_url,
type: 'POST',
data: {
action: 'hvac_approve_trainer',
user_id: userId,
reason: reason,
nonce: hvac_ajax.nonce
},
success: function(response) {
HVAC_PendingApprovals.hideLoading();
if (response.success) {
HVAC_PendingApprovals.showSuccessMessage(response.data.message);
HVAC_PendingApprovals.updateTrainerRow(userId, 'approved');
} else {
HVAC_PendingApprovals.showErrorMessage(response.data.message);
}
},
error: function() {
HVAC_PendingApprovals.hideLoading();
HVAC_PendingApprovals.showErrorMessage('Failed to approve trainer. Please try again.');
}
});
},
rejectTrainer: function(userId, reason) {
this.showLoading();
$.ajax({
url: hvac_ajax.ajax_url,
type: 'POST',
data: {
action: 'hvac_reject_trainer',
user_id: userId,
reason: reason,
nonce: hvac_ajax.nonce
},
success: function(response) {
HVAC_PendingApprovals.hideLoading();
if (response.success) {
HVAC_PendingApprovals.showSuccessMessage(response.data.message);
HVAC_PendingApprovals.updateTrainerRow(userId, 'rejected');
} else {
HVAC_PendingApprovals.showErrorMessage(response.data.message);
}
},
error: function() {
HVAC_PendingApprovals.hideLoading();
HVAC_PendingApprovals.showErrorMessage('Failed to reject trainer. Please try again.');
}
});
},
performBulkAction: function(userIds, action, reason) {
this.showLoading();
$.ajax({
url: hvac_ajax.ajax_url,
type: 'POST',
data: {
action: 'hvac_bulk_trainer_action',
user_ids: userIds,
action: action,
reason: reason,
nonce: hvac_ajax.nonce
},
success: function(response) {
HVAC_PendingApprovals.hideLoading();
if (response.success) {
HVAC_PendingApprovals.showSuccessMessage(response.data.message);
// Update each trainer row
const newStatus = action === 'approve' ? 'approved' : 'rejected';
userIds.forEach(function(userId) {
if (response.data.results[userId] === 'success') {
HVAC_PendingApprovals.updateTrainerRow(userId, newStatus);
}
});
// Clear selections
$('.hvac-trainer-select, #hvac-select-all, #hvac-header-select-all').prop('checked', false);
HVAC_PendingApprovals.updateBulkActionButtons();
} else {
HVAC_PendingApprovals.showErrorMessage(response.data.message);
}
},
error: function() {
HVAC_PendingApprovals.hideLoading();
HVAC_PendingApprovals.showErrorMessage('Failed to perform bulk action. Please try again.');
}
});
},
updateTrainerRow: function(userId, newStatus) {
const row = $('tr[data-user-id="' + userId + '"]');
if (row.length) {
// Update status badge
const statusCell = row.find('.hvac-col-status');
const statusBadges = {
'approved': '<span class="hvac-status-badge hvac-status-approved">Approved</span>',
'rejected': '<span class="hvac-status-badge hvac-status-rejected">Rejected</span>'
};
statusCell.html(statusBadges[newStatus] || newStatus);
// Update actions cell
const actionsCell = row.find('.hvac-col-actions');
actionsCell.html('<span class="hvac-status-text">' + newStatus.charAt(0).toUpperCase() + newStatus.slice(1) + '</span>');
// Remove checkbox column if it exists
row.find('.hvac-col-select').remove();
// Add visual feedback
row.addClass('hvac-row-updated').delay(3000).queue(function() {
$(this).removeClass('hvac-row-updated').dequeue();
});
}
},
getSelectedTrainerIds: function() {
const ids = [];
$('.hvac-trainer-select:checked').each(function() {
ids.push($(this).val());
});
return ids;
},
updateBulkActionButtons: function() {
const selectedCount = $('.hvac-trainer-select:checked').length;
const bulkButtons = $('#hvac-bulk-approve, #hvac-bulk-reject');
if (selectedCount > 0) {
bulkButtons.prop('disabled', false);
} else {
bulkButtons.prop('disabled', true);
}
},
showModal: function(modalSelector) {
$(modalSelector).fadeIn(300);
$('body').addClass('hvac-modal-open');
},
hideModal: function() {
$('.hvac-modal').fadeOut(300);
$('body').removeClass('hvac-modal-open');
},
showLoading: function() {
if ($('#hvac-loading-overlay').length === 0) {
$('body').append('<div id="hvac-loading-overlay"><div class="hvac-loading-spinner"></div></div>');
}
$('#hvac-loading-overlay').show();
},
hideLoading: function() {
$('#hvac-loading-overlay').hide();
},
showSuccessMessage: function(message) {
this.showMessage(message, 'success');
},
showErrorMessage: function(message) {
this.showMessage(message, 'error');
},
showMessage: function(message, type) {
// Remove existing messages
$('.hvac-flash-message').remove();
// Add new message
const messageHtml = '<div class="hvac-flash-message hvac-flash-' + type + '">' + message + '</div>';
$('.hvac-pending-approvals-wrapper').prepend(messageHtml);
// Auto-remove after 5 seconds
setTimeout(function() {
$('.hvac-flash-message').fadeOut(300, function() {
$(this).remove();
});
}, 5000);
// Scroll to top to show message
$('html, body').animate({ scrollTop: 0 }, 300);
}
};
// Initialize when document is ready
$(document).ready(function() {
// Only initialize if we're on the pending approvals page
if ($('.hvac-pending-approvals-wrapper').length > 0) {
HVAC_PendingApprovals.init();
}
});
})(jQuery);