| @@ -1,570 +1,34 @@ | ||
| 1 | -// Simple debounce function implementation | |
| 2 | -function debounce(func, wait) { | |
| 3 | - let timeout; | |
| 4 | - return function executedFunction(...args) { | |
| 5 | - const later = () => { | |
| 6 | - clearTimeout(timeout); | |
| 7 | - func(...args); | |
| 8 | - }; | |
| 9 | - clearTimeout(timeout); | |
| 10 | - timeout = setTimeout(later, wait); | |
| 11 | - }; | |
| 12 | -} | |
| 1 | +jQuery(document).ready(function($) { | |
| 2 | + $('#mxchat-activation-form').on('submit', function(event) { | |
| 3 | + event.preventDefault(); | |
| 13 | 4 | |
| 14 | -// Helper function to open edit modal | |
| 15 | -function mxchatOpenEditModal(intentId, phrases) { | |
| 16 | - const modal = document.getElementById('mxchat-edit-modal'); | |
| 17 | - if (!modal) return; | |
| 18 | - | |
| 19 | - // Get form fields | |
| 20 | - const intentIdField = document.getElementById('edit_intent_id'); | |
| 21 | - const phrasesField = document.getElementById('edit_phrases'); | |
| 22 | - | |
| 23 | - // Set values | |
| 24 | - intentIdField.value = intentId; | |
| 25 | - phrasesField.value = phrases; | |
| 26 | - | |
| 27 | - // Show modal with animation | |
| 28 | - modal.style.display = 'flex'; | |
| 29 | - requestAnimationFrame(() => { | |
| 30 | - modal.classList.add('active'); | |
| 31 | - }); | |
| 32 | - | |
| 33 | - // Set up close handlers | |
| 34 | - const closeModal = () => { | |
| 35 | - modal.classList.remove('active'); | |
| 36 | - setTimeout(() => { | |
| 37 | - modal.style.display = 'none'; | |
| 38 | - }, 300); // Match the CSS transition time | |
| 39 | - }; | |
| 40 | - | |
| 41 | - // Close button handler | |
| 42 | - const closeBtn = modal.querySelector('.mxchat-modal-close'); | |
| 43 | - if (closeBtn) { | |
| 44 | - closeBtn.onclick = closeModal; | |
| 45 | - } | |
| 46 | - | |
| 47 | - // Cancel button handler | |
| 48 | - const cancelBtn = modal.querySelector('.mxchat-modal-cancel'); | |
| 49 | - if (cancelBtn) { | |
| 50 | - cancelBtn.onclick = closeModal; | |
| 51 | - } | |
| 52 | - | |
| 53 | - // Click outside modal to close | |
| 54 | - modal.onclick = (e) => { | |
| 55 | - if (e.target === modal) { | |
| 56 | - closeModal(); | |
| 57 | - } | |
| 58 | - }; | |
| 59 | - | |
| 60 | - // Focus the textarea | |
| 61 | - phrasesField.focus(); | |
| 62 | -} | |
| 63 | - | |
| 64 | -// Initialize event listeners | |
| 65 | -document.addEventListener('DOMContentLoaded', () => { | |
| 66 | - // Set up edit button handlers | |
| 67 | - document.querySelectorAll('.mxchat-edit-button').forEach(button => { | |
| 68 | - button.onclick = () => { | |
| 69 | - const intentId = button.dataset.intentId; | |
| 70 | - const phrases = button.dataset.phrases; | |
| 71 | - mxchatOpenEditModal(intentId, phrases); | |
| 5 | + var formData = { | |
| 6 | + action: 'mxchat_activate_license', | |
| 7 | + email: $('#mxchat_pro_email').val(), | |
| 8 | + key: $('#mxchat_activation_key').val(), | |
| 9 | + security: mxchatAdmin.nonce | |
| 72 | 10 | }; |
| 73 | - }); | |
| 74 | -}); | |
| 75 | 11 | |
| 76 | -jQuery(document).ready(function($) { | |
| 77 | - // Ensure we have a debounce function (use lodash if available, otherwise use our implementation) | |
| 78 | - const useDebounce = (window._ && window._.debounce) ? window._.debounce : debounce; | |
| 79 | - | |
| 80 | - // --- AJAX Auto-Save --- | |
| 81 | - const $autosaveSections = $('.mxchat-autosave-section'); | |
| 82 | - | |
| 83 | - if ($autosaveSections.length) { | |
| 84 | - // Handle real-time range slider value updates | |
| 85 | - $autosaveSections.find('input[type="range"]').on('input', function() { | |
| 86 | - const value = $(this).val(); | |
| 87 | - $('#threshold_value').text(value); | |
| 88 | - }); | |
| 89 | - | |
| 90 | - // Handle all input changes (including range slider) | |
| 91 | - $autosaveSections.find('input, textarea, select').on('change', function() { | |
| 92 | - const $field = $(this); | |
| 93 | - const name = $field.attr('name'); | |
| 94 | - let value; | |
| 95 | - | |
| 96 | - // Handle different input types | |
| 97 | - if ($field.attr('type') === 'checkbox') { | |
| 98 | - value = $field.is(':checked') ? 'on' : 'off'; | |
| 99 | - } else { | |
| 100 | - value = $field.val(); | |
| 101 | - } | |
| 102 | - | |
| 103 | - // Create feedback container | |
| 104 | - const feedbackContainer = $('<div class="feedback-container"></div>'); | |
| 105 | - const spinner = $('<div class="saving-spinner"></div>'); | |
| 106 | - const successIcon = $('<div class="success-icon">✔</div>'); | |
| 107 | - | |
| 108 | - // Position feedback container based on input type | |
| 109 | - if ($field.closest('.toggle-switch').length) { | |
| 110 | - $field.closest('td').append(feedbackContainer); | |
| 111 | - } else if ($field.closest('.mxchat-toggle-switch').length) { | |
| 112 | - $field.closest('.mxchat-toggle-container').append(feedbackContainer); | |
| 113 | - } else if ($field.closest('.slider-container').length) { | |
| 114 | - $field.closest('.slider-container').after(feedbackContainer); | |
| 115 | - } else { | |
| 116 | - $field.after(feedbackContainer); | |
| 117 | - } | |
| 118 | - feedbackContainer.append(spinner); | |
| 119 | - | |
| 120 | - // Determine which AJAX action and nonce to use: | |
| 121 | - var ajaxAction, nonce; | |
| 122 | - // Use the new AJAX action for submenu fields: | |
| 123 | - if ( name.indexOf('mxchat_prompts_options') !== -1 || | |
| 124 | - name === 'mxchat_auto_sync_posts' || | |
| 125 | - name === 'mxchat_auto_sync_pages' ) { | |
| 126 | - ajaxAction = 'mxchat_save_prompts_setting'; | |
| 127 | - nonce = mxchatPromptsAdmin.prompts_setting_nonce; | |
| 128 | - } else { | |
| 129 | - // Otherwise, use the existing AJAX action. | |
| 130 | - ajaxAction = 'mxchat_save_setting'; | |
| 131 | - nonce = mxchatAdmin.setting_nonce; | |
| 132 | - } | |
| 133 | - | |
| 134 | - // AJAX save request | |
| 135 | - $.ajax({ | |
| 136 | - url: (ajaxAction === 'mxchat_save_prompts_setting') ? mxchatPromptsAdmin.ajax_url : mxchatAdmin.ajax_url, | |
| 137 | - type: 'POST', | |
| 138 | - data: { | |
| 139 | - action: ajaxAction, | |
| 140 | - name: name, | |
| 141 | - value: value, | |
| 142 | - _ajax_nonce: nonce | |
| 143 | - }, | |
| 144 | - success: function(response) { | |
| 145 | - if (response.success) { | |
| 146 | - spinner.fadeOut(200, function() { | |
| 147 | - feedbackContainer.append(successIcon); | |
| 148 | - successIcon.fadeIn(200).delay(1000).fadeOut(200, function() { | |
| 149 | - feedbackContainer.remove(); | |
| 150 | - }); | |
| 151 | - }); | |
| 152 | - } else { | |
| 153 | - alert('Error saving: ' + (response.data?.message || 'Unknown error')); | |
| 154 | - if ($field.attr('type') === 'checkbox') { | |
| 155 | - $field.prop('checked', !$field.is(':checked')); | |
| 156 | - } | |
| 157 | - feedbackContainer.remove(); | |
| 158 | - } | |
| 159 | - }, | |
| 160 | - error: function() { | |
| 161 | - alert('An error occurred while saving.'); | |
| 162 | - if ($field.attr('type') === 'checkbox') { | |
| 163 | - $field.prop('checked', !$field.is(':checked')); | |
| 164 | - } | |
| 165 | - feedbackContainer.remove(); | |
| 166 | - } | |
| 167 | - }); | |
| 168 | - }); | |
| 169 | - | |
| 170 | - // Initialize color pickers with debouncing | |
| 171 | - $autosaveSections.find('.my-color-field').each(function() { | |
| 172 | - const $colorField = $(this); | |
| 173 | - | |
| 174 | - $(this).wpColorPicker({ | |
| 175 | - change: useDebounce(function(event, ui) { | |
| 176 | - // Safety check - ensure we have a valid field and value | |
| 177 | - if (!$colorField || !$colorField.val()) { | |
| 178 | - console.warn('Color picker not ready'); | |
| 179 | - return; | |
| 180 | - } | |
| 181 | - | |
| 182 | - const name = $colorField.attr('name'); | |
| 183 | - const value = $colorField.val(); | |
| 184 | - | |
| 185 | - if (!name || !value) { | |
| 186 | - console.warn('Missing required color picker values'); | |
| 187 | - return; | |
| 188 | - } | |
| 189 | - | |
| 190 | - // Create feedback container | |
| 191 | - const feedbackContainer = $('<div class="feedback-container"></div>'); | |
| 192 | - const spinner = $('<div class="saving-spinner"></div>'); | |
| 193 | - const successIcon = $('<div class="success-icon">✔</div>'); | |
| 194 | - | |
| 195 | - // Position feedback container | |
| 196 | - $colorField.closest('.wp-picker-container').after(feedbackContainer); | |
| 197 | - feedbackContainer.append(spinner); | |
| 198 | - | |
| 199 | - // Determine AJAX action and nonce for color fields: | |
| 200 | - var ajaxAction, nonce; | |
| 201 | - if ( name.indexOf('mxchat_prompts_options') !== -1 || | |
| 202 | - name === 'mxchat_auto_sync_posts' || | |
| 203 | - name === 'mxchat_auto_sync_pages' ) { | |
| 204 | - ajaxAction = 'mxchat_save_prompts_setting'; | |
| 205 | - nonce = mxchatPromptsAdmin.prompts_setting_nonce; | |
| 206 | - } else { | |
| 207 | - ajaxAction = 'mxchat_save_setting'; | |
| 208 | - nonce = mxchatAdmin.setting_nonce; | |
| 209 | - } | |
| 210 | - | |
| 211 | - // AJAX save request | |
| 212 | - $.ajax({ | |
| 213 | - url: (ajaxAction === 'mxchat_save_prompts_setting') ? mxchatPromptsAdmin.ajax_url : mxchatAdmin.ajax_url, | |
| 214 | - type: 'POST', | |
| 215 | - data: { | |
| 216 | - action: ajaxAction, | |
| 217 | - name: name, | |
| 218 | - value: value, | |
| 219 | - _ajax_nonce: nonce | |
| 220 | - }, | |
| 221 | - success: function(response) { | |
| 222 | - if (response.success) { | |
| 223 | - spinner.fadeOut(200, function() { | |
| 224 | - feedbackContainer.append(successIcon); | |
| 225 | - successIcon.fadeIn(200).delay(1000).fadeOut(200, function() { | |
| 226 | - feedbackContainer.remove(); | |
| 227 | - }); | |
| 228 | - }); | |
| 229 | - } else { | |
| 230 | - alert('Error saving: ' + (response.data?.message || 'Unknown error')); | |
| 231 | - feedbackContainer.remove(); | |
| 232 | - } | |
| 233 | - }, | |
| 234 | - error: function() { | |
| 235 | - alert('An error occurred while saving.'); | |
| 236 | - feedbackContainer.remove(); | |
| 237 | - } | |
| 238 | - }); | |
| 239 | - }, 500) | |
| 240 | - }); | |
| 241 | - }); | |
| 242 | - | |
| 243 | - // Reinitialize color pickers when switching tabs | |
| 244 | - $('.mxchat-nav-tab').on('click.mxchat', function() { | |
| 245 | - setTimeout(function() { | |
| 246 | - $('.my-color-field:visible').wpColorPicker('close'); | |
| 247 | - }, 100); | |
| 248 | - }); | |
| 249 | - } | |
| 250 | - | |
| 251 | - // Initialize tabs system | |
| 252 | - function initTabs() { | |
| 253 | - // Remove any existing handlers first | |
| 254 | - $('.mxchat-nav-tab').off('click.mxchat'); | |
| 255 | - | |
| 256 | - // Add new click handlers | |
| 257 | - $('.mxchat-nav-tab').on('click.mxchat', function(e) { | |
| 258 | - e.preventDefault(); | |
| 259 | - e.stopPropagation(); | |
| 260 | - | |
| 261 | - var $this = $(this); | |
| 262 | - | |
| 263 | - // Get tab ID - try href first, fallback to data-tab, then to default | |
| 264 | - var tabId = $this.attr('href'); | |
| 265 | - if (tabId) { | |
| 266 | - tabId = tabId.replace('#', ''); | |
| 267 | - } else { | |
| 268 | - tabId = $this.data('tab') || 'chatbot'; | |
| 269 | - } | |
| 270 | - | |
| 271 | - // Safety check for empty tabId | |
| 272 | - if (!tabId) { | |
| 273 | - console.warn('No tab identifier found'); | |
| 274 | - return; | |
| 275 | - } | |
| 276 | - | |
| 277 | - // Update tabs | |
| 278 | - $('.mxchat-nav-tab').removeClass('mxchat-nav-tab-active'); | |
| 279 | - $this.addClass('mxchat-nav-tab-active'); | |
| 280 | - | |
| 281 | - // Update content areas - with safety check | |
| 282 | - $('.mxchat-tab-content').removeClass('active').hide(); | |
| 283 | - var $targetTab = $('#' + tabId); | |
| 284 | - if ($targetTab.length) { | |
| 285 | - $targetTab.addClass('active').show(); | |
| 286 | - | |
| 287 | - // Store active tab | |
| 288 | - try { | |
| 289 | - localStorage.setItem('mxchat_active_tab', tabId); | |
| 290 | - } catch (e) { | |
| 291 | - console.warn('LocalStorage not available:', e); | |
| 292 | - } | |
| 293 | - } else { | |
| 294 | - console.warn('Tab content #' + tabId + ' not found'); | |
| 295 | - } | |
| 296 | - }); | |
| 297 | - } | |
| 298 | - | |
| 299 | - // Initialize tabs and handle events | |
| 300 | - initTabs(); | |
| 301 | - $(document).on('widget-added widget-updated postbox-toggled', initTabs); | |
| 302 | - | |
| 303 | - // Activate initial tab | |
| 304 | - try { | |
| 305 | - var savedTab = localStorage.getItem('mxchat_active_tab'); | |
| 306 | - if (savedTab && $('#' + savedTab).length > 0) { | |
| 307 | - $('.mxchat-nav-tab[href="#' + savedTab + '"]').trigger('click.mxchat'); | |
| 308 | - } else { | |
| 309 | - $('.mxchat-nav-tab').first().trigger('click.mxchat'); | |
| 310 | - } | |
| 311 | - } catch (e) { | |
| 312 | - $('.mxchat-nav-tab').first().trigger('click.mxchat'); | |
| 313 | - } | |
| 314 | - | |
| 315 | - // Attach edit modal event handler | |
| 316 | - $(document).on('click', '.mxchat-edit-button', function() { | |
| 317 | - const intentId = $(this).data('intent-id'); | |
| 318 | - const phrases = $(this).data('phrases'); | |
| 319 | - mxchatOpenEditModal(intentId, phrases); | |
| 320 | - }); | |
| 321 | - | |
| 322 | - // Toggle visibility handlers | |
| 323 | - function toggleVisibility(selector) { | |
| 324 | - $(selector).on('click', function() { | |
| 325 | - var inputField = $(this).prev('input'); | |
| 326 | - if (inputField.attr('type') === 'password') { | |
| 327 | - inputField.attr('type', 'text'); | |
| 328 | - $(this).text('Hide'); | |
| 329 | - } else { | |
| 330 | - inputField.attr('type', 'password'); | |
| 331 | - $(this).text('Show'); | |
| 332 | - } | |
| 333 | - }); | |
| 334 | - } | |
| 335 | - | |
| 336 | - // Initialize all toggle visibility buttons | |
| 337 | - [ | |
| 338 | - '#toggleApiKeyVisibility', | |
| 339 | - '#toggleWooCommerceSecretVisibility', | |
| 340 | - '#toggleLoopsApiKeyVisibility', | |
| 341 | - '#toggleXaiApiKeyVisibility', | |
| 342 | - '#toggleClaudeApiKeyVisibility', | |
| 343 | - '#toggleBraveApiKeyVisibility', | |
| 344 | - '#toggleWebhookUrlVisibility', | |
| 345 | - '#toggleSecretKeyVisibility', | |
| 346 | - '#toggleBotTokenVisibility', | |
| 347 | - '#toggleDeepSeekApiKeyVisibility' | |
| 348 | - ].forEach(toggleVisibility); | |
| 349 | - | |
| 350 | - // Add Intent Form Submission | |
| 351 | - $('#mxchat-add-intent-form').on('submit', function(event) { | |
| 352 | - $('#mxchat-intent-loading').show(); | |
| 353 | - $('#mxchat-intent-loading-text').show(); | |
| 354 | - $(this).find('button[type="submit"]').hide(); | |
| 355 | - }); | |
| 356 | - | |
| 357 | - // Inline Edit Functionality | |
| 358 | - $('.edit-button').on('click', function() { | |
| 359 | - var row = $(this).closest('tr'); | |
| 360 | - row.find('.content-view, .url-view').hide(); | |
| 361 | - row.find('.content-edit, .url-edit').show(); | |
| 362 | - row.find('.edit-button').hide(); | |
| 363 | - row.find('.save-button').show(); | |
| 364 | - }); | |
| 365 | - | |
| 366 | - // Save button handler | |
| 367 | - $('.save-button').on('click', function() { | |
| 368 | - var button = $(this); | |
| 369 | - var row = button.closest('tr'); | |
| 370 | - var id = button.data('id'); | |
| 371 | - var newContent = row.find('.content-edit').val(); | |
| 372 | - var newUrl = row.find('.url-edit').val(); | |
| 373 | - | |
| 374 | - button.prop('disabled', true); | |
| 375 | - button.text('Saving...'); | |
| 376 | - | |
| 377 | - $.ajax({ | |
| 378 | - url: mxchatAdmin.ajax_url, | |
| 379 | - type: 'POST', | |
| 380 | - data: { | |
| 381 | - action: 'mxchat_save_inline_prompt', | |
| 382 | - id: id, | |
| 383 | - article_content: newContent, | |
| 384 | - article_url: newUrl, | |
| 385 | - _ajax_nonce: mxchatAdmin.inline_edit_nonce | |
| 386 | - }, | |
| 387 | - success: function(response) { | |
| 388 | - button.prop('disabled', false); | |
| 389 | - button.text('Save'); | |
| 390 | - | |
| 391 | - if (response.success) { | |
| 392 | - row.find('.content-view').html(newContent.replace(/\n/g, "<br>")); | |
| 393 | - if (newUrl) { | |
| 394 | - row.find('.url-view').html('<a href="' + newUrl + '" target="_blank">' + newUrl + '</a>'); | |
| 395 | - } else { | |
| 396 | - row.find('.url-view').html('N/A'); | |
| 397 | - } | |
| 398 | - | |
| 399 | - row.find('.content-edit, .url-edit').hide(); | |
| 400 | - row.find('.content-view, .url-view').show(); | |
| 401 | - row.find('.save-button').hide(); | |
| 402 | - row.find('.edit-button').show(); | |
| 403 | - } else { | |
| 404 | - alert('Error saving content: ' + (response.data?.message || 'Unknown error')); | |
| 405 | - } | |
| 406 | - }, | |
| 407 | - error: function() { | |
| 408 | - button.prop('disabled', false); | |
| 409 | - button.text('Save'); | |
| 410 | - alert('An error occurred while saving.'); | |
| 411 | - } | |
| 412 | - }); | |
| 413 | - }); | |
| 414 | - | |
| 415 | - // Activation handling | |
| 416 | - const form = $('#mxchat-activation-form'); | |
| 417 | - const spinner = $('#mxchat-activation-spinner'); | |
| 418 | - const submitButton = $('#activate_license_button'); | |
| 419 | - const licenseStatus = $('#mxchat-license-status'); | |
| 420 | - | |
| 421 | - if (form.length && licenseStatus.length && submitButton.length) { | |
| 422 | - function handleActivationResponse(response) { | |
| 423 | - spinner.hide(); | |
| 12 | + $.post(mxchatAdmin.ajax_url, formData, function(response) { | |
| 424 | 13 | if (response.success) { |
| 425 | - licenseStatus.text('Active'); | |
| 426 | - licenseStatus.removeClass('inactive').addClass('active'); | |
| 427 | - form.hide(); | |
| 14 | + $('#mxchat-license-status').text('Active'); | |
| 428 | 15 | } else { |
| 429 | - licenseStatus.text('Inactive'); | |
| 430 | - alert(response.data || 'Activation failed. Please check your input.'); | |
| 431 | - submitButton.prop('disabled', false); | |
| 16 | + $('#mxchat-license-status').text('Inactive'); | |
| 17 | + alert(response.data); | |
| 432 | 18 | } |
| 433 | - } | |
| 434 | - | |
| 435 | - form.on('submit', function(event) { | |
| 436 | - event.preventDefault(); | |
| 437 | - spinner.show(); | |
| 438 | - submitButton.prop('disabled', true); | |
| 439 | - | |
| 440 | - var formData = { | |
| 441 | - action: 'mxchat_activate_license', | |
| 442 | - mxchat_pro_email: $('#mxchat_pro_email').val(), | |
| 443 | - mxchat_activation_key: $('#mxchat_activation_key').val(), | |
| 444 | - security: mxchatAdmin.license_nonce | |
| 445 | - }; | |
| 446 | - | |
| 447 | - $.post(mxchatAdmin.ajax_url, formData, function(response) { | |
| 448 | - handleActivationResponse(response); | |
| 449 | - }).fail(function() { | |
| 450 | - alert('Server error. Please try again.'); | |
| 451 | - spinner.hide(); | |
| 452 | - submitButton.prop('disabled', false); | |
| 453 | - }); | |
| 454 | 19 | }); |
| 455 | - } | |
| 456 | - | |
| 457 | - // Questions handling | |
| 458 | - $('.mxchat-add-question').on('click', function () { | |
| 459 | - const container = $('#mxchat-additional-questions-container'); | |
| 460 | - const questionCount = container.find('.mxchat-question-row').length + 4; | |
| 461 | - const questionIndex = container.find('.mxchat-question-row').length; | |
| 462 | - | |
| 463 | - const newQuestion = ` | |
| 464 | - <div class="mxchat-question-row"> | |
| 465 | - <input type="text" | |
| 466 | - name="additional_popular_questions[]" | |
| 467 | - placeholder="Enter Additional Popular Question ${questionCount}" | |
| 468 | - class="regular-text mxchat-question-input" | |
| 469 | - data-question-index="${questionIndex}" /> | |
| 470 | - <button type="button" class="button mxchat-remove-question" | |
| 471 | - aria-label="Remove question">Remove</button> | |
| 472 | - </div> | |
| 473 | - `; | |
| 474 | - container.append(newQuestion); | |
| 475 | 20 | }); |
| 476 | 21 | |
| 477 | - $(document).on('click', '.mxchat-remove-question', function () { | |
| 478 | - $(this).closest('.mxchat-question-row').remove(); | |
| 479 | - saveQuestions(); | |
| 22 | + $('.nav-tab').on('click', function(e) { | |
| 23 | + e.preventDefault(); | |
| 24 | + $('.nav-tab').removeClass('nav-tab-active'); | |
| 25 | + $(this).addClass('nav-tab-active'); | |
| 26 | + $('.tab-content').removeClass('active').hide(); | |
| 27 | + var activeTab = $(this).attr('href'); | |
| 28 | + $(activeTab).addClass('active').show(); | |
| 480 | 29 | }); |
| 481 | - | |
| 482 | - $(document).on('change', '.mxchat-question-input', function() { | |
| 483 | - saveQuestions(); | |
| 484 | - }); | |
| 485 | - | |
| 486 | - function saveQuestions() { | |
| 487 | - const questions = []; | |
| 488 | - $('.mxchat-question-input').each(function() { | |
| 489 | - const value = $(this).val().trim(); | |
| 490 | - if (value) { | |
| 491 | - questions.push(value); | |
| 492 | - } | |
| 493 | - }); | |
| 494 | - | |
| 495 | - const feedbackContainer = $('<div class="feedback-container"></div>'); | |
| 496 | - const spinner = $('<div class="saving-spinner"></div>'); | |
| 497 | - const successIcon = $('<div class="success-icon">✔</div>'); | |
| 498 | - | |
| 499 | - // Append feedback after the add button | |
| 500 | - $('.mxchat-add-question').after(feedbackContainer); | |
| 501 | - feedbackContainer.append(spinner); | |
| 502 | - | |
| 503 | - // Save via AJAX | |
| 504 | - $.ajax({ | |
| 505 | - url: mxchatAdmin.ajax_url, | |
| 506 | - type: 'POST', | |
| 507 | - data: { | |
| 508 | - action: 'mxchat_save_setting', | |
| 509 | - name: 'additional_popular_questions', | |
| 510 | - value: JSON.stringify(questions), | |
| 511 | - _ajax_nonce: mxchatAdmin.setting_nonce | |
| 512 | - }, | |
| 513 | - success: function(response) { | |
| 514 | - if (response.success) { | |
| 515 | - spinner.fadeOut(200, function() { | |
| 516 | - feedbackContainer.append(successIcon); | |
| 517 | - successIcon.fadeIn(200).delay(1000).fadeOut(200, function() { | |
| 518 | - feedbackContainer.remove(); | |
| 519 | - }); | |
| 520 | - }); | |
| 521 | - } else { | |
| 522 | - alert('Error saving questions: ' + (response.data?.message || 'Unknown error')); | |
| 523 | - feedbackContainer.remove(); | |
| 524 | - } | |
| 525 | - }, | |
| 526 | - error: function() { | |
| 527 | - alert('An error occurred while saving questions.'); | |
| 528 | - feedbackContainer.remove(); | |
| 529 | - } | |
| 530 | - }); | |
| 531 | - } | |
| 532 | - | |
| 533 | - // Live agent status handler | |
| 534 | - const statusToggle = document.getElementById('live_agent_status'); | |
| 535 | - const statusText = statusToggle?.parentElement.nextElementSibling?.querySelector('.status-text'); | |
| 536 | - if (statusToggle && statusText) { | |
| 537 | - statusToggle.addEventListener('change', function() { | |
| 538 | - // Update display text | |
| 539 | - statusText.textContent = this.checked ? 'Online' : 'Offline'; | |
| 540 | - | |
| 541 | - // Send the correct on/off value to the server | |
| 542 | - if (window.mxchatSaveSetting) { | |
| 543 | - window.mxchatSaveSetting('live_agent_status', this.checked ? 'on' : 'off'); | |
| 544 | - } | |
| 545 | - }); | |
| 546 | - } | |
| 547 | - | |
| 548 | - // Function to adjust the textarea height to content | |
| 549 | - function adjustTextareaHeight() { | |
| 550 | - this.style.height = 'auto'; // Reset to auto to calculate scrollHeight | |
| 551 | - this.style.height = this.scrollHeight + 'px'; // Expand to content height | |
| 552 | - } | |
| 553 | 30 | |
| 554 | - // Function to reset the textarea height to initial | |
| 555 | - function resetTextareaHeight() { | |
| 556 | - this.style.height = ''; // Remove inline height, reverting to CSS default | |
| 557 | - } | |
| 31 | + // Activate the first tab by default | |
| 32 | + $('.nav-tab-active').trigger('click'); | |
| 558 | 33 | |
| 559 | - // Target the specific textarea by ID | |
| 560 | - var $textarea = $('#system_prompt_instructions'); | |
| 561 | - | |
| 562 | - // Bind events | |
| 563 | - $textarea.on('focus input', adjustTextareaHeight) // Expand on focus and input | |
| 564 | - .on('blur', resetTextareaHeight); // Reset on blur | |
| 565 | - | |
| 566 | - | |
| 567 | 34 | }); |
| 568 | - | |
| 569 | - | |
| 570 | - | |