You've already forked wc-licensed-product
v0.0.4: - Add WooCommerce settings tab for default license settings - Per-product settings override global defaults v0.0.5: - Add bulk license operations (activate, deactivate, revoke, extend, delete) - Add license renewal/extension and lifetime functionality - Add quick action buttons per license row v0.0.6: - Add license dashboard with statistics and analytics - Add license transfer functionality (admin) - Add CSV export for licenses - Add OpenAPI 3.1 specification - Remove /deactivate API endpoint v0.0.7: - Move license dashboard to WooCommerce Reports section - Add license search and filtering in admin - Add customer-facing license transfer with AJAX modal - Add email notifications for license expiration warnings - Add bulk import licenses from CSV - Update README with comprehensive documentation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
208 lines
7.0 KiB
JavaScript
208 lines
7.0 KiB
JavaScript
/**
|
|
* WC Licensed Product - Frontend Scripts
|
|
*
|
|
* @package Jeremias\WcLicensedProduct
|
|
*/
|
|
|
|
(function($) {
|
|
'use strict';
|
|
|
|
var WCLicensedProductFrontend = {
|
|
$modal: null,
|
|
$form: null,
|
|
|
|
init: function() {
|
|
this.$modal = $('#wclp-transfer-modal');
|
|
this.$form = $('#wclp-transfer-form');
|
|
this.bindEvents();
|
|
},
|
|
|
|
bindEvents: function() {
|
|
$(document).on('click', '.copy-license-btn', this.copyLicenseKey);
|
|
|
|
// Transfer modal events
|
|
$(document).on('click', '.wclp-transfer-btn', this.openTransferModal.bind(this));
|
|
$(document).on('click', '.wclp-modal-close, .wclp-modal-cancel, .wclp-modal-overlay', this.closeTransferModal.bind(this));
|
|
$(document).on('submit', '#wclp-transfer-form', this.submitTransfer.bind(this));
|
|
|
|
// Close modal on escape key
|
|
$(document).on('keyup', function(e) {
|
|
if (e.key === 'Escape') {
|
|
WCLicensedProductFrontend.closeTransferModal();
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Copy license key to clipboard
|
|
*/
|
|
copyLicenseKey: function(e) {
|
|
e.preventDefault();
|
|
|
|
var $btn = $(this);
|
|
var licenseKey = $btn.data('license-key');
|
|
|
|
if (!licenseKey) {
|
|
return;
|
|
}
|
|
|
|
// Use modern clipboard API if available
|
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
navigator.clipboard.writeText(licenseKey)
|
|
.then(function() {
|
|
WCLicensedProductFrontend.showCopyFeedback($btn, true);
|
|
})
|
|
.catch(function() {
|
|
WCLicensedProductFrontend.fallbackCopy(licenseKey, $btn);
|
|
});
|
|
} else {
|
|
WCLicensedProductFrontend.fallbackCopy(licenseKey, $btn);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Fallback copy method for older browsers
|
|
*/
|
|
fallbackCopy: function(text, $btn) {
|
|
var $temp = $('<textarea>');
|
|
$('body').append($temp);
|
|
$temp.val(text).select();
|
|
|
|
try {
|
|
var success = document.execCommand('copy');
|
|
WCLicensedProductFrontend.showCopyFeedback($btn, success);
|
|
} catch (err) {
|
|
WCLicensedProductFrontend.showCopyFeedback($btn, false);
|
|
}
|
|
|
|
$temp.remove();
|
|
},
|
|
|
|
/**
|
|
* Show feedback after copy attempt
|
|
*/
|
|
showCopyFeedback: function($btn, success) {
|
|
var message = success
|
|
? wcLicensedProduct.strings.copied
|
|
: wcLicensedProduct.strings.copyFailed;
|
|
|
|
var $feedback = $('<span class="copy-feedback"></span>')
|
|
.text(message)
|
|
.addClass(success ? 'success' : 'error');
|
|
|
|
$btn.after($feedback);
|
|
|
|
setTimeout(function() {
|
|
$feedback.fadeOut(300, function() {
|
|
$(this).remove();
|
|
});
|
|
}, 1500);
|
|
},
|
|
|
|
/**
|
|
* Open transfer modal
|
|
*/
|
|
openTransferModal: function(e) {
|
|
e.preventDefault();
|
|
|
|
var $btn = $(e.currentTarget);
|
|
var licenseId = $btn.data('license-id');
|
|
var currentDomain = $btn.data('current-domain');
|
|
|
|
$('#transfer-license-id').val(licenseId);
|
|
$('#transfer-current-domain').text(currentDomain);
|
|
$('#transfer-new-domain').val('');
|
|
$('#wclp-transfer-message').hide().removeClass('success error');
|
|
$('#wclp-transfer-submit').prop('disabled', false);
|
|
|
|
this.$modal.show();
|
|
$('#transfer-new-domain').focus();
|
|
},
|
|
|
|
/**
|
|
* Close transfer modal
|
|
*/
|
|
closeTransferModal: function(e) {
|
|
if (e && $(e.target).closest('.wclp-modal-content').length && !$(e.target).is('.wclp-modal-close, .wclp-modal-cancel')) {
|
|
return;
|
|
}
|
|
this.$modal.hide();
|
|
},
|
|
|
|
/**
|
|
* Submit transfer request
|
|
*/
|
|
submitTransfer: function(e) {
|
|
e.preventDefault();
|
|
|
|
var self = this;
|
|
var licenseId = $('#transfer-license-id').val();
|
|
var newDomain = $('#transfer-new-domain').val().trim();
|
|
var $message = $('#wclp-transfer-message');
|
|
var $submit = $('#wclp-transfer-submit');
|
|
|
|
// Basic validation
|
|
if (!newDomain) {
|
|
$message.text(wcLicensedProduct.strings.invalidDomain)
|
|
.removeClass('success').addClass('error').show();
|
|
return;
|
|
}
|
|
|
|
// Confirm transfer
|
|
if (!confirm(wcLicensedProduct.strings.transferConfirm)) {
|
|
return;
|
|
}
|
|
|
|
// Disable submit button
|
|
$submit.prop('disabled', true);
|
|
$message.hide();
|
|
|
|
// Send AJAX request
|
|
$.ajax({
|
|
url: wcLicensedProduct.ajaxUrl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'wclp_customer_transfer_license',
|
|
nonce: wcLicensedProduct.transferNonce,
|
|
license_id: licenseId,
|
|
new_domain: newDomain
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
$message.text(response.data.message)
|
|
.removeClass('error').addClass('success').show();
|
|
|
|
// Update the domain display in the license card
|
|
var $domainDisplay = $('.license-domain-display[data-license-id="' + licenseId + '"]');
|
|
$domainDisplay.find('.domain-value').text(response.data.new_domain);
|
|
$domainDisplay.find('.wclp-transfer-btn').data('current-domain', response.data.new_domain);
|
|
|
|
// Close modal after a short delay
|
|
setTimeout(function() {
|
|
self.closeTransferModal();
|
|
}, 1500);
|
|
} else {
|
|
$message.text(response.data.message || wcLicensedProduct.strings.transferError)
|
|
.removeClass('success').addClass('error').show();
|
|
$submit.prop('disabled', false);
|
|
}
|
|
},
|
|
error: function(xhr) {
|
|
var message = wcLicensedProduct.strings.transferError;
|
|
if (xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message) {
|
|
message = xhr.responseJSON.data.message;
|
|
}
|
|
$message.text(message)
|
|
.removeClass('success').addClass('error').show();
|
|
$submit.prop('disabled', false);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
$(document).ready(function() {
|
|
WCLicensedProductFrontend.init();
|
|
});
|
|
|
|
})(jQuery);
|