diff --git a/assets/js/dashboard.js b/assets/js/dashboard.js index 4d5b424..ddbc0ef 100644 --- a/assets/js/dashboard.js +++ b/assets/js/dashboard.js @@ -87,14 +87,16 @@ $targetSitesField.find('.hssm-checkboxes-compact').removeClass('hssm-field-has-error'); }); - // Filtering and management + // Filtering and management (slide row edit/delete bound in bindSlideActions after list load) $(document).on('click', '#apply-filters', this.applyFilters.bind(this)); - $(document).on('click', '.hssm-edit-slide', this.editSlide.bind(this)); - $(document).on('click', '.hssm-delete-slide', function(e) { + + // Edit form actions — register once; do not re-bind in populateEditForm (prevents duplicate toasts) + $(document).on('click.hssmDashboard', '.hssm-cancel-edit, .hssm-cancel-edit-btn', (e) => { e.preventDefault(); - const slideId = $(e.currentTarget).data('slide-id'); - HSSMDashboard.deleteSlide(slideId); + this.cancelEdit(e); }); + $(document).on('click.hssmDashboard', '.hssm-update-slide', this.updateSlide.bind(this)); + $(document).on('click.hssmDashboard', '.hssm-schedule-updated-slide', this.scheduleUpdatedSlide.bind(this)); // Analytics functionality $(document).on('click', '#generate-report', this.generateAnalyticsReport.bind(this)); @@ -811,6 +813,7 @@ `); + $(document).off('click.hssmSlideActions'); return; } @@ -830,7 +833,7 @@ slides.forEach(slide => { const imageUrl = slide.featured_image_url || ''; const statusClass = this.getStatusClass(slide.status); - const sitesText = this.formatSitesList(slide.target_sites); + const sitesText = this.formatSitesList(slide.sites || slide.target_sites); const scheduleText = this.formatScheduleText(slide); html += ` @@ -916,29 +919,26 @@ // Bind slide action events bindSlideActions: function() { - // Edit slide - $(document).off('click', '.hssm-edit-slide').on('click', '.hssm-edit-slide', (e) => { + // Namespaced so repeated list renders replace handlers instead of stacking + $(document).off('click.hssmSlideActions', '.hssm-edit-slide').on('click.hssmSlideActions', '.hssm-edit-slide', (e) => { e.preventDefault(); const slideId = $(e.currentTarget).data('slide-id'); this.editSlide(slideId); }); - // Delete slide - $(document).off('click', '.hssm-delete-slide').on('click', '.hssm-delete-slide', (e) => { + $(document).off('click.hssmSlideActions', '.hssm-delete-slide').on('click.hssmSlideActions', '.hssm-delete-slide', (e) => { e.preventDefault(); const slideId = $(e.currentTarget).data('slide-id'); this.deleteSlide(slideId); }); - // Duplicate slide - $(document).off('click', '.hssm-duplicate-slide').on('click', '.hssm-duplicate-slide', (e) => { + $(document).off('click.hssmSlideActions', '.hssm-duplicate-slide').on('click.hssmSlideActions', '.hssm-duplicate-slide', (e) => { e.preventDefault(); const slideId = $(e.currentTarget).data('slide-id'); this.duplicateSlide(slideId); }); - // Toggle status - $(document).off('click', '.hssm-toggle-status').on('click', '.hssm-toggle-status', (e) => { + $(document).off('click.hssmSlideActions', '.hssm-toggle-status').on('click.hssmSlideActions', '.hssm-toggle-status', (e) => { e.preventDefault(); const slideId = $(e.currentTarget).data('slide-id'); this.toggleSlideStatus(slideId); @@ -1107,12 +1107,7 @@ `; $('#slide-forms-container').html(formHtml); - - // Bind cancel edit events - $(document).on('click', '.hssm-cancel-edit, .hssm-cancel-edit-btn', this.cancelEdit.bind(this)); - $(document).on('click', '.hssm-update-slide', this.updateSlide.bind(this)); - $(document).on('click', '.hssm-schedule-updated-slide', this.scheduleUpdatedSlide.bind(this)); - + this.showMessage('Slide loaded for editing', 'success'); }, @@ -1137,19 +1132,22 @@ `).join(''); }, - // Cancel edit mode - cancelEdit: function(e) { - if (e) e.preventDefault(); - + // Cancel edit mode (silent: true skips toast — used after successful update so we do not double-message) + cancelEdit: function(e, silent) { + if (e && e.preventDefault) { + e.preventDefault(); + } + this.isEditMode = false; this.editingSlideId = null; - - // Return to normal create form + $('#slide-forms-container').empty(); this.formCounter = 0; this.addInitialSlideForm(); - - this.showMessage('Edit cancelled', 'info'); + + if (!silent) { + this.showMessage('Edit cancelled', 'info'); + } }, // Update slide function @@ -1182,11 +1180,8 @@ if (response.success) { this.showMessage('Slide updated successfully as draft!', 'success'); - - // Exit edit mode and refresh manage slides if that tab is available - this.cancelEdit(); - - // If manage slides tab exists, refresh it + this.cancelEdit(null, true); + if ($('#manage-slides').length > 0) { $('.hssm-nav-tabs a[data-tab="manage-slides"]').click(); } @@ -1231,11 +1226,8 @@ if (response.success) { this.showMessage('Slide updated and scheduled for approval!', 'success'); - - // Exit edit mode and refresh manage slides if that tab is available - this.cancelEdit(); - - // If manage slides tab exists, refresh it + this.cancelEdit(null, true); + if ($('#manage-slides').length > 0) { $('.hssm-nav-tabs a[data-tab="manage-slides"]').click(); } @@ -1337,25 +1329,19 @@ // Show message to user showMessage: function(message, type = 'info') { const $messages = $('#hssm-messages'); - const messageHtml = ` -
- `; + if (!$messages.length) { + return; + } - $messages.append(messageHtml); + const $msg = $('').addClass(type).text(message); + $messages.append($msg); - // Auto-remove after 5 seconds - setTimeout(() => { - $messages.find('.hssm-message').last().fadeOut(300, function() { + const dismissMs = 5000; + window.setTimeout(() => { + $msg.stop(true, true).fadeOut(300, function() { $(this).remove(); }); - }, 5000); - - // Scroll to messages - $('html, body').animate({ - scrollTop: $messages.offset().top - 20 - }, 300); + }, dismissMs); }, // Placeholder methods for future implementation