/** * Admin JavaScript for Informatiq Smart Pricing */ console.log('Informatiq Smart Pricing: Script loaded'); (function($) { 'use strict'; console.log('Informatiq Smart Pricing: IIFE executed, jQuery available:', typeof $ !== 'undefined'); var InformatiqSP = { /** * Initialize */ init: function() { console.log('Informatiq Smart Pricing: init() called'); console.log('informatiqSP object:', typeof informatiqSP !== 'undefined' ? informatiqSP : 'NOT DEFINED'); this.bindEvents(); }, /** * Bind event handlers */ bindEvents: function() { console.log('Informatiq Smart Pricing: bindEvents() called'); var $compareBtn = $('#informatiq-sp-compare-products'); console.log('Compare products button found:', $compareBtn.length > 0); $('#informatiq-sp-manual-sync').on('click', this.handleManualSync); $('#informatiq-sp-test-connection').on('click', this.handleTestConnection); $('#informatiq-sp-revoke-auth').on('click', this.handleRevokeAuth); $compareBtn.on('click', this.handleCompareProducts); console.log('Informatiq Smart Pricing: All event handlers bound'); }, /** * Handle manual sync button click */ handleManualSync: function(e) { e.preventDefault(); var $button = $(this); var $status = $('#informatiq-sp-sync-status'); // Confirm action if (!confirm(informatiqSP.strings.confirmSync || 'Are you sure you want to run a manual price sync? This may take several minutes.')) { return; } // Disable button and show loading state $button.prop('disabled', true).addClass('informatiq-sp-loading'); // Show status message $status .removeClass('notice-success notice-error') .addClass('notice-info') .html('

' + (informatiqSP.strings.syncInProgress || 'Sync in progress...') + '

') .show(); // Make AJAX request $.ajax({ url: informatiqSP.ajaxUrl, type: 'POST', data: { action: 'informatiq_sp_manual_sync', nonce: informatiqSP.nonce }, success: function(response) { if (response.success) { $status .removeClass('notice-info notice-error') .addClass('notice-success') .html('

' + response.data.message + '

'); // Reload page after 2 seconds to show updated logs setTimeout(function() { location.reload(); }, 2000); } else { $status .removeClass('notice-info notice-success') .addClass('notice-error') .html('

Error: ' + (response.data.message || 'Unknown error') + '

'); } }, error: function(jqXHR, textStatus, errorThrown) { $status .removeClass('notice-info notice-success') .addClass('notice-error') .html('

Error: ' + errorThrown + '

'); }, complete: function() { $button.prop('disabled', false).removeClass('informatiq-sp-loading'); } }); }, /** * Handle test connection button click */ handleTestConnection: function(e) { e.preventDefault(); var $button = $(this); var $status = $('#informatiq-sp-sync-status'); // Disable button and show loading state $button.prop('disabled', true).addClass('informatiq-sp-loading'); // Show status message $status .removeClass('notice-success notice-error') .addClass('notice-info') .html('

' + (informatiqSP.strings.testInProgress || 'Testing connection...') + '

') .show(); // Make AJAX request $.ajax({ url: informatiqSP.ajaxUrl, type: 'POST', data: { action: 'informatiq_sp_test_connection', nonce: informatiqSP.nonce }, success: function(response) { if (response.success) { $status .removeClass('notice-info notice-error') .addClass('notice-success') .html('

' + response.data.message + '

'); } else { $status .removeClass('notice-info notice-success') .addClass('notice-error') .html('

Error: ' + (response.data.message || 'Unknown error') + '

'); } }, error: function(jqXHR, textStatus, errorThrown) { $status .removeClass('notice-info notice-success') .addClass('notice-error') .html('

Error: ' + errorThrown + '

'); }, complete: function() { $button.prop('disabled', false).removeClass('informatiq-sp-loading'); // Hide status message after 5 seconds setTimeout(function() { $status.fadeOut(); }, 5000); } }); }, /** * Handle revoke authorization button click */ handleRevokeAuth: function(e) { e.preventDefault(); var $button = $(this); // Confirm action if (!confirm(informatiqSP.strings.revokeConfirm || 'Are you sure you want to revoke Google authorization?')) { return; } // Disable button and show loading state $button.prop('disabled', true).text(informatiqSP.strings.revokeInProgress || 'Revoking...'); // Make AJAX request $.ajax({ url: informatiqSP.ajaxUrl, type: 'POST', data: { action: 'informatiq_sp_revoke_auth', nonce: informatiqSP.nonce }, success: function(response) { if (response.success) { // Reload page to show updated status location.reload(); } else { alert('Error: ' + (response.data.message || 'Unknown error')); $button.prop('disabled', false).text('Revoke Authorization'); } }, error: function(jqXHR, textStatus, errorThrown) { alert('Error: ' + errorThrown); $button.prop('disabled', false).text('Revoke Authorization'); } }); }, /** * Handle compare products button click */ handleCompareProducts: function(e) { e.preventDefault(); console.log('=== COMPARE PRODUCTS CLICKED ==='); var $button = $(this); var $spinner = $button.next('.spinner'); var $results = $('#informatiq-sp-comparison-results'); var $tbody = $('#informatiq-sp-comparison-tbody'); var $status = $('#informatiq-sp-sync-status'); console.log('Button:', $button.length); console.log('Spinner:', $spinner.length); console.log('Results container:', $results.length); console.log('informatiqSP:', informatiqSP); // Show loading status $status .removeClass('notice-success notice-error') .addClass('notice-info') .html('

Loading product comparison... This may take a moment.

') .show(); // Disable button and show spinner $button.prop('disabled', true); $spinner.addClass('is-active'); console.log('Making AJAX request to:', informatiqSP.ajaxUrl); console.log('With nonce:', informatiqSP.nonce); // Make AJAX request $.ajax({ url: informatiqSP.ajaxUrl, type: 'POST', timeout: 120000, // 2 minute timeout data: { action: 'informatiq_sp_compare_products', nonce: informatiqSP.nonce }, beforeSend: function(xhr) { console.log('AJAX beforeSend - request starting'); }, success: function(response) { console.log('AJAX success callback'); console.log('AJAX response:', response); // Log debug info if available. if (response.data && response.data.debug) { console.log('=== DEBUG INFO ==='); console.log('Sample Google product:', response.data.debug.sample_google_product); console.log('Sample indexed keys:', response.data.debug.sample_google_keys); console.log('Total indexed entries:', response.data.debug.index_count); console.log('=================='); } $status.hide(); if (response.success) { var data = response.data; var html = ''; // Stats counters. var stats = { total: 0, withBenchmark: 0, cheaper: 0, competitive: 0, expensive: 0, totalPotentialGain: 0 }; if (data.products.length === 0) { html = 'No in-stock products with SKU found.'; } else { $.each(data.products, function(i, product) { stats.total++; var localPrice = product.local_price ? data.currency + parseFloat(product.local_price).toFixed(2) : '-'; var benchmarkPrice = product.benchmark_price ? data.currency + parseFloat(product.benchmark_price).toFixed(2) : '-'; var recommendedPrice = product.recommended_price ? data.currency + parseFloat(product.recommended_price).toFixed(2) : '-'; var potentialGain = '-'; var priceLabel = product.price_type === 'sale' ? ' (sale)' : ''; // Status and colors. var statusText = '-'; var statusStyle = ''; var localPriceStyle = ''; var gainStyle = ''; if (product.has_benchmark) { stats.withBenchmark++; if (product.price_status === 'cheaper') { stats.cheaper++; statusText = 'Cheaper'; statusStyle = 'color: #00a32a; font-weight: bold;'; localPriceStyle = 'color: #00a32a;'; } else if (product.price_status === 'competitive') { stats.competitive++; statusText = 'Competitive'; statusStyle = 'color: #2271b1; font-weight: bold;'; localPriceStyle = 'color: #2271b1;'; } else if (product.price_status === 'expensive') { stats.expensive++; statusText = 'Expensive'; statusStyle = 'color: #d63638; font-weight: bold;'; localPriceStyle = 'color: #d63638;'; } if (product.potential_gain !== null) { var gain = parseFloat(product.potential_gain); stats.totalPotentialGain += gain; if (gain > 0) { potentialGain = '+' + data.currency + gain.toFixed(2); gainStyle = 'color: #00a32a; font-weight: bold;'; } else if (gain < 0) { potentialGain = '-' + data.currency + Math.abs(gain).toFixed(2); gainStyle = 'color: #d63638;'; } else { potentialGain = data.currency + '0.00'; } } } else if (product.found) { statusText = 'No benchmark'; statusStyle = 'color: #dba617;'; } else { statusText = 'Not in Google'; statusStyle = 'color: #888;'; } html += ''; html += '' + product.name + ''; html += '' + localPrice + priceLabel + ''; html += '' + benchmarkPrice + ''; html += '' + recommendedPrice + ''; html += '' + potentialGain + ''; html += '' + statusText + ''; html += ''; }); } $tbody.html(html); $results.show(); // Show summary with statistics. var $summary = $('#informatiq-sp-comparison-summary'); var summaryHtml = 'Summary: '; summaryHtml += stats.withBenchmark + ' of ' + stats.total + ' products have competitor data. '; summaryHtml += '' + stats.cheaper + ' cheaper, '; summaryHtml += '' + stats.competitive + ' competitive, '; summaryHtml += '' + stats.expensive + ' expensive. '; if (stats.totalPotentialGain > 0) { summaryHtml += '
Total potential gain if optimized: +' + data.currency + stats.totalPotentialGain.toFixed(2) + ' per sale'; } else if (stats.totalPotentialGain < 0) { summaryHtml += '
Current margin vs recommended: ' + data.currency + stats.totalPotentialGain.toFixed(2) + ''; } $summary.html(summaryHtml).show(); } else { $status .removeClass('notice-info notice-success') .addClass('notice-error') .html('

Error: ' + (response.data.message || 'Unknown error') + '

') .show(); } }, error: function(jqXHR, textStatus, errorThrown) { console.error('AJAX error:', textStatus, errorThrown, jqXHR.responseText); $status .removeClass('notice-info notice-success') .addClass('notice-error') .html('

Error: ' + errorThrown + ' - ' + textStatus + '

') .show(); }, complete: function() { console.log('AJAX request complete'); $button.prop('disabled', false); $spinner.removeClass('is-active'); } }); } }; // Initialize when document is ready $(document).ready(function() { InformatiqSP.init(); }); })(jQuery);