/** * WP BnB Admin JavaScript * * @package Magdev\WpBnb */ (function($) { 'use strict'; /** * Initialize license management functionality. */ function initLicenseManagement() { var $validateBtn = $('#wp-bnb-validate-license'); var $activateBtn = $('#wp-bnb-activate-license'); var $spinner = $('#wp-bnb-license-spinner'); var $message = $('#wp-bnb-license-message'); if (!$validateBtn.length) { return; } // Validate license button click. $validateBtn.on('click', function(e) { e.preventDefault(); performLicenseAction('wp_bnb_validate_license', wpBnbAdmin.i18n.validating); }); // Activate license button click. $activateBtn.on('click', function(e) { e.preventDefault(); performLicenseAction('wp_bnb_activate_license', wpBnbAdmin.i18n.activating); }); /** * Perform a license AJAX action. * * @param {string} action AJAX action name. * @param {string} loadingText Loading text to display. */ function performLicenseAction(action, loadingText) { // Disable buttons and show spinner. $validateBtn.prop('disabled', true); $activateBtn.prop('disabled', true); $spinner.addClass('is-active'); $message.hide(); $.ajax({ url: wpBnbAdmin.ajaxUrl, type: 'POST', data: { action: action, nonce: wpBnbAdmin.nonce }, success: function(response) { $spinner.removeClass('is-active'); $validateBtn.prop('disabled', false); $activateBtn.prop('disabled', false); if (response.success) { showMessage('success', response.data.message); // Reload page after short delay to show updated status. setTimeout(function() { window.location.reload(); }, 1500); } else { showMessage('error', response.data.message || wpBnbAdmin.i18n.error); } }, error: function() { $spinner.removeClass('is-active'); $validateBtn.prop('disabled', false); $activateBtn.prop('disabled', false); showMessage('error', wpBnbAdmin.i18n.error); } }); } /** * Show a message. * * @param {string} type Message type (success or error). * @param {string} message Message text. */ function showMessage(type, message) { $message .removeClass('success error') .addClass(type) .text(message) .fadeIn(); } } /** * Initialize room gallery functionality. */ function initRoomGallery() { var $container = $('#bnb-room-gallery'); var $addButton = $('#bnb-add-gallery-images'); var $input = $('#bnb_room_gallery'); var $imagesContainer = $container.find('.bnb-gallery-images'); if (!$addButton.length) { return; } // Media frame for selecting images. var mediaFrame; // Add images button click. $addButton.on('click', function(e) { e.preventDefault(); // If frame exists, reopen it. if (mediaFrame) { mediaFrame.open(); return; } // Create media frame. mediaFrame = wp.media({ title: wpBnbAdmin.i18n.selectImages, button: { text: wpBnbAdmin.i18n.addToGallery }, multiple: true, library: { type: 'image' } }); // Handle selection. mediaFrame.on('select', function() { var selection = mediaFrame.state().get('selection'); selection.each(function(attachment) { var data = attachment.toJSON(); var thumbnail = data.sizes.thumbnail ? data.sizes.thumbnail.url : data.url; // Check if already in gallery. if ($imagesContainer.find('[data-id="' + data.id + '"]').length) { return; } // Add image to gallery. var $image = $(''); $imagesContainer.append($image); }); updateGalleryInput(); }); mediaFrame.open(); }); // Remove image button click. $imagesContainer.on('click', '.bnb-remove-image', function(e) { e.preventDefault(); $(this).closest('.bnb-gallery-image').remove(); updateGalleryInput(); }); // Make gallery sortable. $imagesContainer.sortable({ items: '.bnb-gallery-image', cursor: 'move', update: function() { updateGalleryInput(); } }); /** * Update the hidden input with gallery image IDs. */ function updateGalleryInput() { var ids = []; $imagesContainer.find('.bnb-gallery-image').each(function() { ids.push($(this).data('id')); }); $input.val(ids.join(',')); } } /** * Initialize pricing settings functionality. */ function initPricingSettings() { var $midTermInput = $('#wp_bnb_mid_term_max_nights'); var $longTermMin = $('#wp-bnb-long-term-min'); if (!$midTermInput.length || !$longTermMin.length) { return; } // Update long-term minimum display when mid-term max changes. $midTermInput.on('input', function() { $longTermMin.text($(this).val()); }); } /** * Initialize season form validation. */ function initSeasonForm() { var $form = $('.bnb-season-form'); if (!$form.length) { return; } // Validate date format on input. $form.find('#season_start_date, #season_end_date').on('input', function() { var value = $(this).val(); var isValid = /^\d{2}-\d{2}$/.test(value); if (value.length > 0 && !isValid) { $(this).css('border-color', '#d63638'); } else { $(this).css('border-color', ''); } }); // Validate modifier range. $form.find('#season_modifier').on('input', function() { var value = parseFloat($(this).val()); var $preview = $(this).siblings('.bnb-modifier-preview'); if ($preview.length === 0) { $preview = $(''); $(this).after($preview); } if (!isNaN(value) && value > 0) { var percentage = ((value - 1) * 100).toFixed(0); var text = ''; if (percentage > 0) { text = '+' + percentage + '% ' + (wpBnbAdmin.i18n.increase || 'increase'); $preview.css('color', '#d63638'); } else if (percentage < 0) { text = percentage + '% ' + (wpBnbAdmin.i18n.discount || 'discount'); $preview.css('color', '#00a32a'); } else { text = wpBnbAdmin.i18n.normalPrice || 'Normal price'; $preview.css('color', '#646970'); } $preview.text(' = ' + text); } else { $preview.text(''); } }).trigger('input'); } /** * Initialize pricing meta box interactions. */ function initPricingMetaBox() { var $pricingTable = $('.bnb-pricing-table'); if (!$pricingTable.length) { return; } // Highlight empty required prices. $pricingTable.find('input[type="number"]').on('blur', function() { var $input = $(this); var value = $input.val(); var isShortTerm = $input.attr('id').indexOf('short_term') !== -1; // Short-term price is recommended. if (isShortTerm && (value === '' || parseFloat(value) <= 0)) { $input.css('background-color', '#fcf0f1'); } else { $input.css('background-color', ''); } }); } // Initialize on document ready. $(document).ready(function() { initLicenseManagement(); initRoomGallery(); initPricingSettings(); initSeasonForm(); initPricingMetaBox(); }); })(jQuery);