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

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