PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 1.6.1
MxChat – AI Chatbot & Content Generation for WordPress v1.6.1
3.2.21 3.2.20 3.2.19 3.2.18 3.2.17 3.2.16 3.2.15 3.2.14 3.2.12 3.2.13 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 3.2.6 3.2.5 3.2.4 3.2.3 3.2.2 3.2.1 2.0.3 2.0.4 2.0.5 2.0.6 All 152 releases
mxchat-basic / js / mxchat-admin.js

mxchat-admin.js in MxChat – AI Chatbot & Content Generation for WordPress 1.6.1, at js/mxchat-admin.js

398 lines 14.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 function mxchatOpenEditModal(intentId, phrases) {
2 const modal = document.getElementById('mxchat-edit-modal');
3 if (!modal) return;
4 const intentIdField = document.getElementById('edit_intent_id');
5 const phrasesField = document.getElementById('edit_phrases');
6
7 intentIdField.value = intentId;
8 phrasesField.value = phrases;
9 modal.style.display = 'block';
10 }
11
12
13
14
15 jQuery(document).ready(function($) {
16 //console.log('Script loaded'); // Confirm script is loading
17
18
19 // --- AJAX Auto-Save ---
20 // Only target elements within the autosave sections
21 const $autosaveSections = $('.mxchat-autosave-section');
22
23 if ($autosaveSections.length) {
24 // Handle real-time range slider value updates
25 $autosaveSections.find('input[type="range"]').on('input', function() {
26 const value = $(this).val();
27 $('#threshold_value').text(value);
28 });
29
30 // Handle all input changes (including range slider)
31 $autosaveSections.find('input, textarea, select').on('change', function() {
32 const $field = $(this);
33 const name = $field.attr('name');
34 let value;
35
36 // Handle different input types
37 if ($field.attr('type') === 'checkbox') {
38 value = $field.is(':checked') ? 'on' : 'off';
39 } else {
40 value = $field.val();
41 }
42
43 // Create feedback container
44 const feedbackContainer = $('<div class="feedback-container"></div>');
45 const spinner = $('<div class="saving-spinner"></div>');
46 const successIcon = $('<div class="success-icon">✔</div>');
47
48 // Position feedback container based on input type
49 if ($field.closest('.toggle-switch').length) {
50 $field.closest('.toggle-switch').after(feedbackContainer);
51 } else if ($field.closest('.slider-container').length) {
52 $field.closest('.slider-container').after(feedbackContainer);
53 } else {
54 $field.after(feedbackContainer);
55 }
56 feedbackContainer.append(spinner);
57
58 // AJAX save request
59 $.ajax({
60 url: mxchatAdmin.ajax_url,
61 type: 'POST',
62 data: {
63 action: 'mxchat_save_setting',
64 name: name,
65 value: value,
66 _ajax_nonce: mxchatAdmin.setting_nonce
67 },
68 success: function(response) {
69 if (response.success) {
70 spinner.fadeOut(200, function() {
71 feedbackContainer.append(successIcon);
72 successIcon.fadeIn(200).delay(1000).fadeOut(200, function() {
73 feedbackContainer.remove();
74 });
75 });
76 } else {
77 alert('Error saving: ' + response.data.message);
78 if ($field.attr('type') === 'checkbox') {
79 $field.prop('checked', !$field.is(':checked'));
80 }
81 feedbackContainer.remove();
82 }
83 },
84 error: function() {
85 alert('An error occurred while saving.');
86 if ($field.attr('type') === 'checkbox') {
87 $field.prop('checked', !$field.is(':checked'));
88 }
89 feedbackContainer.remove();
90 }
91 });
92 });
93
94 // Initialize color pickers with debouncing
95 $autosaveSections.find('.my-color-field').wpColorPicker({
96 change: _.debounce(function(event, ui) {
97 const $field = $(this);
98 const name = $field.attr('name');
99 const value = $field.val();
100
101 // Create feedback container
102 const feedbackContainer = $('<div class="feedback-container"></div>');
103 const spinner = $('<div class="saving-spinner"></div>');
104 const successIcon = $('<div class="success-icon">✔</div>');
105
106 // Position feedback container
107 $field.closest('.wp-picker-container').after(feedbackContainer);
108 feedbackContainer.append(spinner);
109
110 // AJAX save request
111 $.ajax({
112 url: mxchatAdmin.ajax_url,
113 type: 'POST',
114 data: {
115 action: 'mxchat_save_setting',
116 name: name,
117 value: value,
118 _ajax_nonce: mxchatAdmin.setting_nonce
119 },
120 success: function(response) {
121 if (response.success) {
122 spinner.fadeOut(200, function() {
123 feedbackContainer.append(successIcon);
124 successIcon.fadeIn(200).delay(1000).fadeOut(200, function() {
125 feedbackContainer.remove();
126 });
127 });
128 } else {
129 alert('Error saving: ' + response.data.message);
130 feedbackContainer.remove();
131 }
132 },
133 error: function() {
134 alert('An error occurred while saving.');
135 feedbackContainer.remove();
136 }
137 });
138 }, 500)
139 });
140 }
141
142 // --- Tab Navigation and Toggles ---
143
144 $('.mxchat-nav-tab').on('click', function(e) {
145 e.preventDefault();
146 $('.mxchat-nav-tab').removeClass('mxchat-nav-tab-active');
147 $(this).addClass('mxchat-nav-tab-active');
148 $('.mxchat-tab-content').removeClass('active').hide();
149 var activeTab = $(this).attr('href');
150 $(activeTab).addClass('active').show();
151 });
152
153 // Activate the first tab by default
154 $('.mxchat-nav-tab-active').trigger('click');
155
156
157 // Attach click event to dynamically call the function
158 $(document).on('click', '.mxchat-edit-button', function() {
159 const intentId = $(this).data('intent-id');
160 const phrases = $(this).data('phrases');
161 mxchatOpenEditModal(intentId, phrases);
162 });
163
164 // Toggle visibility of various API keys
165 function toggleVisibility(selector) {
166 $(selector).on('click', function() {
167 var inputField = $(this).prev('input');
168 if (inputField.attr('type') === 'password') {
169 inputField.attr('type', 'text');
170 $(this).text('Hide');
171 } else {
172 inputField.attr('type', 'password');
173 $(this).text('Show');
174 }
175 });
176 }
177 toggleVisibility('#toggleApiKeyVisibility');
178 toggleVisibility('#toggleWooCommerceSecretVisibility');
179 toggleVisibility('#toggleLoopsApiKeyVisibility');
180 toggleVisibility('#toggleXaiApiKeyVisibility');
181 toggleVisibility('#toggleClaudeApiKeyVisibility');
182 toggleVisibility('#toggleBraveApiKeyVisibility');
183 toggleVisibility('#toggleWebhookUrlVisibility');
184 toggleVisibility('#toggleSecretKeyVisibility');
185 toggleVisibility('#toggleBotTokenVisibility');
186
187 // --- Add Intent Form Submission ---
188
189 $('#mxchat-add-intent-form').on('submit', function(event) {
190 $('#mxchat-intent-loading').show();
191 $('#mxchat-intent-loading-text').show();
192 $(this).find('button[type="submit"]').hide(); // Hide the submit button to prevent multiple clicks
193 });
194
195 // --- Inline Edit Functionality ---
196
197 $('.edit-button').on('click', function() {
198 var row = $(this).closest('tr');
199 row.find('.content-view, .url-view').hide();
200 row.find('.content-edit, .url-edit').show();
201 row.find('.edit-button').hide();
202 row.find('.save-button').show();
203 });
204
205 $('.save-button').on('click', function() {
206 var button = $(this);
207 var row = button.closest('tr');
208 var id = button.data('id');
209 var newContent = row.find('.content-edit').val();
210 var newUrl = row.find('.url-edit').val();
211
212 // Send an AJAX request to save the changes
213 $.ajax({
214 url: ajaxurl, // ajaxurl is automatically available in WP admin
215 type: 'POST',
216 data: {
217 action: 'mxchat_save_inline_prompt',
218 id: id,
219 article_content: newContent,
220 article_url: newUrl,
221 _ajax_nonce: mxchatInlineEdit.nonce // Use localized nonce
222 },
223 success: function(response) {
224 if (response.success) {
225 row.find('.content-view').html(newContent.replace(/\n/g, "<br>"));
226 row.find('.url-view a').attr('href', newUrl).text(newUrl);
227 row.find('.content-edit, .url-edit').hide();
228 row.find('.content-view, .url-view').show();
229 row.find('.save-button').hide();
230 row.find('.edit-button').show();
231 } else {
232 alert('Error saving content.');
233 }
234 },
235 error: function() {
236 alert('An error occurred.');
237 }
238 });
239 });
240
241 // --- Activation Script ---
242
243 // Select activation-related elements
244 var form = $('#mxchat-activation-form');
245 var spinner = $('#mxchat-activation-spinner');
246 var submitButton = $('#activate_license_button');
247 var licenseStatus = $('#mxchat-license-status');
248
249 // Ensure essential elements exist before running activation-specific code
250 if (form.length && licenseStatus.length && submitButton.length) {
251 //console.log('Activation elements detected, running activation-specific code.');
252
253 // Function to handle the response from the activation AJAX request
254 function handleActivationResponse(response) {
255 spinner.hide(); // Hide the spinner
256
257 if (response.success) {
258 // Update UI on successful activation
259 licenseStatus.text('Active');
260 licenseStatus.removeClass('inactive').addClass('active');
261 form.hide(); // Hide the activation form after successful activation
262 } else {
263 licenseStatus.text('Inactive');
264 alert(response.data || 'Activation failed. Please check your input.');
265 submitButton.prop('disabled', false); // Re-enable button on failure
266 }
267 }
268
269 // Event listener for form submission to activate the license
270 form.on('submit', function(event) {
271 event.preventDefault();
272
273 // Show spinner and disable the submit button
274 spinner.show();
275 submitButton.prop('disabled', true);
276
277 // Gather form data
278 var formData = {
279 action: 'mxchat_activate_license',
280 mxchat_pro_email: $('#mxchat_pro_email').val(),
281 mxchat_activation_key: $('#mxchat_activation_key').val(),
282 security: mxchatAdmin.license_nonce // FIXED: Using correct nonce
283 };
284
285 // Send the AJAX request using jQuery
286 $.post(mxchatAdmin.ajax_url, formData, function(response) {
287 handleActivationResponse(response);
288 }).fail(function() {
289 alert('Server error. Please try again.');
290 spinner.hide();
291 submitButton.prop('disabled', false);
292 });
293 });
294 } else {
295 //console.log('Activation elements not found; skipping activation-specific code.');
296 }
297
298
299
300
301 // Handle adding new questions
302 $('.mxchat-add-question').on('click', function () {
303 const container = $('#mxchat-additional-questions-container');
304 const questionCount = container.find('.mxchat-question-row').length + 4;
305 const questionIndex = container.find('.mxchat-question-row').length;
306
307 const newQuestion = `
308 <div class="mxchat-question-row">
309 <input type="text"
310 name="additional_popular_questions[]"
311 placeholder="Enter Additional Popular Question ${questionCount}"
312 class="regular-text mxchat-question-input"
313 data-question-index="${questionIndex}" />
314 <button type="button" class="button mxchat-remove-question"
315 aria-label="Remove question">Remove</button>
316 </div>
317 `;
318 container.append(newQuestion);
319 });
320
321 // Handle removing questions
322 $(document).on('click', '.mxchat-remove-question', function () {
323 const $row = $(this).closest('.mxchat-question-row');
324 $row.remove();
325
326 // Save the updated questions array after removal
327 saveQuestions();
328 });
329
330 // Handle question input changes
331 $(document).on('change', '.mxchat-question-input', function() {
332 saveQuestions();
333 });
334
335 // Function to save all questions
336 function saveQuestions() {
337 const questions = [];
338 $('.mxchat-question-input').each(function() {
339 const value = $(this).val().trim();
340 if (value) {
341 questions.push(value);
342 }
343 });
344
345 // Create feedback container
346 const feedbackContainer = $('<div class="feedback-container"></div>');
347 const spinner = $('<div class="saving-spinner"></div>');
348 const successIcon = $('<div class="success-icon">✔</div>');
349
350 // Append feedback after the add button
351 $('.mxchat-add-question').after(feedbackContainer);
352 feedbackContainer.append(spinner);
353
354 // Save via AJAX
355 $.ajax({
356 url: mxchatAdmin.ajax_url,
357 type: 'POST',
358 data: {
359 action: 'mxchat_save_setting',
360 name: 'additional_popular_questions',
361 value: JSON.stringify(questions),
362 _ajax_nonce: mxchatAdmin.setting_nonce
363 },
364 success: function(response) {
365 if (response.success) {
366 spinner.fadeOut(200, function() {
367 feedbackContainer.append(successIcon);
368 successIcon.fadeIn(200).delay(1000).fadeOut(200, function() {
369 feedbackContainer.remove();
370 });
371 });
372 } else {
373 alert('Error saving questions: ' + response.data.message);
374 feedbackContainer.remove();
375 }
376 },
377 error: function() {
378 alert('An error occurred while saving questions.');
379 feedbackContainer.remove();
380 }
381 });
382 }
383
384 const statusToggle = document.getElementById('live_agent_status');
385 const statusText = statusToggle?.parentElement.nextElementSibling?.querySelector('.status-text');
386 if (statusToggle && statusText) {
387 statusToggle.addEventListener('change', function() {
388 // Update display text
389 statusText.textContent = this.checked ? 'Online' : 'Offline';
390
391 // Send the correct on/off value to the server
392 if (window.mxchatSaveSetting) {
393 window.mxchatSaveSetting('live_agent_status', this.checked ? 'on' : 'off');
394 }
395 });
396 }
397 });
398