upskill-event-manager/assets/js/hvac-certificate-actions.js
Ben Reed cdc5ea85f4 feat: Add comprehensive CSS, JavaScript and theme asset infrastructure
Add massive collection of CSS, JavaScript and theme assets that were previously excluded:

**CSS Files (681 total):**
- HVAC plugin-specific styles (hvac-*.css): 34 files including dashboard, certificates, registration, mobile nav, accessibility fixes, animations, and welcome popup
- Theme framework files (Astra, builder systems, layouts): 200+ files
- Plugin compatibility styles (WooCommerce, WPForms, Elementor, Contact Form 7): 150+ files
- WordPress core and editor styles: 50+ files
- Responsive and RTL language support: 200+ files

**JavaScript Files (400+ total):**
- HVAC plugin functionality (hvac-*.js): 27 files including menu systems, dashboard enhancements, profile sharing, mobile responsive features, accessibility, and animations
- Framework and library files: jQuery plugins, GSAP, AOS, Swiper, Chart.js, Lottie, Isotope
- Plugin compatibility scripts: WPForms, WooCommerce, Elementor, Contact Form 7, LifterLMS
- WordPress core functionality: customizer, admin, block editor compatibility
- Third-party integrations: Stripe, SMTP, analytics, search functionality

**Assets:**
- Certificate background images and logos
- Comprehensive theme styling infrastructure
- Mobile-responsive design systems
- Cross-browser compatibility assets
- Performance-optimized minified versions

**Updated .gitignore:**
- Fixed asset directory whitelisting patterns to properly include CSS/JS/images
- Added proper directory structure recognition (!/assets/css/, !/assets/js/, etc.)
- Maintains security by excluding sensitive files while including essential assets

This commit provides the complete frontend infrastructure needed for:
- Full theme functionality and styling
- Plugin feature implementations
- Mobile responsiveness and accessibility
- Cross-browser compatibility
- Performance optimization
- Developer workflow support
2025-08-11 16:20:31 -03:00

552 lines
No EOL
22 KiB
JavaScript

