Initial commit of slide manager plugin

This commit is contained in:
2026-02-08 21:39:31 -08:00
commit 40099aa68a
32 changed files with 11284 additions and 0 deletions
+207
View File
@@ -0,0 +1,207 @@
/**
* Hi-School Slide Manager - Admin Sortable functionality
*
* Handles drag-and-drop ordering of slides in the admin list table
*/
jQuery(document).ready(function($) {
'use strict';
// Only initialize on the slides list page
if (typeof hssmAjax === 'undefined' || !$('.wp-list-table tbody').length) {
return;
}
// Initialize sortable functionality
initializeSortable();
/**
* Initialize jQuery UI sortable on the slides table
*/
function initializeSortable() {
const $tbody = $('.wp-list-table tbody');
// Make the table body sortable
$tbody.sortable({
handle: '.hssm-drag-handle',
placeholder: 'ui-sortable-placeholder',
helper: function(e, tr) {
var $helper = tr.clone();
$helper.children().each(function(index) {
$(this).width(tr.children().eq(index).width());
});
return $helper;
},
start: function(e, ui) {
ui.placeholder.height(ui.item.height());
ui.item.addClass('ui-sortable-helper');
},
stop: function(e, ui) {
ui.item.removeClass('ui-sortable-helper');
updateSlideOrder();
},
tolerance: 'pointer',
cursor: 'move',
opacity: 0.8,
distance: 5
});
// Add visual feedback
$tbody.on('mouseenter', '.hssm-drag-handle', function() {
$(this).closest('tr').addClass('hssm-sortable-hover');
});
$tbody.on('mouseleave', '.hssm-drag-handle', function() {
$(this).closest('tr').removeClass('hssm-sortable-hover');
});
// Add CSS for hover effect
if (!$('#hssm-sortable-styles').length) {
$('<style id="hssm-sortable-styles">')
.text(`
.wp-list-table tbody tr.hssm-sortable-hover {
background-color: #f0f8ff;
}
.wp-list-table .hssm-drag-handle {
opacity: 0.6;
transition: opacity 0.2s ease;
}
.wp-list-table .hssm-drag-handle:hover {
opacity: 1;
}
.wp-list-table tbody tr.ui-sortable-helper td {
background-color: #f9f9f9;
border-color: #0073aa;
}
`)
.appendTo('head');
}
}
/**
* Update slide order via AJAX
*/
function updateSlideOrder() {
const slideIds = [];
// Collect all slide IDs in their new order
$('.wp-list-table tbody tr').each(function() {
const postId = $(this).attr('id');
if (postId && postId.startsWith('post-')) {
const slideId = parseInt(postId.replace('post-', ''));
if (slideId) {
slideIds.push(slideId);
}
}
});
if (slideIds.length === 0) {
return;
}
// Show loading indicator
showLoadingIndicator();
// Send AJAX request to update order
$.ajax({
url: hssmAjax.ajaxurl,
type: 'POST',
data: {
action: 'hssm_update_slide_order',
nonce: hssmAjax.nonce,
slide_ids: slideIds
},
success: function(response) {
hideLoadingIndicator();
if (response.success) {
showNotification('Slide order updated successfully!', 'success');
// Update the order column values
updateOrderColumnValues(slideIds);
} else {
showNotification('Failed to update slide order: ' + (response.data?.message || 'Unknown error'), 'error');
}
},
error: function(xhr, status, error) {
hideLoadingIndicator();
showNotification('Error updating slide order: ' + error, 'error');
}
});
}
/**
* Update the order column values in the table
*/
function updateOrderColumnValues(slideIds) {
slideIds.forEach(function(slideId, index) {
const $row = $('#post-' + slideId);
const $orderCell = $row.find('.column-order');
if ($orderCell.length) {
$orderCell.text(index);
}
});
}
/**
* Show loading indicator
*/
function showLoadingIndicator() {
if ($('#hssm-loading-indicator').length === 0) {
$('<div id="hssm-loading-indicator" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(0,0,0,0.8); color: white; padding: 20px; border-radius: 5px; z-index: 9999; font-size: 16px;">')
.html('<span class="dashicons dashicons-update" style="animation: rotation 1s infinite linear; margin-right: 10px;"></span> Updating slide order...')
.appendTo('body');
}
}
/**
* Hide loading indicator
*/
function hideLoadingIndicator() {
$('#hssm-loading-indicator').remove();
}
/**
* Show notification message
*/
function showNotification(message, type) {
const $notice = $('<div class="notice notice-' + type + ' is-dismissible hssm-notice">')
.html('<p>' + message + '</p>')
.hide();
// Insert after the page title
$('.wrap h1').first().after($notice);
// Animate in
$notice.slideDown(300);
// Add dismiss functionality
$notice.on('click', '.notice-dismiss', function() {
$notice.slideUp(300, function() {
$(this).remove();
});
});
// Auto-dismiss success messages after 3 seconds
if (type === 'success') {
setTimeout(function() {
$notice.find('.notice-dismiss').click();
}, 3000);
}
}
// Add rotation animation for loading spinner
if (!$('#hssm-animation-styles').length) {
$('<style id="hssm-animation-styles">')
.text(`
@keyframes rotation {
from { transform: rotate(0deg); }
to { transform: rotate(359deg); }
}
.hssm-notice {
margin: 10px 0;
}
`)
.appendTo('head');
}
});
+223
View File
@@ -0,0 +1,223 @@
/**
* Hi-School Slide Manager - Admin JavaScript
*/
jQuery(document).ready(function($) {
'use strict';
// Initialize admin functionality
initializeAdmin();
/**
* Initialize admin functionality
*/
function initializeAdmin() {
// Handle form submissions
$('.hssm-settings-form').on('submit', handleFormSubmission);
// Handle media upload buttons
$('.hssm-upload-button').on('click', handleMediaUpload);
// Handle slide preview
$('.hssm-preview-button').on('click', handleSlidePreview);
// Initialize sortable slides if library is available
if (typeof $.fn.sortable !== 'undefined') {
initializeSortable();
}
}
/**
* Handle form submission
*/
function handleFormSubmission(e) {
e.preventDefault();
var $form = $(this);
var $submitBtn = $form.find('[type="submit"]');
var originalText = $submitBtn.text();
// Show loading state
$submitBtn.text('Saving...').prop('disabled', true);
// Simulate form processing (replace with actual AJAX call)
setTimeout(function() {
$submitBtn.text('Saved!').removeClass('hssm-btn').addClass('hssm-btn-success');
setTimeout(function() {
$submitBtn.text(originalText).removeClass('hssm-btn-success').addClass('hssm-btn').prop('disabled', false);
}, 2000);
}, 1000);
}
/**
* Handle media upload
*/
function handleMediaUpload(e) {
e.preventDefault();
var $button = $(this);
var $input = $button.siblings('input[type="hidden"]');
var $preview = $button.siblings('.hssm-image-preview');
// WordPress media uploader
if (typeof wp !== 'undefined' && wp.media) {
var mediaUploader = wp.media({
title: 'Choose Slide Image',
button: {
text: 'Use this image'
},
multiple: false
});
mediaUploader.on('select', function() {
var attachment = mediaUploader.state().get('selection').first().toJSON();
$input.val(attachment.id);
$preview.html('<img src="' + attachment.url + '" style="max-width: 200px; height: auto;">');
});
mediaUploader.open();
}
}
/**
* Handle slide preview
*/
function handleSlidePreview(e) {
e.preventDefault();
var $button = $(this);
var slideData = gatherSlideData($button.closest('.hssm-slide-form'));
// Create preview modal
var $modal = $('<div class="hssm-modal">');
var $modalContent = $('<div class="hssm-modal-content">');
var $closeBtn = $('<span class="hssm-modal-close">&times;</span>');
$modalContent.append($closeBtn);
$modalContent.append('<h3>Slide Preview</h3>');
$modalContent.append('<div class="hssm-slide-preview">' + generateSlideHTML(slideData) + '</div>');
$modal.append($modalContent);
$('body').append($modal);
// Show modal
$modal.fadeIn();
// Close modal handlers
$closeBtn.on('click', function() {
$modal.fadeOut(function() {
$modal.remove();
});
});
$modal.on('click', function(e) {
if (e.target === this) {
$modal.fadeOut(function() {
$modal.remove();
});
}
});
}
/**
* Initialize sortable slides
*/
function initializeSortable() {
$('.hssm-slides-list').sortable({
handle: '.hssm-slide-handle',
placeholder: 'hssm-slide-placeholder',
update: function(event, ui) {
// Handle slide reordering
updateSlideOrder();
}
});
}
/**
* Gather slide data from form
*/
function gatherSlideData($form) {
return {
title: $form.find('[name="slide_title"]').val(),
content: $form.find('[name="slide_content"]').val(),
image: $form.find('[name="slide_image"]').val()
};
}
/**
* Generate slide HTML for preview
*/
function generateSlideHTML(data) {
var html = '<div class="hssm-slide">';
html += '<h3>' + (data.title || 'Untitled Slide') + '</h3>';
html += '<div class="hssm-slide-content">' + (data.content || 'No content') + '</div>';
if (data.image) {
html += '<div class="hssm-slide-image"><img src="' + data.image + '" alt="Slide Image"></div>';
}
html += '</div>';
return html;
}
/**
* Update slide order after sorting
*/
function updateSlideOrder() {
var order = [];
$('.hssm-slides-list .hssm-slide-item').each(function() {
order.push($(this).data('slide-id'));
});
// Send order to server (implement AJAX call)
console.log('New slide order:', order);
}
});
// Add modal styles
document.addEventListener('DOMContentLoaded', function() {
var style = document.createElement('style');
style.textContent = `
.hssm-modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
}
.hssm-modal-content {
background-color: #fff;
margin: 5% auto;
padding: 20px;
border-radius: 8px;
width: 80%;
max-width: 600px;
position: relative;
max-height: 80vh;
overflow-y: auto;
}
.hssm-modal-close {
position: absolute;
top: 10px;
right: 15px;
font-size: 28px;
font-weight: bold;
cursor: pointer;
color: #aaa;
}
.hssm-modal-close:hover,
.hssm-modal-close:focus {
color: #000;
}
.hssm-btn-success {
background: #46b450 !important;
}
`;
document.head.appendChild(style);
});
File diff suppressed because it is too large Load Diff
+79
View File
@@ -0,0 +1,79 @@
/**
* Hi-School Slide Manager - Frontend JavaScript
*/
jQuery(document).ready(function($) {
'use strict';
// Initialize slide functionality
initializeSlides();
/**
* Initialize slide functionality
*/
function initializeSlides() {
$('.hssm-slides-container').each(function() {
var $container = $(this);
var $slides = $container.find('.hssm-slide');
// Add fade-in animation
$slides.each(function(index) {
var $slide = $(this);
setTimeout(function() {
$slide.addClass('hssm-fade-in');
}, index * 100);
});
// Add click handlers for interactive slides
$slides.on('click', function() {
var $slide = $(this);
$slide.toggleClass('hssm-slide-expanded');
});
});
}
/**
* Handle slide interactions
*/
$(document).on('click', '.hssm-slide-toggle', function(e) {
e.preventDefault();
var $button = $(this);
var $slide = $button.closest('.hssm-slide');
var $content = $slide.find('.hssm-slide-content');
$content.slideToggle(300);
$button.text($content.is(':visible') ? 'Hide' : 'Show');
});
/**
* Handle keyboard navigation
*/
$(document).on('keydown', '.hssm-slide', function(e) {
if (e.which === 13 || e.which === 32) { // Enter or Space
e.preventDefault();
$(this).click();
}
});
});
// Add CSS classes via JavaScript for animations
document.addEventListener('DOMContentLoaded', function() {
var style = document.createElement('style');
style.textContent = `
.hssm-slide {
opacity: 0;
transform: translateY(20px);
transition: opacity 0.5s ease, transform 0.5s ease;
}
.hssm-slide.hssm-fade-in {
opacity: 1;
transform: translateY(0);
}
.hssm-slide.hssm-slide-expanded {
transform: scale(1.02);
}
`;
document.head.appendChild(style);
});
+166
View File
@@ -0,0 +1,166 @@
/**
* Hi-School Slide Manager Preview JavaScript
*
* Handles interactions on the slide preview page
*
* @package Hi_School_Slide_Manager
* @since 1.0.0
*/
(function($) {
'use strict';
// Preview object
const HSSMPreview = {
// Initialize
init: function() {
this.bindEvents();
this.initDatepicker();
},
// Initialize Datepicker
initDatepicker: function() {
if ($('#hssm_date').length === 0) return;
$('#hssm_date').datepicker({
dateFormat: 'yy-mm-dd',
beforeShowDay: function(date) {
var y = date.getFullYear();
var m = date.getMonth() + 1;
var d = date.getDate();
// Pad month and day
var dateString = y + '-' + (m < 10 ? '0' : '') + m + '-' + (d < 10 ? '0' : '') + d;
if (typeof hssmEvents !== 'undefined' && hssmEvents[dateString]) {
var classes = [];
var events = hssmEvents[dateString];
if (events.indexOf('start') !== -1) {
classes.push('hssm-datepicker-start');
}
if (events.indexOf('end') !== -1) {
classes.push('hssm-datepicker-end');
}
return [true, classes.join(' '), ''];
}
return [true, '', ''];
},
onSelect: function(dateText) {
// Trigger form submit
$(this).closest('form').submit();
}
});
},
// Bind event handlers
bindEvents: function() {
$(document).on('click', '#email-preview', this.emailPreview.bind(this));
$(document).on('click', '#download-screenshot', this.downloadScreenshot.bind(this));
$(document).on('click', '#copy-preview-link', this.copyPreviewLink.bind(this));
$(document).on('click', '.hssm-approve-slide', this.approveSlide.bind(this));
},
// Email preview functionality
emailPreview: function(e) {
e.preventDefault();
this.showMessage('Email preview functionality coming soon!', 'info');
},
// Download screenshot functionality
downloadScreenshot: function(e) {
e.preventDefault();
this.showMessage('Screenshot download functionality coming soon!', 'info');
},
// Copy preview link
copyPreviewLink: function(e) {
e.preventDefault();
const previewUrl = window.location.href;
if (navigator.clipboard) {
navigator.clipboard.writeText(previewUrl).then(() => {
this.showMessage('Preview link copied to clipboard!', 'success');
});
} else {
this.showMessage('Preview link: ' + previewUrl, 'info');
}
},
// Approve slide
approveSlide: function(e) {
e.preventDefault();
const $btn = $(e.currentTarget);
const slideId = $btn.data('id');
if (!confirm(hssmPreview.strings.approve_confirm)) {
return;
}
$btn.prop('disabled', true).addClass('hssm-loading');
$.ajax({
url: hssmPreview.ajaxurl,
type: 'POST',
data: {
action: 'hssm_approve_slide',
nonce: hssmPreview.nonce,
slide_id: slideId,
approve_action: 'schedule' // Smart approve: schedules if future date exists, otherwise publishes
},
success: (response) => {
if (response.success) {
this.showMessage(hssmPreview.strings.approve_success, 'success');
// Reload page to reflect changes
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
this.showMessage(response.data.message || hssmPreview.strings.approve_error, 'error');
$btn.prop('disabled', false).removeClass('hssm-loading');
}
},
error: () => {
this.showMessage(hssmPreview.strings.approve_error, 'error');
$btn.prop('disabled', false).removeClass('hssm-loading');
}
});
},
// Show message to user
showMessage: function(message, type = 'info') {
// Create message container if it doesn't exist
let $messages = $('#hssm-preview-messages');
if ($messages.length === 0) {
$messages = $('<div id="hssm-preview-messages" class="hssm-messages"></div>');
$('.hssm-preview-actions').before($messages);
}
const messageHtml = `
<div class="hssm-message ${type}">
${message}
</div>
`;
$messages.append(messageHtml);
// Auto-remove after 5 seconds
setTimeout(() => {
$messages.find('.hssm-message').last().fadeOut(300, function() {
$(this).remove();
});
}, 5000);
}
};
// Initialize when document is ready
$(document).ready(function() {
HSSMPreview.init();
});
})(jQuery);
+109
View File
@@ -0,0 +1,109 @@
/**
* HSSM Slider JavaScript
* Handles navigation and autoplay for the [hssm_slider] shortcode
* Custom classes version
*/
(function($) {
'use strict';
var HSSMSlider = function(container) {
this.$container = $(container);
this.$track = this.$container.find('.hssm-track');
this.$slides = this.$container.find('.hssm-slide');
this.slideCount = this.$slides.length;
this.currentIndex = 0;
this.autoplay = this.$container.data('autoplay') === true || this.$container.data('autoplay') === 'true';
this.interval = parseInt(this.$container.data('interval')) || 5000;
this.timer = null;
if (this.slideCount <= 1) return;
this.init();
};
HSSMSlider.prototype.init = function() {
var self = this;
// Arrows
this.$container.find('.hssm-arrow-next').on('click', function(e) {
e.preventDefault();
self.stopAutoplay();
self.next();
self.startAutoplay();
});
this.$container.find('.hssm-arrow-prev').on('click', function(e) {
e.preventDefault();
self.stopAutoplay();
self.prev();
self.startAutoplay();
});
// Touch swipe support
var touchStartX = 0;
var touchStartY = 0;
this.$container.on('touchstart', function(e) {
touchStartX = e.originalEvent.touches[0].pageX;
touchStartY = e.originalEvent.touches[0].pageY;
});
this.$container.on('touchend', function(e) {
var touchEndX = e.originalEvent.changedTouches[0].pageX;
var touchEndY = e.originalEvent.changedTouches[0].pageY;
// Calculate distance
var dx = touchStartX - touchEndX;
var dy = touchStartY - touchEndY;
// Only swipe if horizontal movement is greater than vertical (prevents swipe on scroll)
if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 50) {
if (dx > 0) {
self.next();
} else {
self.prev();
}
self.stopAutoplay();
self.startAutoplay();
}
});
this.startAutoplay();
};
HSSMSlider.prototype.update = function() {
var offset = -this.currentIndex * 100;
this.$track.css('transform', 'translateX(' + offset + '%)');
};
HSSMSlider.prototype.next = function() {
this.currentIndex = (this.currentIndex + 1) % this.slideCount;
this.update();
};
HSSMSlider.prototype.prev = function() {
this.currentIndex = (this.currentIndex - 1 + this.slideCount) % this.slideCount;
this.update();
};
HSSMSlider.prototype.startAutoplay = function() {
if (!this.autoplay) return;
var self = this;
this.timer = setInterval(function() {
self.next();
}, this.interval);
};
HSSMSlider.prototype.stopAutoplay = function() {
if (this.timer) {
clearInterval(this.timer);
}
};
$(document).ready(function() {
$('.hssm-slider-container').each(function() {
new HSSMSlider(this);
});
});
})(jQuery);