Implement versions 0.0.4-0.0.7 features

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>
This commit is contained in:
2026-01-21 20:32:35 +01:00
parent 78e43b9aea
commit 49a0699963
21 changed files with 4132 additions and 289 deletions

View File

@@ -8,12 +8,29 @@
'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();
}
});
},
/**
@@ -80,6 +97,106 @@
$(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);
}
});
}
};