/**
* Certificate Actions JavaScript
*
* Handles the AJAX interactions for certificate viewing, emailing, and revocation.
*/
(function($) {
'use strict';
// Certificate Actions
const CertificateActions = {
/**
* Initialize certificate actions
*/
init: function() {
// View certificate
$(document).on('click', '.hvac-view-certificate', this.viewCertificate);
// Email certificate
$(document).on('click', '.hvac-email-certificate', this.emailCertificate);
// Revoke certificate
$(document).on('click', '.hvac-revoke-certificate', this.revokeCertificate);
// Close certificate modal
$(document).on('click', '.hvac-modal-close, .hvac-modal-overlay', this.closeCertificateModal);
},
/**
* View certificate
*/
viewCertificate: function(e) {
e.preventDefault();
const $button = $(this);
const certificateId = $button.data('certificate-id');
// Disable button while processing
$button.prop('disabled', true).addClass('hvac-loading');
// AJAX request
$.ajax({
url: hvacCertificateData.ajaxUrl,
type: 'POST',
data: {
action: 'hvac_get_certificate_url',
certificate_id: certificateId,
nonce: hvacCertificateData.viewNonce
},
success: function(response) {
$button.prop('disabled', false).removeClass('hvac-loading');
if (response.success && response.data.url) {
// Show preview modal if it exists
if ($('#hvac-certificate-modal').length > 0) {
CertificateActions.showCertificateModal(response.data.url);
} else {
// Open in new tab
window.open(response.data.url, '_blank');
}
} else {
// Use toast notification instead of alert
if (window.HVACToast) {
HVACToast.error(response.data.message || 'Failed to get certificate URL');
} else {
alert(response.data.message || 'Error: Failed to get certificate URL');
}
}
},
error: function() {
$button.prop('disabled', false).removeClass('hvac-loading');
// Use toast notification instead of alert
if (window.HVACToast) {
HVACToast.error('Failed to connect to server');
} else {
alert('Error: Failed to connect to server');
}
}
});
},
/**
* Show certificate modal
*/
showCertificateModal: function(url) {
// Set iframe source
$('#hvac-certificate-preview').attr('src', url);
// Show modal
$('.hvac-modal-overlay').fadeIn(200);
$('#hvac-certificate-modal').fadeIn(200);
},
/**
* Close certificate modal
*/
closeCertificateModal: function(e) {
if (e.target === this || $(e.target).hasClass('hvac-modal-close')) {
$('.hvac-modal-overlay').fadeOut(200);
$('#hvac-certificate-modal').fadeOut(200);
// Clear iframe src after fade
setTimeout(function() {
$('#hvac-certificate-preview').attr('src', '');
}, 200);
}
},
/**
* Email certificate
*/
emailCertificate: function(e) {
e.preventDefault();
const $button = $(this);
const certificateId = $button.data('certificate-id');
// Confirm sending
if (!confirm('Send certificate to attendee via email?')) {
return;
}
// Disable button while processing
$button.prop('disabled', true).addClass('hvac-loading');
// AJAX request
$.ajax({
url: hvacCertificateData.ajaxUrl,
type: 'POST',
data: {
action: 'hvac_email_certificate',
certificate_id: certificateId,
nonce: hvacCertificateData.emailNonce
},
success: function(response) {
$button.prop('disabled', false).removeClass('hvac-loading');
if (response.success) {
// Use toast notification instead of alert
if (window.HVACToast) {
HVACToast.success(response.data.message || 'Certificate sent successfully');
} else {
alert(response.data.message || 'Certificate sent successfully');
}
// Update UI to indicate certificate has been emailed
const $row = $button.closest('tr');
$row.find('.hvac-certificate-emailed').text('Yes');
} else {
// Use toast notification instead of alert
if (window.HVACToast) {
HVACToast.error(response.data.message || 'Failed to send certificate');
} else {
alert(response.data.message || 'Error: Failed to send certificate');
}
}
},
error: function() {
$button.prop('disabled', false).removeClass('hvac-loading');
// Use toast notification instead of alert
if (window.HVACToast) {
HVACToast.error('Failed to connect to server');
} else {
alert('Error: Failed to connect to server');
}
}
});
},
/**
* Revoke certificate
*/
revokeCertificate: function(e) {
e.preventDefault();
const $button = $(this);
const certificateId = $button.data('certificate-id');
// Prompt for revocation reason
const reason = prompt('Please enter a reason for revoking this certificate:', '');
// If canceled
if (reason === null) {
return;
}
// Disable button while processing
$button.prop('disabled', true).addClass('hvac-loading');
// AJAX request
$.ajax({
url: hvacCertificateData.ajaxUrl,
type: 'POST',
data: {
action: 'hvac_revoke_certificate',
certificate_id: certificateId,
reason: reason,
nonce: hvacCertificateData.revokeNonce
},
success: function(response) {
$button.prop('disabled', false).removeClass('hvac-loading');
if (response.success) {
// Use toast notification instead of alert
if (window.HVACToast) {
HVACToast.success(response.data.message || 'Certificate revoked successfully');
} else {
alert(response.data.message || 'Certificate revoked successfully');
}
// Update UI to indicate certificate has been revoked
const $row = $button.closest('tr');
$row.find('.hvac-certificate-status').text('Revoked');
$row.find('.hvac-certificate-status').addClass('hvac-status-revoked');
$row.find('.hvac-certificate-revoked-date').text(response.data.revoked_date || 'Today');
// Hide revoke button, show unrevoke button if it exists
$button.hide();
$row.find('.hvac-unrevoke-certificate').show();
} else {
// Use toast notification instead of alert
if (window.HVACToast) {
HVACToast.error(response.data.message || 'Failed to revoke certificate');
} else {
alert(response.data.message || 'Error: Failed to revoke certificate');
}
}
},
error: function() {
$button.prop('disabled', false).removeClass('hvac-loading');
// Use toast notification instead of alert
if (window.HVACToast) {
HVACToast.error('Failed to connect to server');
} else {
alert('Error: Failed to connect to server');
}
}
});
}
};
// Generate Certificates AJAX functionality
const GenerateCertificates = {
/**
* Initialize generate certificates functionality
*/
init: function() {
// Event selection
$(document).on('change', '#event_id', this.loadAttendees);
// Certificate generation (use event delegation for dynamic form)
$(document).on('submit', '#generate-certificates-form', this.generateCertificates);
// Helper buttons (use event delegation for dynamic buttons)
$(document).on('click', '#select-all-attendees', this.selectAllAttendees);
$(document).on('click', '#select-checked-in', this.selectCheckedInAttendees);
$(document).on('click', '#deselect-all-attendees', this.deselectAllAttendees);
// Certificate preview (use event delegation for dynamic buttons)
$(document).on('click', '.hvac-preview-certificate', this.showCertificatePreview);
$(document).on('click', '.hvac-modal-close', this.closeCertificatePreview);
$(document).on('click', '#hvac-certificate-preview-modal', function(e) {
if (e.target === this) {
GenerateCertificates.closeCertificatePreview(e);
}
});
},
/**
* Load attendees via AJAX when event is selected
*/
loadAttendees: function(e) {
const eventId = $(this).val();
if (!eventId) {
$('#step-select-attendees').hide();
return;
}
// Show loading
$('#attendees-loading').show();
$('#attendees-content').hide();
$.ajax({
url: hvacCertificateData.ajaxUrl,
type: 'POST',
data: {
action: 'hvac_get_event_attendees',
event_id: eventId,
nonce: hvacCertificateData.generateNonce
},
success: function(response) {
if (response.success) {
GenerateCertificates.renderAttendees(response.data.attendees, response.data.event_title);
$('#step-select-attendees').show();
} else {
// Use toast notification instead of alert
if (window.HVACToast) {
HVACToast.error(response.data.message);
} else {
alert('Error: ' + response.data.message);
}
}
},
error: function() {
// Use toast notification instead of alert
if (window.HVACToast) {
HVACToast.error('Failed to load attendees. Please try again.');
} else {
alert('Failed to load attendees. Please try again.');
}
},
complete: function() {
$('#attendees-loading').hide();
$('#attendees-content').show();
}
});
},
/**
* Render attendees table
*/
renderAttendees: function(attendees, eventTitle) {
if (attendees.length === 0) {
$('#attendees-table-container').html('<p class="hvac-empty-state">This event has no attendees.</p>');
return;
}
let tableHtml = `
<div class="hvac-form-group">
<div class="hvac-table-actions">
<button type="button" class="hvac-button hvac-secondary" id="select-all-attendees">Select All</button>
<button type="button" class="hvac-button hvac-secondary" id="select-checked-in">Select Checked-In Only</button>
<button type="button" class="hvac-button hvac-secondary" id="deselect-all-attendees">Deselect All</button>
</div>
<div class="hvac-attendees-table-wrapper">
<table class="hvac-attendees-table">
<thead>
<tr>
<th class="hvac-checkbox-column">
<input type="checkbox" id="select-all-checkbox">
</th>
<th>Attendee</th>
<th>Email</th>
<th>Status</th>
<th>Certificate</th>
</tr>
</thead>
<tbody>
`;
attendees.forEach(function(attendee) {
const checkedInClass = attendee.check_in ? 'hvac-checked-in' : '';
const statusClass = attendee.check_in ? 'hvac-status-checked-in' : 'hvac-status-not-checked-in';
const statusText = attendee.check_in ? 'Checked In' : 'Not Checked In';
const certificateStatus = attendee.has_certificate ? 'Certificate Issued' : 'No Certificate';
const hasCertClass = attendee.has_certificate ? 'hvac-has-certificate' : '';
tableHtml += `
<tr class="${hasCertClass} ${checkedInClass}">
<td>
${!attendee.has_certificate ?
`<input type="checkbox" name="attendee_ids[]" value="${attendee.attendee_id}" class="attendee-checkbox" ${attendee.check_in ? 'checked' : ''}>` :
''
}
</td>
<td>${attendee.holder_name}</td>
<td>${attendee.holder_email}</td>
<td><span class="${statusClass}">${statusText}</span></td>
<td>${certificateStatus}</td>
</tr>
`;
});
tableHtml += `
</tbody>
</table>
</div>
</div>
`;
$('#attendees-table-container').html(tableHtml);
},
/**
* Generate certificates via AJAX
*/
generateCertificates: function(e) {
e.preventDefault();
const $form = $(this);
const formData = $form.serialize();
// Show loading
const $submitBtn = $form.find('button[type="submit"]');
$submitBtn.prop('disabled', true).text('Generating...');
// Hide previous messages
$('.hvac-success-message, .hvac-errors').remove();
$.ajax({
url: hvacCertificateData.ajaxUrl,
type: 'POST',
data: formData + '&action=hvac_generate_certificates&nonce=' + hvacCertificateData.generateNonce,
success: function(response) {
if (response.success) {
// Show success message with preview option
let successMessage = `
<div class="hvac-success-message">
<p>${response.data.message}</p>
<p><a href="/certificate-reports/" class="hvac-button hvac-primary">View All Certificates</a></p>
`;
// Add preview buttons if certificates were generated
if (response.data.preview_urls && response.data.preview_urls.length > 0) {
successMessage += '<div class="hvac-certificate-previews"><h4>Preview Generated Certificates:</h4>';
response.data.preview_urls.forEach(function(preview) {
successMessage += `
<button type="button" class="hvac-button hvac-secondary hvac-preview-certificate"
data-url="${preview.preview_url}"
data-attendee="${preview.attendee_name}">
Preview - ${preview.attendee_name}
</button>
`;
});
successMessage += '</div>';
}
successMessage += '</div>';
$form.before(successMessage);
// Reload attendees to update certificate status
$('#event_id').trigger('change');
} else {
// Show error message
$form.before(`
<div class="hvac-errors">
<p class="hvac-error">${response.data.message}</p>
</div>
`);
}
},
error: function() {
$form.before(`
<div class="hvac-errors">
<p class="hvac-error">Failed to generate certificates. Please try again.</p>
</div>
`);
},
complete: function() {
$submitBtn.prop('disabled', false).text('Generate Certificates');
}
});
},
/**
* Select all attendees
*/
selectAllAttendees: function(e) {
e.preventDefault();
$('.attendee-checkbox').prop('checked', true);
$('#select-all-checkbox').prop('checked', true);
},
/**
* Select only checked-in attendees
*/
selectCheckedInAttendees: function(e) {
e.preventDefault();
$('.attendee-checkbox').each(function() {
const $row = $(this).closest('tr');
$(this).prop('checked', $row.hasClass('hvac-checked-in'));
});
$('#select-all-checkbox').prop('checked', false);
},
/**
* Deselect all attendees
*/
deselectAllAttendees: function(e) {
e.preventDefault();
$('.attendee-checkbox').prop('checked', false);
$('#select-all-checkbox').prop('checked', false);
},
/**
* Show certificate preview modal
*/
showCertificatePreview: function(e) {
e.preventDefault();
const $button = $(this);
const url = $button.data('url');
const attendeeName = $button.data('attendee');
if (!url) {
// Use toast notification instead of alert
if (window.HVACToast) {
HVACToast.error('Preview URL not available');
} else {
alert('Preview URL not available');
}
return;
}
// Create modal if it doesn't exist
if ($('#hvac-certificate-preview-modal').length === 0) {
$('body').append(`
<div id="hvac-certificate-preview-modal" class="hvac-modal">
<div class="hvac-modal-content">
<div class="hvac-modal-header">
<h3>Certificate Preview</h3>
<span class="hvac-modal-close">&times;</span>
</div>
<div class="hvac-modal-body">
<iframe id="hvac-certificate-preview-iframe" src="" width="100%" height="600px" frameborder="0"></iframe>
</div>
</div>
</div>
`);
}
// Update modal title and iframe source
$('#hvac-certificate-preview-modal h3').text(`Certificate Preview - ${attendeeName}`);
$('#hvac-certificate-preview-iframe').attr('src', url);
// Show modal
$('#hvac-certificate-preview-modal').show();
},
/**
* Close certificate preview modal
*/
closeCertificatePreview: function(e) {
e.preventDefault();
$('#hvac-certificate-preview-modal').hide();
$('#hvac-certificate-preview-iframe').attr('src', '');
}
};
// Initialize when document is ready
$(document).ready(function() {
CertificateActions.init();
// Always initialize Generate Certificates functionality if on the generate certificates page
// (the form may not exist initially but will be created dynamically)
if ($('#event_id').length || $('#generate-certificates-form').length) {
GenerateCertificates.init();
}
});
})(jQuery);