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
552 lines
No EOL
22 KiB
JavaScript
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">×</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); |