Files
Instagram-Gallery-Sync-Pro/admin/js/admin-script.js

503 lines
18 KiB
JavaScript

/**
* Instagram Gallery Sync Pro - Admin Script
*
* Handles admin UI interactions
*
* @package Instagram_Gallery_Sync_Pro
*/
(function ($) {
'use strict';
/**
* Admin Controller
*/
const IGSPAdmin = {
/**
* Initialize
*/
init: function () {
this.initColorPickers();
this.initSliders();
this.initLayoutSelector();
this.initConditionalFields();
this.initSyncButton();
this.initToolButtons();
this.initTabPersistence();
this.initPostsTab();
this.initManualPostForm();
},
/**
* Initialize color pickers
*/
initColorPickers: function () {
if ($('.igsp-color-picker').length === 0) {
return;
}
try {
$('.igsp-color-picker').wpColorPicker({
change: function (event, ui) {
// Update live preview
IGSPAdmin.updatePreview();
}
});
} catch (e) {
// Color picker not available on this tab
}
},
/**
* Initialize range sliders
*/
initSliders: function () {
$('input[type="range"]').on('input change', function () {
const $slider = $(this);
const $value = $slider.siblings('.igsp-slider-value');
let value = $slider.val();
// Handle special cases
const id = $slider.attr('id');
if (id === 'igsp_auto_delete_days') {
value = value == 0 ? igspAdmin.strings.never || 'Never' : value + ' days';
} else if (id === 'igsp_spacing' || id === 'igsp_padding' ||
id === 'igsp_border_radius' || id === 'igsp_caption_font_size') {
value += 'px';
} else if (id === 'igsp_request_timeout') {
value += 's';
} else if (id === 'igsp_slider_delay') {
// Convert milliseconds to seconds for display
value = (parseInt(value) / 1000) + 's';
}
$value.text(value);
// Update live preview if applicable
if (id === 'igsp_caption_font_size') {
IGSPAdmin.updatePreview();
}
});
},
/**
* Initialize layout selector
*/
initLayoutSelector: function () {
$('.igsp-layout-option input').on('change', function () {
$('.igsp-layout-option').removeClass('selected');
$(this).closest('.igsp-layout-option').addClass('selected');
});
},
/**
* Initialize conditional fields
*/
initConditionalFields: function () {
$('[data-depends-on]').each(function () {
const $field = $(this);
const dependsOn = $field.data('depends-on');
const dependsValue = $field.data('depends-value');
function checkVisibility() {
const $input = $('[name="' + dependsOn + '"]:checked, [name="' + dependsOn + '"]').filter(':checked, select');
const currentValue = $input.val();
if (currentValue === dependsValue) {
$field.show();
} else {
$field.hide();
}
}
// Initial check
checkVisibility();
// Listen for changes
$('[name="' + dependsOn + '"]').on('change', checkVisibility);
});
},
/**
* Initialize sync button
*/
initSyncButton: function () {
$('#igsp-sync-now').on('click', function () {
const $button = $(this);
const $progress = $('#igsp-sync-progress');
const $result = $('#igsp-sync-result');
// Disable button
$button.prop('disabled', true);
$progress.show();
$result.hide();
// Animate progress bar
const $fill = $progress.find('.igsp-progress-fill');
$fill.css('width', '0%');
// Simulate progress
let progress = 0;
const progressInterval = setInterval(function () {
progress += Math.random() * 15;
if (progress > 90) progress = 90;
$fill.css('width', progress + '%');
}, 500);
// Make AJAX request
$.ajax({
url: igspAdmin.ajaxUrl,
type: 'POST',
data: {
action: 'igsp_manual_sync',
nonce: igspAdmin.nonce
},
success: function (response) {
clearInterval(progressInterval);
$fill.css('width', '100%');
setTimeout(function () {
$progress.hide();
$result.removeClass('success error');
if (response.success) {
$result.addClass('success').html(response.data.message).show();
IGSPAdmin.updateSyncStatus();
} else {
$result.addClass('error').html(response.data.message || igspAdmin.strings.syncError).show();
}
$button.prop('disabled', false);
}, 500);
},
error: function () {
clearInterval(progressInterval);
$progress.hide();
$result.addClass('error').html(igspAdmin.strings.syncError).show();
$button.prop('disabled', false);
}
});
});
},
/**
* Initialize tool buttons
*/
initToolButtons: function () {
// Clear cache
$('#igsp-clear-cache').on('click', function () {
const $button = $(this);
$button.prop('disabled', true).text(igspAdmin.strings.processing);
$.post(igspAdmin.ajaxUrl, {
action: 'igsp_clear_cache',
nonce: igspAdmin.nonce
}, function (response) {
if (response.success) {
$button.text(igspAdmin.strings.done);
setTimeout(function () {
$button.prop('disabled', false).html('<span class="dashicons dashicons-trash"></span> Clear Cache');
}, 2000);
}
});
});
// Reset data
$('#igsp-reset-data').on('click', function () {
if (!confirm(igspAdmin.strings.confirmReset)) {
return;
}
const $button = $(this);
$button.prop('disabled', true).text(igspAdmin.strings.processing);
$.post(igspAdmin.ajaxUrl, {
action: 'igsp_reset_data',
nonce: igspAdmin.nonce
}, function (response) {
if (response.success) {
location.reload();
}
});
});
// Clear logs
$('#igsp-clear-logs').on('click', function () {
if (!confirm(igspAdmin.strings.confirmClearLogs)) {
return;
}
const $button = $(this);
$button.prop('disabled', true);
$.post(igspAdmin.ajaxUrl, {
action: 'igsp_clear_logs',
nonce: igspAdmin.nonce
}, function (response) {
if (response.success) {
location.reload();
}
});
});
},
/**
* Initialize Posts Tab functionality
*/
initPostsTab: function () {
// Toggle post active/inactive
$(document).on('click', '.igsp-toggle-post', function () {
const $button = $(this);
const postId = $button.data('post-id');
const $row = $button.closest('.igsp-post-row');
$button.prop('disabled', true);
$.post(igspAdmin.ajaxUrl, {
action: 'igsp_toggle_post',
nonce: igspAdmin.nonce,
post_id: postId
}, function (response) {
if (response.success) {
const isActive = response.data.is_active;
const $icon = $button.find('.dashicons');
const $badge = $row.find('.igsp-status-badge');
if (isActive) {
$row.removeClass('igsp-post-inactive');
$icon.removeClass('dashicons-visibility').addClass('dashicons-hidden');
$badge.removeClass('igsp-status-inactive').addClass('igsp-status-active').text('Aktiv');
$button.attr('title', 'Deaktivieren');
} else {
$row.addClass('igsp-post-inactive');
$icon.removeClass('dashicons-hidden').addClass('dashicons-visibility');
$badge.removeClass('igsp-status-active').addClass('igsp-status-inactive').text('Inaktiv');
$button.attr('title', 'Aktivieren');
}
}
$button.prop('disabled', false);
}).fail(function () {
$button.prop('disabled', false);
});
});
// Delete post
$(document).on('click', '.igsp-delete-post', function () {
if (!confirm(igspAdmin.strings.confirmDeletePost)) {
return;
}
const $button = $(this);
const postId = $button.data('post-id');
const $row = $button.closest('.igsp-post-row');
$button.prop('disabled', true);
$.post(igspAdmin.ajaxUrl, {
action: 'igsp_delete_post',
nonce: igspAdmin.nonce,
post_id: postId
}, function (response) {
if (response.success) {
$row.fadeOut(300, function () {
$(this).remove();
// Update count
const $count = $('.igsp-post-count');
const currentCount = parseInt($count.text().replace(/\D/g, '')) || 0;
$count.text('(' + Math.max(0, currentCount - 1) + ')');
});
} else {
$button.prop('disabled', false);
}
}).fail(function () {
$button.prop('disabled', false);
});
});
},
/**
* Initialize Manual Post Form
*/
initManualPostForm: function () {
// Only init if the button exists on this page
if ($('#igsp-select-image-btn').length === 0) {
return;
}
let mediaFrame = null;
let selectedAttachmentId = 0;
// Open media library via button
$('#igsp-select-image-btn').on('click', function (e) {
e.preventDefault();
e.stopPropagation();
// Check if wp.media is available
if (typeof wp === 'undefined' || typeof wp.media === 'undefined') {
alert('WordPress Media Library ist nicht verfügbar. Bitte lade die Seite neu.');
return;
}
// If media frame already exists, reopen it
if (mediaFrame) {
mediaFrame.open();
return;
}
// Create media frame
mediaFrame = wp.media({
title: igspAdmin.strings.selectImage,
button: {
text: igspAdmin.strings.useImage
},
multiple: false,
library: {
type: 'image'
}
});
// When image is selected
mediaFrame.on('select', function () {
const attachment = mediaFrame.state().get('selection').first().toJSON();
selectedAttachmentId = attachment.id;
$('#igsp-attachment-id').val(attachment.id);
// Show preview
const previewUrl = attachment.sizes && attachment.sizes.medium
? attachment.sizes.medium.url
: attachment.url;
$('#igsp-preview-img').attr('src', previewUrl);
$('#igsp-image-preview').show();
$('#igsp-upload-placeholder').hide();
});
mediaFrame.open();
});
// Remove image
$('#igsp-remove-image').on('click', function (e) {
e.stopPropagation();
selectedAttachmentId = 0;
$('#igsp-attachment-id').val('');
$('#igsp-preview-img').attr('src', '');
$('#igsp-image-preview').hide();
$('#igsp-upload-placeholder').show();
});
// Submit manual post
$('#igsp-add-manual-post').on('click', function () {
const $button = $(this);
const $result = $('#igsp-manual-post-result');
const attachmentId = $('#igsp-attachment-id').val();
if (!attachmentId) {
$result.removeClass('success').addClass('error').text('Bitte wähle ein Bild aus.').show();
return;
}
$button.prop('disabled', true);
$result.hide();
// Convert datetime-local to MySQL format
let postedAt = $('#igsp-manual-date').val();
if (postedAt) {
postedAt = postedAt.replace('T', ' ') + ':00';
}
$.post(igspAdmin.ajaxUrl, {
action: 'igsp_add_manual_post',
nonce: igspAdmin.nonce,
attachment_id: attachmentId,
post_url: $('#igsp-manual-url').val(),
caption: $('#igsp-manual-caption').val(),
posted_at: postedAt
}, function (response) {
$result.removeClass('success error');
if (response.success) {
$result.addClass('success').text(response.data.message).show();
// Reset form
selectedAttachmentId = 0;
$('#igsp-attachment-id').val('');
$('#igsp-preview-img').attr('src', '');
$('#igsp-image-preview').hide();
$('#igsp-upload-placeholder').show();
$('#igsp-manual-url').val('');
$('#igsp-manual-caption').val('');
$('#igsp-manual-date').val('');
// Reload after short delay to show new post in table
setTimeout(function () {
location.reload();
}, 1500);
} else {
$result.addClass('error').text(response.data.message).show();
}
$button.prop('disabled', false);
}).fail(function () {
$result.addClass('error').text('Ein Fehler ist aufgetreten.').show();
$button.prop('disabled', false);
});
});
},
/**
* Update sync status
*/
updateSyncStatus: function () {
$.post(igspAdmin.ajaxUrl, {
action: 'igsp_get_sync_status',
nonce: igspAdmin.nonce
}, function (response) {
if (response.success) {
$('#igsp-total-posts').text(response.data.total_posts);
$('#igsp-last-sync').text(response.data.last_sync);
$('#igsp-next-sync').text(response.data.next_sync);
}
});
},
/**
* Update live preview
*/
updatePreview: function () {
const primaryColor = $('#igsp_primary_color').val() || '#e1306c';
const hoverColor = $('#igsp_hover_color').val() || '#c13584';
const textColor = $('#igsp_text_color').val() || '#ffffff';
const fontSize = $('#igsp_caption_font_size').val() || 14;
$('.igsp-preview-item').css({
'--primary': primaryColor,
'--hover': hoverColor,
'--text': textColor
});
$('.igsp-preview-caption').css('font-size', fontSize + 'px');
},
/**
* Tab persistence
*/
initTabPersistence: function () {
// Store current tab in localStorage
$('.igsp-tab-link').on('click', function () {
const tab = $(this).attr('href').split('tab=')[1];
if (tab) {
localStorage.setItem('igsp_active_tab', tab);
}
});
}
};
// Initialize when document is ready
$(document).ready(function () {
IGSPAdmin.init();
});
})(jQuery);