upskill-event-manager/assets/js/hvac-announcements-admin.js
ben 054639c95c
Some checks failed
HVAC Plugin CI/CD Pipeline / Code Quality & Standards (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Unit Tests (push) Has been cancelled
Security Monitoring & Compliance / Secrets & Credential Scan (push) Has been cancelled
Security Monitoring & Compliance / WordPress Security Analysis (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Security Analysis (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Integration Tests (push) Has been cancelled
Security Monitoring & Compliance / Dependency Vulnerability Scan (push) Has been cancelled
Security Monitoring & Compliance / Static Code Security Analysis (push) Has been cancelled
Security Monitoring & Compliance / Security Compliance Validation (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Deploy to Production (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Notification (push) Has been cancelled
Security Monitoring & Compliance / Security Summary Report (push) Has been cancelled
Security Monitoring & Compliance / Security Team Notification (push) Has been cancelled
feat: complete master trainer system transformation from 0% to 100% success
- Deploy 6 simultaneous WordPress specialized agents using sequential thinking and Zen MCP
- Resolve all critical issues: permissions, jQuery dependencies, CDN mapping, security vulnerabilities
- Implement bulletproof jQuery loading system with WordPress hook timing fixes
- Create professional MapGeo Safety system with CDN health monitoring and fallback UI
- Fix privilege escalation vulnerability with capability-based authorization
- Add complete announcement admin system with modal forms and AJAX handling
- Enhance import/export functionality (54 trainers successfully exported)
- Achieve 100% operational master trainer functionality verified via MCP Playwright E2E testing

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-02 16:41:51 -03:00

499 lines
No EOL
15 KiB
JavaScript

/**
* HVAC Announcements Admin JavaScript
*
* @package HVAC_Community_Events
*/
jQuery(document).ready(function($) {
'use strict';
// State variables
let currentPage = 1;
let totalPages = 1;
let currentStatus = 'any';
let searchTerm = '';
let editorInstance = null;
// Initialize
init();
/**
* Initialize the announcements interface
*/
function init() {
loadAnnouncements();
loadCategories();
initializeEventHandlers();
initializeEditor();
}
/**
* Initialize TinyMCE editor
*/
function initializeEditor() {
if (typeof wp !== 'undefined' && wp.editor) {
// Initialize WordPress editor
wp.editor.initialize('announcement-content', {
tinymce: {
wpautop: true,
plugins: 'lists link image media paste',
toolbar1: 'formatselect | bold italic | alignleft aligncenter alignright | bullist numlist | link unlink | wp_adv',
toolbar2: 'strikethrough hr forecolor pastetext removeformat charmap outdent indent undo redo wp_help',
height: 300
},
quicktags: true,
mediaButtons: true
});
}
}
/**
* Initialize event handlers
*/
function initializeEventHandlers() {
// Add announcement button - FIXED: Use correct class selector to match HTML template
$('.hvac-add-announcement').on('click', function() {
openModal();
});
// Modal close buttons
$('.modal-close, .modal-cancel').on('click', function() {
closeModal();
});
// Form submission
$('#announcement-form').on('submit', function(e) {
e.preventDefault();
saveAnnouncement();
});
// Status filter
$('#status-filter').on('change', function() {
currentStatus = $(this).val();
currentPage = 1;
loadAnnouncements();
});
// Search
$('#search-btn').on('click', function() {
searchTerm = $('#announcement-search').val();
currentPage = 1;
loadAnnouncements();
});
$('#announcement-search').on('keypress', function(e) {
if (e.which === 13) {
searchTerm = $(this).val();
currentPage = 1;
loadAnnouncements();
}
});
// Pagination
$('#prev-page').on('click', function() {
if (currentPage > 1) {
currentPage--;
loadAnnouncements();
}
});
$('#next-page').on('click', function() {
if (currentPage < totalPages) {
currentPage++;
loadAnnouncements();
}
});
// Edit/Delete actions (delegated)
$(document).on('click', '.edit-announcement', function() {
const id = $(this).data('id');
editAnnouncement(id);
});
$(document).on('click', '.delete-announcement', function() {
const id = $(this).data('id');
if (confirm(hvac_announcements.strings.confirm_delete)) {
deleteAnnouncement(id);
}
});
// Featured image selection
$('#select-featured-image').on('click', function(e) {
e.preventDefault();
selectFeaturedImage();
});
$('#remove-featured-image').on('click', function(e) {
e.preventDefault();
removeFeaturedImage();
});
}
/**
* Load announcements via AJAX
*/
function loadAnnouncements() {
const data = {
action: 'hvac_get_announcements',
nonce: hvac_announcements.nonce,
page: currentPage,
per_page: 20,
status: currentStatus,
search: searchTerm
};
$.post(hvac_announcements.ajax_url, data, function(response) {
if (response.success) {
displayAnnouncements(response.data.announcements);
updatePagination(response.data.current_page, response.data.pages);
} else {
showError(response.data || hvac_announcements.strings.error_loading);
}
});
}
/**
* Display announcements in table
*/
function displayAnnouncements(announcements) {
const tbody = $('#announcements-list');
tbody.empty();
if (announcements.length === 0) {
tbody.append('<tr><td colspan="6" class="no-items">No announcements found</td></tr>');
return;
}
announcements.forEach(function(announcement) {
const row = $('<tr>');
// Title
row.append('<td class="column-title"><strong>' + escapeHtml(announcement.title) + '</strong></td>');
// Status
const statusClass = 'status-' + announcement.status;
row.append('<td class="column-status"><span class="' + statusClass + '">' + announcement.status + '</span></td>');
// Categories
const categories = announcement.categories.join(', ') || '-';
row.append('<td class="column-categories">' + escapeHtml(categories) + '</td>');
// Author
row.append('<td class="column-author">' + escapeHtml(announcement.author) + '</td>');
// Date
row.append('<td class="column-date">' + announcement.date + '</td>');
// Actions
let actions = '<td class="column-actions">';
if (announcement.can_edit) {
actions += '<button class="button button-small edit-announcement" data-id="' + announcement.id + '">Edit</button> ';
}
if (announcement.can_delete) {
actions += '<button class="button button-small delete-announcement" data-id="' + announcement.id + '">Delete</button>';
}
actions += '</td>';
row.append(actions);
tbody.append(row);
});
}
/**
* Update pagination controls
*/
function updatePagination(current, total) {
currentPage = current;
totalPages = total;
$('#current-page').text(current);
$('#total-pages').text(total);
$('#prev-page').prop('disabled', current <= 1);
$('#next-page').prop('disabled', current >= total);
}
/**
* Load categories for the form
*/
function loadCategories() {
$.post(hvac_announcements.ajax_url, {
action: 'hvac_get_announcement_categories',
nonce: hvac_announcements.nonce
}, function(response) {
if (response.success) {
displayCategories(response.data);
}
});
}
/**
* Display categories as checkboxes
*/
function displayCategories(categories) {
const container = $('#categories-container');
container.empty();
if (categories.length === 0) {
container.append('<p class="no-categories">No categories available</p>');
return;
}
categories.forEach(function(category) {
const checkbox = $('<label class="category-checkbox">');
checkbox.append('<input type="checkbox" name="categories[]" value="' + category.id + '">');
checkbox.append(' ' + escapeHtml(category.name));
container.append(checkbox);
});
}
/**
* Open the modal for adding/editing
*/
function openModal(announcementId) {
$('#announcement-modal').fadeIn();
if (announcementId) {
$('#modal-title').text('Edit Announcement');
loadAnnouncementForEdit(announcementId);
} else {
$('#modal-title').text('Add New Announcement');
resetForm();
}
}
/**
* Close the modal
*/
function closeModal() {
$('#announcement-modal').fadeOut();
resetForm();
}
/**
* Reset the form
*/
function resetForm() {
$('#announcement-form')[0].reset();
$('#announcement-id').val('');
// Reset editor
if (wp.editor) {
wp.editor.setContent('announcement-content', '');
}
// Reset featured image
removeFeaturedImage();
// Uncheck all categories
$('#categories-container input[type="checkbox"]').prop('checked', false);
}
/**
* Load announcement for editing
*/
function loadAnnouncementForEdit(id) {
$.post(hvac_announcements.ajax_url, {
action: 'hvac_get_announcement',
nonce: hvac_announcements.nonce,
id: id
}, function(response) {
if (response.success) {
populateForm(response.data);
} else {
showError(response.data || 'Failed to load announcement');
closeModal();
}
});
}
/**
* Populate form with announcement data
*/
function populateForm(announcement) {
$('#announcement-id').val(announcement.id);
$('#announcement-title').val(announcement.title);
$('#announcement-excerpt').val(announcement.excerpt);
$('#announcement-status').val(announcement.status);
$('#announcement-tags').val(announcement.tags);
// Set content in editor
if (wp.editor) {
wp.editor.setContent('announcement-content', announcement.content);
}
// Set publish date
if (announcement.date) {
const date = new Date(announcement.date);
const localDate = date.toISOString().slice(0, 16);
$('#announcement-date').val(localDate);
}
// Set categories
if (announcement.categories && announcement.categories.length > 0) {
announcement.categories.forEach(function(catId) {
$('#categories-container input[value="' + catId + '"]').prop('checked', true);
});
}
// Set featured image
if (announcement.featured_image_id) {
$('#featured-image-id').val(announcement.featured_image_id);
if (announcement.featured_image_url) {
$('#featured-image-preview').html('<img src="' + announcement.featured_image_url + '" />');
$('#remove-featured-image').show();
}
}
}
/**
* Save announcement (create or update)
*/
function saveAnnouncement() {
// Get editor content
let content = '';
if (wp.editor) {
content = wp.editor.getContent('announcement-content');
}
// Gather form data
const formData = {
action: $('#announcement-id').val() ? 'hvac_update_announcement' : 'hvac_create_announcement',
nonce: hvac_announcements.nonce,
id: $('#announcement-id').val(),
title: $('#announcement-title').val(),
content: content,
excerpt: $('#announcement-excerpt').val(),
status: $('#announcement-status').val(),
publish_date: $('#announcement-date').val(),
tags: $('#announcement-tags').val(),
categories: [],
featured_image_id: $('#featured-image-id').val()
};
// Get selected categories
$('#categories-container input:checked').each(function() {
formData.categories.push($(this).val());
});
// Send AJAX request
$.post(hvac_announcements.ajax_url, formData, function(response) {
if (response.success) {
showSuccess(response.data.message);
closeModal();
loadAnnouncements();
} else {
showError(response.data || hvac_announcements.strings.error_saving);
}
});
}
/**
* Edit announcement
*/
function editAnnouncement(id) {
openModal(id);
}
/**
* Delete announcement
*/
function deleteAnnouncement(id) {
$.post(hvac_announcements.ajax_url, {
action: 'hvac_delete_announcement',
nonce: hvac_announcements.nonce,
id: id
}, function(response) {
if (response.success) {
showSuccess(response.data.message || hvac_announcements.strings.success_deleted);
loadAnnouncements();
} else {
showError(response.data || 'Failed to delete announcement');
}
});
}
/**
* Select featured image using WordPress media uploader
*/
function selectFeaturedImage() {
if (typeof wp.media === 'undefined') {
return;
}
const mediaUploader = wp.media({
title: 'Select Featured Image',
button: {
text: 'Use this image'
},
multiple: false
});
mediaUploader.on('select', function() {
const attachment = mediaUploader.state().get('selection').first().toJSON();
$('#featured-image-id').val(attachment.id);
let imageUrl = attachment.url;
if (attachment.sizes && attachment.sizes.medium) {
imageUrl = attachment.sizes.medium.url;
}
$('#featured-image-preview').html('<img src="' + imageUrl + '" />');
$('#remove-featured-image').show();
});
mediaUploader.open();
}
/**
* Remove featured image
*/
function removeFeaturedImage() {
$('#featured-image-id').val('');
$('#featured-image-preview').empty();
$('#remove-featured-image').hide();
}
/**
* Show success message
*/
function showSuccess(message) {
const notice = $('<div class="notice notice-success is-dismissible"><p>' + message + '</p></div>');
$('.hvac-announcements-wrapper').prepend(notice);
setTimeout(function() {
notice.fadeOut(function() {
notice.remove();
});
}, 3000);
}
/**
* Show error message
*/
function showError(message) {
const notice = $('<div class="notice notice-error is-dismissible"><p>' + message + '</p></div>');
$('.hvac-announcements-wrapper').prepend(notice);
setTimeout(function() {
notice.fadeOut(function() {
notice.remove();
});
}, 5000);
}
/**
* Escape HTML
*/
function escapeHtml(text) {
const map = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#039;'
};
return text.replace(/[&<>"']/g, function(m) { return map[m]; });
}
});