diff --git a/assets/css/admin.css b/assets/css/admin.css
index cca0628..3cda32c 100644
--- a/assets/css/admin.css
+++ b/assets/css/admin.css
@@ -468,3 +468,114 @@
.licenses-table .license-actions {
width: 220px;
}
+
+/* Live Search Styles */
+.wclp-live-search-results {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ right: 0;
+ min-width: 400px;
+ max-width: 600px;
+ max-height: 400px;
+ overflow-y: auto;
+ background: #fff;
+ border: 1px solid #c3c4c7;
+ border-radius: 0 0 4px 4px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ z-index: 1000;
+}
+
+.wclp-live-search-results:empty {
+ display: none;
+}
+
+.wclp-search-result-item {
+ padding: 12px 15px;
+ border-bottom: 1px solid #f0f0f0;
+ cursor: pointer;
+ transition: background-color 0.15s ease;
+}
+
+.wclp-search-result-item:last-child {
+ border-bottom: none;
+}
+
+.wclp-search-result-item:hover,
+.wclp-search-result-item.active {
+ background-color: #f0f6fc;
+}
+
+.wclp-result-main {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 10px;
+ margin-bottom: 4px;
+}
+
+.wclp-result-key code {
+ font-size: 13px;
+ background: #f0f0f0;
+ padding: 2px 6px;
+ border-radius: 3px;
+}
+
+.wclp-result-key mark {
+ background-color: #fff8c5;
+ padding: 0;
+}
+
+.wclp-result-details {
+ display: flex;
+ gap: 15px;
+ font-size: 12px;
+ color: #646970;
+ margin-bottom: 2px;
+}
+
+.wclp-result-domain mark {
+ background-color: #fff8c5;
+ padding: 0;
+}
+
+.wclp-result-product {
+ color: #2271b1;
+}
+
+.wclp-result-customer {
+ font-size: 11px;
+ color: #8c8f94;
+}
+
+.wclp-result-customer small {
+ opacity: 0.8;
+}
+
+.wclp-search-loading,
+.wclp-search-no-results,
+.wclp-search-error {
+ padding: 15px;
+ text-align: center;
+ color: #646970;
+ font-size: 13px;
+}
+
+.wclp-search-loading .spinner {
+ float: none;
+ margin: 0 5px 0 0;
+ vertical-align: middle;
+}
+
+.wclp-search-error {
+ color: #d63638;
+}
+
+/* Search box positioning */
+.wclp-filter-form .search-box {
+ position: relative;
+}
+
+#license-search-input {
+ width: 280px;
+}
diff --git a/assets/js/admin-licenses.js b/assets/js/admin-licenses.js
new file mode 100644
index 0000000..3b866e8
--- /dev/null
+++ b/assets/js/admin-licenses.js
@@ -0,0 +1,237 @@
+/**
+ * WC Licensed Product - Admin Licenses Live Search
+ *
+ * @package Jeremias\WcLicensedProduct
+ */
+
+(function($) {
+ 'use strict';
+
+ var searchTimeout = null;
+ var $searchInput = $('#license-search-input');
+ var $resultsDropdown = null;
+ var isSearching = false;
+
+ /**
+ * Initialize live search
+ */
+ function init() {
+ if (!$searchInput.length) {
+ return;
+ }
+
+ // Create results dropdown
+ $resultsDropdown = $('
');
+ $searchInput.parent().css('position', 'relative').append($resultsDropdown);
+
+ // Bind events
+ $searchInput.on('input', handleSearchInput);
+ $searchInput.on('keydown', handleKeydown);
+ $searchInput.on('focus', function() {
+ if ($resultsDropdown.children().length > 0) {
+ $resultsDropdown.show();
+ }
+ });
+
+ // Close dropdown when clicking outside
+ $(document).on('click', function(e) {
+ if (!$(e.target).closest('.search-box').length) {
+ $resultsDropdown.hide();
+ }
+ });
+ }
+
+ /**
+ * Handle search input with debouncing
+ */
+ function handleSearchInput() {
+ var query = $searchInput.val().trim();
+
+ // Clear previous timeout
+ if (searchTimeout) {
+ clearTimeout(searchTimeout);
+ }
+
+ // Hide results if query is too short
+ if (query.length < 2) {
+ $resultsDropdown.hide().empty();
+ return;
+ }
+
+ // Show loading state
+ showLoading();
+
+ // Debounce search
+ searchTimeout = setTimeout(function() {
+ performSearch(query);
+ }, 300);
+ }
+
+ /**
+ * Handle keyboard navigation
+ */
+ function handleKeydown(e) {
+ var $items = $resultsDropdown.find('.wclp-search-result-item');
+ var $active = $items.filter('.active');
+ var index = $items.index($active);
+
+ switch (e.keyCode) {
+ case 40: // Down arrow
+ e.preventDefault();
+ if (index < $items.length - 1) {
+ $items.removeClass('active');
+ $items.eq(index + 1).addClass('active');
+ } else if (index === -1 && $items.length > 0) {
+ $items.eq(0).addClass('active');
+ }
+ break;
+
+ case 38: // Up arrow
+ e.preventDefault();
+ if (index > 0) {
+ $items.removeClass('active');
+ $items.eq(index - 1).addClass('active');
+ }
+ break;
+
+ case 13: // Enter
+ if ($active.length) {
+ e.preventDefault();
+ window.location.href = $active.data('url');
+ }
+ break;
+
+ case 27: // Escape
+ $resultsDropdown.hide();
+ break;
+ }
+ }
+
+ /**
+ * Show loading state
+ */
+ function showLoading() {
+ $resultsDropdown.html(
+ '' +
+ ' ' +
+ wclpAdmin.strings.searching +
+ '
'
+ ).show();
+ }
+
+ /**
+ * Perform AJAX search
+ */
+ function performSearch(query) {
+ if (isSearching) {
+ return;
+ }
+
+ isSearching = true;
+
+ $.ajax({
+ url: wclpAdmin.ajaxUrl,
+ type: 'GET',
+ data: {
+ action: 'wclp_live_search',
+ nonce: wclpAdmin.nonce,
+ search: query
+ },
+ success: function(response) {
+ if (response.success && response.data.results) {
+ renderResults(response.data.results, query);
+ } else {
+ showNoResults();
+ }
+ },
+ error: function() {
+ $resultsDropdown.html(
+ '' + wclpAdmin.strings.error + '
'
+ ).show();
+ },
+ complete: function() {
+ isSearching = false;
+ }
+ });
+ }
+
+ /**
+ * Render search results
+ */
+ function renderResults(results, query) {
+ if (results.length === 0) {
+ showNoResults();
+ return;
+ }
+
+ var html = '';
+ results.forEach(function(item) {
+ var statusClass = 'license-status-' + item.status;
+ var highlightedKey = highlightMatch(item.license_key, query);
+ var highlightedDomain = highlightMatch(item.domain, query);
+
+ html += '' +
+ '
' +
+ '' + highlightedKey + '' +
+ '' + escapeHtml(item.status) + '' +
+ '
' +
+ '
' +
+ '' + highlightedDomain + '' +
+ '' + escapeHtml(item.product_name) + '' +
+ '
' +
+ '
' +
+ escapeHtml(item.customer_name) +
+ (item.customer_email ? ' (' + escapeHtml(item.customer_email) + ')' : '') +
+ '
' +
+ '
';
+ });
+
+ $resultsDropdown.html(html).show();
+
+ // Make items clickable
+ $resultsDropdown.find('.wclp-search-result-item').on('click', function() {
+ window.location.href = $(this).data('url');
+ }).on('mouseenter', function() {
+ $resultsDropdown.find('.wclp-search-result-item').removeClass('active');
+ $(this).addClass('active');
+ });
+ }
+
+ /**
+ * Show no results message
+ */
+ function showNoResults() {
+ $resultsDropdown.html(
+ '' + wclpAdmin.strings.noResults + '
'
+ ).show();
+ }
+
+ /**
+ * Highlight matching text
+ */
+ function highlightMatch(text, query) {
+ if (!text || !query) {
+ return escapeHtml(text || '');
+ }
+
+ var escaped = escapeHtml(text);
+ var queryEscaped = escapeHtml(query);
+ var regex = new RegExp('(' + queryEscaped.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'gi');
+
+ return escaped.replace(regex, '$1');
+ }
+
+ /**
+ * Escape HTML entities
+ */
+ function escapeHtml(text) {
+ if (!text) return '';
+ var div = document.createElement('div');
+ div.textContent = text;
+ return div.innerHTML;
+ }
+
+ // Initialize when document is ready
+ $(document).ready(init);
+
+})(jQuery);
diff --git a/src/Admin/AdminController.php b/src/Admin/AdminController.php
index c05c151..87a34b1 100644
--- a/src/Admin/AdminController.php
+++ b/src/Admin/AdminController.php
@@ -52,6 +52,9 @@ final class AdminController
// Add to WooCommerce Reports
add_filter('woocommerce_admin_reports', [$this, 'addLicenseReports']);
+
+ // AJAX handler for live search
+ add_action('wp_ajax_wclp_live_search', [$this, 'handleLiveSearch']);
}
/**
@@ -108,6 +111,67 @@ final class AdminController
[],
WC_LICENSED_PRODUCT_VERSION
);
+
+ // Enqueue live search script on licenses page
+ if ($isLicensePage) {
+ wp_enqueue_script(
+ 'wc-licensed-product-admin',
+ WC_LICENSED_PRODUCT_PLUGIN_URL . 'assets/js/admin-licenses.js',
+ ['jquery'],
+ WC_LICENSED_PRODUCT_VERSION,
+ true
+ );
+
+ wp_localize_script('wc-licensed-product-admin', 'wclpAdmin', [
+ 'ajaxUrl' => admin_url('admin-ajax.php'),
+ 'nonce' => wp_create_nonce('wclp_live_search'),
+ 'strings' => [
+ 'noResults' => __('No licenses found', 'wc-licensed-product'),
+ 'searching' => __('Searching...', 'wc-licensed-product'),
+ 'error' => __('Search failed', 'wc-licensed-product'),
+ ],
+ ]);
+ }
+ }
+
+ /**
+ * Handle AJAX live search request
+ */
+ public function handleLiveSearch(): void
+ {
+ check_ajax_referer('wclp_live_search', 'nonce');
+
+ if (!current_user_can('manage_woocommerce')) {
+ wp_send_json_error(['message' => __('Permission denied.', 'wc-licensed-product')], 403);
+ }
+
+ $search = isset($_GET['search']) ? sanitize_text_field($_GET['search']) : '';
+
+ if (strlen($search) < 2) {
+ wp_send_json_success(['results' => []]);
+ }
+
+ $filters = ['search' => $search];
+ $licenses = $this->licenseManager->getAllLicenses(1, 10, $filters);
+
+ $results = [];
+ foreach ($licenses as $license) {
+ $product = wc_get_product($license->getProductId());
+ $customer = get_userdata($license->getCustomerId());
+
+ $results[] = [
+ 'id' => $license->getId(),
+ 'license_key' => $license->getLicenseKey(),
+ 'domain' => $license->getDomain(),
+ 'status' => $license->getStatus(),
+ 'product_name' => $product ? $product->get_name() : __('Unknown', 'wc-licensed-product'),
+ 'customer_name' => $customer ? $customer->display_name : __('Guest', 'wc-licensed-product'),
+ 'customer_email' => $customer ? $customer->user_email : '',
+ 'view_url' => admin_url('admin.php?page=wc-licenses&s=' . urlencode($license->getLicenseKey())),
+ ];
+ }
+
+ wp_send_json_success(['results' => $results]);
}
/**