PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 1.6.4
MxChat – AI Chatbot & Content Generation for WordPress v1.6.4
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.4, at js/mxchat-admin.js

415 lines 15.1 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 toggleVisibility('#toggleDeepSeekApiKeyVisibility');
187
188
189 // --- Add Intent Form Submission ---
190
191 $('#mxchat-add-intent-form').on('submit', function(event) {
192 $('#mxchat-intent-loading').show();
193 $('#mxchat-intent-loading-text').show();
194 $(this).find('button[type="submit"]').hide(); // Hide the submit button to prevent multiple clicks
195 });
196
197 // --- Inline Edit Functionality ---
198
199 $('.edit-button').on('click', function() {
200 var row = $(this).closest('tr');
201 row.find('.content-view, .url-view').hide();
202 row.find('.content-edit, .url-edit').show();
203 row.find('.edit-button').hide();
204 row.find('.save-button').show();
205 });
206
207 $('.save-button').on('click', function() {
208 var button = $(this);
209 var row = button.closest('tr');
210 var id = button.data('id');
211 var newContent = row.find('.content-edit').val();
212 var newUrl = row.find('.url-edit').val();
213
214 // Add loading state
215 button.prop('disabled', true);
216 button.text('Saving...');
217
218 $.ajax({
219 url: mxchatAdmin.ajax_url,
220 type: 'POST',
221 data: {
222 action: 'mxchat_save_inline_prompt',
223 id: id,
224 article_content: newContent,
225 article_url: newUrl,
226 _ajax_nonce: mxchatAdmin.inline_edit_nonce
227 },
228 success: function(response) {
229 button.prop('disabled', false);
230 button.text('Save');
231
232 if (response.success) {
233 // Update the view
234 row.find('.content-view').html(newContent.replace(/\n/g, "<br>"));
235 if (newUrl) {
236 row.find('.url-view').html('<a href="' + newUrl + '" target="_blank">' + newUrl + '</a>');
237 } else {
238 row.find('.url-view').html('N/A');
239 }
240
241 // Hide edit fields, show view fields
242 row.find('.content-edit, .url-edit').hide();
243 row.find('.content-view, .url-view').show();
244 row.find('.save-button').hide();
245 row.find('.edit-button').show();
246 } else {
247 alert('Error saving content: ' + (response.data?.message || 'Unknown error'));
248 }
249 },
250 error: function() {
251 button.prop('disabled', false);
252 button.text('Save');
253 alert('An error occurred while saving.');
254 }
255 });
256 });
257
258 // --- Activation Script ---
259
260 // Select activation-related elements
261 var form = $('#mxchat-activation-form');
262 var spinner = $('#mxchat-activation-spinner');
263 var submitButton = $('#activate_license_button');
264 var licenseStatus = $('#mxchat-license-status');
265
266 // Ensure essential elements exist before running activation-specific code
267 if (form.length && licenseStatus.length && submitButton.length) {
268 //console.log('Activation elements detected, running activation-specific code.');
269
270 // Function to handle the response from the activation AJAX request
271 function handleActivationResponse(response) {
272 spinner.hide(); // Hide the spinner
273
274 if (response.success) {
275 // Update UI on successful activation
276 licenseStatus.text('Active');
277 licenseStatus.removeClass('inactive').addClass('active');
278 form.hide(); // Hide the activation form after successful activation
279 } else {
280 licenseStatus.text('Inactive');
281 alert(response.data || 'Activation failed. Please check your input.');
282 submitButton.prop('disabled', false); // Re-enable button on failure
283 }
284 }
285
286 // Event listener for form submission to activate the license
287 form.on('submit', function(event) {
288 event.preventDefault();
289
290 // Show spinner and disable the submit button
291 spinner.show();
292 submitButton.prop('disabled', true);
293
294 // Gather form data
295 var formData = {
296 action: 'mxchat_activate_license',
297 mxchat_pro_email: $('#mxchat_pro_email').val(),
298 mxchat_activation_key: $('#mxchat_activation_key').val(),
299 security: mxchatAdmin.license_nonce // FIXED: Using correct nonce
300 };
301
302 // Send the AJAX request using jQuery
303 $.post(mxchatAdmin.ajax_url, formData, function(response) {
304 handleActivationResponse(response);
305 }).fail(function() {
306 alert('Server error. Please try again.');
307 spinner.hide();
308 submitButton.prop('disabled', false);
309 });
310 });
311 } else {
312 //console.log('Activation elements not found; skipping activation-specific code.');
313 }
314
315
316
317
318 // Handle adding new questions
319 $('.mxchat-add-question').on('click', function () {
320 const container = $('#mxchat-additional-questions-container');
321 const questionCount = container.find('.mxchat-question-row').length + 4;
322 const questionIndex = container.find('.mxchat-question-row').length;
323
324 const newQuestion = `
325 <div class="mxchat-question-row">
326 <input type="text"
327 name="additional_popular_questions[]"
328 placeholder="Enter Additional Popular Question ${questionCount}"
329 class="regular-text mxchat-question-input"
330 data-question-index="${questionIndex}" />
331 <button type="button" class="button mxchat-remove-question"
332 aria-label="Remove question">Remove</button>
333 </div>
334 `;
335 container.append(newQuestion);
336 });
337
338 // Handle removing questions
339 $(document).on('click', '.mxchat-remove-question', function () {
340 const $row = $(this).closest('.mxchat-question-row');
341 $row.remove();
342
343 // Save the updated questions array after removal
344 saveQuestions();
345 });
346
347 // Handle question input changes
348 $(document).on('change', '.mxchat-question-input', function() {
349 saveQuestions();
350 });
351
352 // Function to save all questions
353 function saveQuestions() {
354 const questions = [];
355 $('.mxchat-question-input').each(function() {
356 const value = $(this).val().trim();
357 if (value) {
358 questions.push(value);
359 }
360 });
361
362 // Create feedback container
363 const feedbackContainer = $('<div class="feedback-container"></div>');
364 const spinner = $('<div class="saving-spinner"></div>');
365 const successIcon = $('<div class="success-icon">✔</div>');
366
367 // Append feedback after the add button
368 $('.mxchat-add-question').after(feedbackContainer);
369 feedbackContainer.append(spinner);
370
371 // Save via AJAX
372 $.ajax({
373 url: mxchatAdmin.ajax_url,
374 type: 'POST',
375 data: {
376 action: 'mxchat_save_setting',
377 name: 'additional_popular_questions',
378 value: JSON.stringify(questions),
379 _ajax_nonce: mxchatAdmin.setting_nonce
380 },
381 success: function(response) {
382 if (response.success) {
383 spinner.fadeOut(200, function() {
384 feedbackContainer.append(successIcon);
385 successIcon.fadeIn(200).delay(1000).fadeOut(200, function() {
386 feedbackContainer.remove();
387 });
388 });
389 } else {
390 alert('Error saving questions: ' + response.data.message);
391 feedbackContainer.remove();
392 }
393 },
394 error: function() {
395 alert('An error occurred while saving questions.');
396 feedbackContainer.remove();
397 }
398 });
399 }
400
401 const statusToggle = document.getElementById('live_agent_status');
402 const statusText = statusToggle?.parentElement.nextElementSibling?.querySelector('.status-text');
403 if (statusToggle && statusText) {
404 statusToggle.addEventListener('change', function() {
405 // Update display text
406 statusText.textContent = this.checked ? 'Online' : 'Offline';
407
408 // Send the correct on/off value to the server
409 if (window.mxchatSaveSetting) {
410 window.mxchatSaveSetting('live_agent_status', this.checked ? 'on' : 'off');
411 }
412 });
413 }
414 });
415