PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 3.0.6
MxChat – AI Chatbot & Content Generation for WordPress v3.0.6
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 / includes / admin-settings-page.php

admin-settings-page.php in MxChat – AI Chatbot & Content Generation for WordPress 3.0.6, at includes/admin-settings-page.php

1,166 lines 74.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MxChat Admin Settings Page - Redesigned with Sidebar Navigation
4 *
5 * @package MxChat
6 * @since 2.7.0
7 */
8
9 if (!defined('ABSPATH')) {
10 exit;
11 }
12
13 /**
14 * Render the new sidebar-based admin settings page
15 */
16 function mxchat_render_settings_page($admin_instance) {
17 $is_activated = $admin_instance->is_activated();
18 $options = get_option('mxchat_options', array());
19 $plugin_url = plugin_dir_url(dirname(__FILE__));
20 ?>
21 <div class="mxch-admin-wrapper">
22 <!-- Mobile Header -->
23 <header class="mxch-mobile-header">
24 <a href="#" class="mxch-mobile-logo">
25 <div class="mxch-mobile-logo-icon">
26 <img src="<?php echo esc_url($plugin_url . 'images/icon-128x128.png'); ?>" alt="MxChat">
27 </div>
28 <span class="mxch-mobile-logo-text">MxChat</span>
29 </a>
30 <button type="button" class="mxch-mobile-menu-btn" aria-label="<?php esc_attr_e('Open menu', 'mxchat'); ?>">
31 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>
32 </button>
33 </header>
34
35 <!-- Mobile Menu Overlay -->
36 <div class="mxch-mobile-overlay"></div>
37
38 <!-- Mobile Menu Modal -->
39 <div class="mxch-mobile-menu">
40 <div class="mxch-mobile-menu-header">
41 <span class="mxch-mobile-menu-title"><?php esc_html_e('Settings', 'mxchat'); ?></span>
42 <button type="button" class="mxch-mobile-menu-close" aria-label="<?php esc_attr_e('Close menu', 'mxchat'); ?>">
43 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
44 </button>
45 </div>
46 <nav class="mxch-mobile-menu-nav">
47 <!-- Configuration Section -->
48 <div class="mxch-mobile-nav-section">
49 <div class="mxch-mobile-nav-section-title"><?php esc_html_e('Configuration', 'mxchat'); ?></div>
50 <button class="mxch-mobile-nav-link" data-parent="chatbot">
51 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/></svg>
52 <span><?php esc_html_e('Chatbot', 'mxchat'); ?></span>
53 <svg class="mxch-mobile-nav-arrow" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>
54 </button>
55 <div class="mxch-mobile-nav-sub" data-parent="chatbot">
56 <button class="mxch-mobile-nav-sub-link active" data-target="chatbot-ai-models"><?php esc_html_e('AI Models', 'mxchat'); ?></button>
57 <button class="mxch-mobile-nav-sub-link" data-target="chatbot-behavior"><?php esc_html_e('Behavior', 'mxchat'); ?></button>
58 <button class="mxch-mobile-nav-sub-link" data-target="chatbot-display"><?php esc_html_e('Display', 'mxchat'); ?></button>
59 <button class="mxch-mobile-nav-sub-link" data-target="chatbot-lead-capture"><?php esc_html_e('Lead Capture', 'mxchat'); ?></button>
60 <button class="mxch-mobile-nav-sub-link" data-target="chatbot-quick-questions"><?php esc_html_e('Quick Questions', 'mxchat'); ?></button>
61 <button class="mxch-mobile-nav-sub-link" data-target="chatbot-rate-limits"><?php esc_html_e('Rate Limits', 'mxchat'); ?></button>
62 </div>
63 <button class="mxch-mobile-nav-link" data-target="api-keys">
64 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21 2-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0 3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg>
65 <span><?php esc_html_e('API Keys', 'mxchat'); ?></span>
66 </button>
67 </div>
68 <!-- Integrations Section -->
69 <div class="mxch-mobile-nav-section">
70 <div class="mxch-mobile-nav-section-title"><?php esc_html_e('Integrations', 'mxchat'); ?></div>
71 <button class="mxch-mobile-nav-link" data-parent="integrations">
72 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg>
73 <span><?php esc_html_e('Integrations', 'mxchat'); ?></span>
74 <svg class="mxch-mobile-nav-arrow" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>
75 </button>
76 <div class="mxch-mobile-nav-sub" data-parent="integrations">
77 <button class="mxch-mobile-nav-sub-link" data-target="integrations-toolbar"><?php esc_html_e('Toolbar', 'mxchat'); ?></button>
78 <button class="mxch-mobile-nav-sub-link" data-target="integrations-loops"><?php esc_html_e('Loops', 'mxchat'); ?></button>
79 <button class="mxch-mobile-nav-sub-link" data-target="integrations-brave"><?php esc_html_e('Brave Search', 'mxchat'); ?></button>
80 <button class="mxch-mobile-nav-sub-link" data-target="integrations-slack"><?php esc_html_e('Slack', 'mxchat'); ?></button>
81 <button class="mxch-mobile-nav-sub-link" data-target="integrations-telegram"><?php esc_html_e('Telegram', 'mxchat'); ?></button>
82 </div>
83 </div>
84 <!-- Resources Section -->
85 <div class="mxch-mobile-nav-section">
86 <div class="mxch-mobile-nav-section-title"><?php esc_html_e('Resources', 'mxchat'); ?></div>
87 <button class="mxch-mobile-nav-link" data-target="tutorials">
88 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2" ry="2"/></svg>
89 <span><?php esc_html_e('Tutorials', 'mxchat'); ?></span>
90 </button>
91 </div>
92 <?php if (!$is_activated): ?>
93 <div class="mxch-mobile-menu-footer">
94 <a href="https://mxchat.ai/" target="_blank" class="mxch-mobile-upgrade-btn">
95 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9H4.5a2.5 2.5 0 0 1 0-5H6"/><path d="M18 9h1.5a2.5 2.5 0 0 0 0-5H18"/><path d="M4 22h16"/><path d="M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20.24 7 22"/><path d="M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22"/><path d="M18 2H6v7a6 6 0 0 0 12 0V2Z"/></svg>
96 <?php esc_html_e('Upgrade to Pro', 'mxchat'); ?>
97 </a>
98 </div>
99 <?php endif; ?>
100 </nav>
101 </div>
102
103 <!-- Sidebar Navigation -->
104 <aside class="mxch-sidebar">
105 <div class="mxch-sidebar-header">
106 <a href="#" class="mxch-sidebar-logo">
107 <div class="mxch-sidebar-logo-icon">
108 <img src="<?php echo esc_url($plugin_url . 'images/icon-128x128.png'); ?>" alt="MxChat">
109 </div>
110 <span class="mxch-sidebar-logo-text">MxChat</span>
111 <span class="mxch-sidebar-version">v<?php echo esc_html(MXCHAT_VERSION ?? '2.7.0'); ?></span>
112 </a>
113 </div>
114
115 <nav class="mxch-sidebar-nav">
116 <!-- Chatbot Section -->
117 <div class="mxch-nav-section">
118 <div class="mxch-nav-section-title"><?php esc_html_e('Configuration', 'mxchat'); ?></div>
119
120 <div class="mxch-nav-item expanded" data-section="chatbot">
121 <button class="mxch-nav-link active">
122 <span class="mxch-nav-link-icon">
123 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/></svg>
124 </span>
125 <span class="mxch-nav-link-text"><?php esc_html_e('Chatbot', 'mxchat'); ?></span>
126 <svg class="mxch-nav-link-arrow" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>
127 </button>
128 <div class="mxch-nav-sub">
129 <button class="mxch-nav-sub-link active" data-target="chatbot-ai-models"><?php esc_html_e('AI Models', 'mxchat'); ?></button>
130 <button class="mxch-nav-sub-link" data-target="chatbot-behavior"><?php esc_html_e('Behavior', 'mxchat'); ?></button>
131 <button class="mxch-nav-sub-link" data-target="chatbot-display"><?php esc_html_e('Display', 'mxchat'); ?></button>
132 <button class="mxch-nav-sub-link" data-target="chatbot-lead-capture"><?php esc_html_e('Lead Capture', 'mxchat'); ?></button>
133 <button class="mxch-nav-sub-link" data-target="chatbot-quick-questions"><?php esc_html_e('Quick Questions', 'mxchat'); ?></button>
134 <button class="mxch-nav-sub-link" data-target="chatbot-rate-limits"><?php esc_html_e('Rate Limits', 'mxchat'); ?></button>
135 </div>
136 </div>
137
138 <div class="mxch-nav-item" data-section="api-keys">
139 <button class="mxch-nav-link" data-target="api-keys">
140 <span class="mxch-nav-link-icon">
141 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21 2-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0 3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg>
142 </span>
143 <span class="mxch-nav-link-text"><?php esc_html_e('API Keys', 'mxchat'); ?></span>
144 </button>
145 </div>
146 </div>
147
148 <!-- Integrations Section -->
149 <div class="mxch-nav-section">
150 <div class="mxch-nav-section-title"><?php esc_html_e('Integrations', 'mxchat'); ?></div>
151
152 <div class="mxch-nav-item" data-section="integrations">
153 <button class="mxch-nav-link">
154 <span class="mxch-nav-link-icon">
155 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg>
156 </span>
157 <span class="mxch-nav-link-text"><?php esc_html_e('Integrations', 'mxchat'); ?></span>
158 <svg class="mxch-nav-link-arrow" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>
159 </button>
160 <div class="mxch-nav-sub">
161 <button class="mxch-nav-sub-link" data-target="integrations-toolbar"><?php esc_html_e('Toolbar', 'mxchat'); ?></button>
162 <button class="mxch-nav-sub-link" data-target="integrations-loops"><?php esc_html_e('Loops', 'mxchat'); ?></button>
163 <button class="mxch-nav-sub-link" data-target="integrations-brave"><?php esc_html_e('Brave Search', 'mxchat'); ?></button>
164 <button class="mxch-nav-sub-link" data-target="integrations-slack"><?php esc_html_e('Slack', 'mxchat'); ?></button>
165 <button class="mxch-nav-sub-link" data-target="integrations-telegram"><?php esc_html_e('Telegram', 'mxchat'); ?></button>
166 </div>
167 </div>
168 </div>
169
170 <!-- Resources Section -->
171 <div class="mxch-nav-section">
172 <div class="mxch-nav-section-title"><?php esc_html_e('Resources', 'mxchat'); ?></div>
173
174 <div class="mxch-nav-item" data-section="tutorials">
175 <button class="mxch-nav-link" data-target="tutorials">
176 <span class="mxch-nav-link-icon">
177 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2" ry="2"/></svg>
178 </span>
179 <span class="mxch-nav-link-text"><?php esc_html_e('Tutorials', 'mxchat'); ?></span>
180 </button>
181 </div>
182 </div>
183 </nav>
184
185 <?php if (!$is_activated): ?>
186 <div class="mxch-sidebar-footer">
187 <a href="https://mxchat.ai/" target="_blank" class="mxch-sidebar-upgrade-v2">
188 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
189 <?php esc_html_e('Pro Upgrade', 'mxchat'); ?>
190 </a>
191 </div>
192 <?php endif; ?>
193 </aside>
194
195 <!-- Main Content Area -->
196 <main class="mxch-content">
197 <?php if (!$is_activated): ?>
198 <div class="mxch-pro-banner">
199 <div class="mxch-pro-banner-content">
200 <h3 class="mxch-pro-banner-title"><?php esc_html_e('MxChat Pro — Lifetime Access', 'mxchat'); ?></h3>
201 <p class="mxch-pro-banner-text"><?php esc_html_e('One-time purchase. Unlock 10+ premium add-ons: Admin AI Assistant, Forms Builder, Chatbot Themes, and more.', 'mxchat'); ?></p>
202 </div>
203 <a href="https://mxchat.ai/" target="_blank" class="mxch-pro-banner-btn"><span><?php esc_html_e('Learn More', 'mxchat'); ?></span></a>
204 </div>
205 <?php endif; ?>
206
207 <?php
208 // Show theme migration notice for Pro users
209 $admin_instance->show_theme_migration_banner();
210 ?>
211
212 <!-- ========================================
213 CHATBOT - AI MODELS
214 ======================================== -->
215 <div id="chatbot-ai-models" class="mxch-section active">
216 <div class="mxch-content-header">
217 <h1 class="mxch-content-title"><?php esc_html_e('AI Models', 'mxchat'); ?></h1>
218 <p class="mxch-content-subtitle"><?php esc_html_e('Configure the AI models your chatbot will use for conversations and embeddings.', 'mxchat'); ?></p>
219 </div>
220
221 <div class="mxch-card">
222 <div class="mxch-card-body mxchat-autosave-section">
223 <?php
224 // Chat Model
225 mxchat_render_field_wrapper('model', __('Chat Model', 'mxchat'), function() use ($admin_instance) {
226 $admin_instance->mxchat_model_callback();
227 }, __('Select the AI model your chatbot will use for conversations.', 'mxchat'));
228
229 // Embedding Model
230 mxchat_render_field_wrapper('embedding_model', __('Embedding Model', 'mxchat'), function() use ($admin_instance) {
231 $admin_instance->embedding_model_callback();
232 }, __('Vector embedding model for knowledge base matching. Changing models requires reconfiguring knowledge data.', 'mxchat'));
233
234 // Enable Streaming
235 mxchat_render_field_wrapper('enable_streaming', __('Enable Streaming', 'mxchat'), function() use ($admin_instance) {
236 $admin_instance->enable_streaming_toggle_callback();
237 }, __('Enable real-time streaming responses for supported models (OpenAI, Claude, DeepSeek, Grok).', 'mxchat'));
238
239 // Enable Web Search (OpenAI only)
240 mxchat_render_field_wrapper('enable_web_search', __('Enable Web Search', 'mxchat'), function() use ($admin_instance) {
241 $admin_instance->enable_web_search_toggle_callback();
242 }, __('Allow the chatbot to search the web for current information (OpenAI models only).', 'mxchat'));
243 ?>
244 </div>
245 </div>
246 </div>
247
248 <!-- ========================================
249 CHATBOT - BEHAVIOR
250 ======================================== -->
251 <div id="chatbot-behavior" class="mxch-section">
252 <div class="mxch-content-header">
253 <h1 class="mxch-content-title"><?php esc_html_e('Behavior', 'mxchat'); ?></h1>
254 <p class="mxch-content-subtitle"><?php esc_html_e('Control how your AI chatbot responds and processes queries.', 'mxchat'); ?></p>
255 </div>
256
257 <div class="mxch-card">
258 <div class="mxch-card-body mxchat-autosave-section">
259 <?php
260 // AI Instructions
261 mxchat_render_field_wrapper('system_prompt_instructions', __('AI Instructions (Behavior)', 'mxchat'), function() use ($admin_instance) {
262 $admin_instance->system_prompt_instructions_callback();
263 }, __('Provide system-level instructions to guide the AI\'s behavior and responses.', 'mxchat'));
264
265 // Similarity Threshold
266 mxchat_render_field_wrapper('similarity_threshold', __('Similarity Threshold', 'mxchat'), function() use ($admin_instance) {
267 $admin_instance->mxchat_similarity_threshold_callback();
268 }, __('Adjust threshold for content matching. Lower values = more matches, higher values = stricter matching.', 'mxchat'));
269
270 // RAG Sources Limit
271 mxchat_render_field_wrapper('rag_sources_limit', __('RAG Sources Limit', 'mxchat'), function() use ($admin_instance) {
272 $admin_instance->mxchat_rag_sources_limit_callback();
273 }, __('Number of knowledge base sources (pages/documents) to include in AI context. Higher values provide more context but use more tokens.', 'mxchat'));
274
275 // Contextual Awareness
276 mxchat_render_field_wrapper('contextual_awareness', __('Contextual Awareness', 'mxchat'), function() use ($admin_instance) {
277 $admin_instance->mxchat_contextual_awareness_callback();
278 }, __('Allow the chatbot to understand and reference the current page content for more relevant responses.', 'mxchat'));
279
280 // Citation Links
281 mxchat_render_field_wrapper('citation_links', __('Citation Links', 'mxchat'), function() use ($admin_instance) {
282 $admin_instance->mxchat_citation_links_toggle_callback();
283 }, __('Allow the AI to include citation links from your knowledge database in responses. If disabled, ensure your AI Behavior settings do not mention links or the AI may fabricate URLs.', 'mxchat'));
284
285 // Frontend Debugger
286 mxchat_render_field_wrapper('frontend_debugger', __('Frontend Debugger', 'mxchat'), function() use ($admin_instance) {
287 $admin_instance->mxchat_frontend_debugger_callback();
288 }, __('Show debug panel on frontend for admins. Displays similarity scores and query analysis.', 'mxchat'));
289 ?>
290 </div>
291 </div>
292 </div>
293
294 <!-- ========================================
295 CHATBOT - DISPLAY
296 ======================================== -->
297 <div id="chatbot-display" class="mxch-section">
298 <div class="mxch-content-header">
299 <h1 class="mxch-content-title"><?php esc_html_e('Display Settings', 'mxchat'); ?></h1>
300 <p class="mxch-content-subtitle"><?php esc_html_e('Customize how and where your chatbot appears on your website.', 'mxchat'); ?></p>
301 </div>
302
303 <div class="mxch-card">
304 <div class="mxch-card-header">
305 <h3 class="mxch-card-title">
306 <svg class="mxch-card-title-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="9" y1="21" x2="9" y2="9"/></svg>
307 <?php esc_html_e('Visibility', 'mxchat'); ?>
308 </h3>
309 </div>
310 <div class="mxch-card-body mxchat-autosave-section">
311 <?php
312 // Auto-Display
313 mxchat_render_field_wrapper('auto_display', __('Auto-Display Chatbot', 'mxchat'), function() use ($admin_instance) {
314 $admin_instance->mxchat_append_to_body_callback();
315 }, __('Show chatbot automatically on all pages. Disable to use shortcode [mxchat_chatbot] instead.', 'mxchat'));
316
317 // Open Links in New Tab
318 mxchat_render_field_wrapper('link_target', __('Open Links in New Tab', 'mxchat'), function() use ($admin_instance) {
319 $admin_instance->mxchat_link_target_toggle_callback();
320 }, __('Open links clicked in chat responses in a new browser tab.', 'mxchat'));
321
322 // Chat Persistence
323 mxchat_render_field_wrapper('chat_persistence', __('Chat Persistence', 'mxchat'), function() use ($admin_instance) {
324 $admin_instance->mxchat_chat_persistence_toggle_callback();
325 }, __('Keep chat history when users navigate or return within 24 hours.', 'mxchat'));
326 ?>
327 </div>
328 </div>
329
330 <div class="mxch-card">
331 <div class="mxch-card-header">
332 <h3 class="mxch-card-title">
333 <svg class="mxch-card-title-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
334 <?php esc_html_e('Text & Labels', 'mxchat'); ?>
335 </h3>
336 </div>
337 <div class="mxch-card-body mxchat-autosave-section">
338 <?php
339 // Top Bar Title
340 mxchat_render_field_wrapper('top_bar_title', __('Top Bar Title', 'mxchat'), function() use ($admin_instance) {
341 $admin_instance->mxchat_top_bar_title_callback();
342 }, __('Title text shown in the chatbot header.', 'mxchat'));
343
344 // AI Agent Text
345 mxchat_render_field_wrapper('ai_agent_text', __('AI Agent Text', 'mxchat'), function() use ($admin_instance) {
346 $admin_instance->mxchat_ai_agent_text_callback();
347 }, __('Text shown for AI agents in the status indicator.', 'mxchat'));
348
349 // Intro Message
350 mxchat_render_field_wrapper('intro_message', __('Introductory Message', 'mxchat'), function() use ($admin_instance) {
351 $admin_instance->mxchat_intro_message_callback();
352 }, __('First message shown when chat opens. HTML allowed.', 'mxchat'));
353
354 // Input Placeholder
355 mxchat_render_field_wrapper('input_copy', __('Input Placeholder', 'mxchat'), function() use ($admin_instance) {
356 $admin_instance->mxchat_input_copy_callback();
357 }, __('Placeholder text in the chat input field.', 'mxchat'));
358
359 // Chat Teaser
360 mxchat_render_field_wrapper('pre_chat_message', __('Chat Teaser Pop-up', 'mxchat'), function() use ($admin_instance) {
361 $admin_instance->mxchat_pre_chat_message_callback();
362 }, __('Message shown before users start chatting.', 'mxchat'));
363 ?>
364 </div>
365 </div>
366 </div>
367
368 <!-- ========================================
369 CHATBOT - LEAD CAPTURE
370 ======================================== -->
371 <div id="chatbot-lead-capture" class="mxch-section">
372 <div class="mxch-content-header">
373 <h1 class="mxch-content-title"><?php esc_html_e('Lead Capture', 'mxchat'); ?></h1>
374 <p class="mxch-content-subtitle"><?php esc_html_e('Collect user information and manage privacy settings.', 'mxchat'); ?></p>
375 </div>
376
377 <div class="mxch-card">
378 <div class="mxch-card-header">
379 <h3 class="mxch-card-title">
380 <svg class="mxch-card-title-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>
381 <?php esc_html_e('Email Capture', 'mxchat'); ?>
382 </h3>
383 </div>
384 <div class="mxch-card-body mxchat-autosave-section">
385 <?php
386 // Require Email
387 mxchat_render_field_wrapper('enable_email_block', __('Require Email to Chat', 'mxchat'), function() use ($admin_instance) {
388 $admin_instance->enable_email_block_callback();
389 }, __('Require users to enter their email before chatting. Shows for non-logged-in users.', 'mxchat'));
390
391 // Email Form Content
392 mxchat_render_field_wrapper('email_blocker_header', __('Email Form Content', 'mxchat'), function() use ($admin_instance) {
393 $admin_instance->email_blocker_header_content_callback();
394 }, __('HTML content shown above the email form.', 'mxchat'));
395
396 // Email Button Text
397 mxchat_render_field_wrapper('email_blocker_button', __('Submit Button Text', 'mxchat'), function() use ($admin_instance) {
398 $admin_instance->email_blocker_button_text_callback();
399 }, __('Text for the email form submit button.', 'mxchat'));
400
401 // Require Name
402 mxchat_render_field_wrapper('enable_name_field', __('Also Require Name', 'mxchat'), function() use ($admin_instance) {
403 $admin_instance->enable_name_field_callback();
404 }, __('Also require users to enter their name with email.', 'mxchat'));
405
406 // Name Placeholder
407 mxchat_render_field_wrapper('name_placeholder', __('Name Field Placeholder', 'mxchat'), function() use ($admin_instance) {
408 $admin_instance->name_field_placeholder_callback();
409 }, __('Placeholder text for the name input field.', 'mxchat'));
410 ?>
411 </div>
412 </div>
413
414 <div class="mxch-card">
415 <div class="mxch-card-header">
416 <h3 class="mxch-card-title">
417 <svg class="mxch-card-title-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
418 <?php esc_html_e('Privacy & Compliance', 'mxchat'); ?>
419 </h3>
420 </div>
421 <div class="mxch-card-body mxchat-autosave-section">
422 <?php
423 // Privacy Notice
424 mxchat_render_field_wrapper('privacy_toggle', __('Privacy Notice', 'mxchat'), function() use ($admin_instance) {
425 $admin_instance->mxchat_privacy_toggle_callback();
426 }, __('Show privacy notice below the chat widget.', 'mxchat'));
427
428 // Complianz
429 mxchat_render_field_wrapper('complianz_toggle', __('Complianz Integration', 'mxchat'), function() use ($admin_instance) {
430 $admin_instance->mxchat_complianz_toggle_callback();
431 }, __('Apply Complianz consent logic to the chatbot (requires Complianz plugin).', 'mxchat'));
432 ?>
433 </div>
434 </div>
435 </div>
436
437 <!-- ========================================
438 CHATBOT - QUICK QUESTIONS
439 ======================================== -->
440 <div id="chatbot-quick-questions" class="mxch-section">
441 <div class="mxch-content-header">
442 <h1 class="mxch-content-title"><?php esc_html_e('Quick Questions', 'mxchat'); ?></h1>
443 <p class="mxch-content-subtitle"><?php esc_html_e('Pre-defined questions displayed above the chat input to help users get started.', 'mxchat'); ?></p>
444 </div>
445
446 <div class="mxch-card">
447 <div class="mxch-card-body mxchat-autosave-section">
448 <?php
449 // Quick Question 1
450 mxchat_render_field_wrapper('popular_question_1', __('Quick Question 1', 'mxchat'), function() use ($admin_instance) {
451 $admin_instance->mxchat_popular_question_1_callback();
452 });
453
454 // Quick Question 2
455 mxchat_render_field_wrapper('popular_question_2', __('Quick Question 2', 'mxchat'), function() use ($admin_instance) {
456 $admin_instance->mxchat_popular_question_2_callback();
457 });
458
459 // Quick Question 3
460 mxchat_render_field_wrapper('popular_question_3', __('Quick Question 3', 'mxchat'), function() use ($admin_instance) {
461 $admin_instance->mxchat_popular_question_3_callback();
462 });
463
464 // Additional Questions
465 mxchat_render_field_wrapper('additional_questions', __('Additional Questions', 'mxchat'), function() use ($admin_instance) {
466 $admin_instance->mxchat_additional_popular_questions_callback();
467 }, __('Add as many quick questions as you need.', 'mxchat'));
468 ?>
469 </div>
470 </div>
471 </div>
472
473 <!-- ========================================
474 CHATBOT - RATE LIMITS
475 ======================================== -->
476 <div id="chatbot-rate-limits" class="mxch-section">
477 <div class="mxch-content-header">
478 <h1 class="mxch-content-title"><?php esc_html_e('Rate Limits', 'mxchat'); ?></h1>
479 <p class="mxch-content-subtitle"><?php esc_html_e('Set message limits for each user role to manage API usage.', 'mxchat'); ?></p>
480 </div>
481
482 <div class="mxch-notice mxch-notice-info" style="margin-bottom: 24px;">
483 <svg class="mxch-notice-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
484 <div>
485 <strong><?php esc_html_e('Placeholders available:', 'mxchat'); ?></strong>
486 <code>{limit}</code>, <code>{timeframe}</code>, <code>{count}</code>, <code>{remaining}</code>
487 <br>
488 <strong><?php esc_html_e('Markdown links supported:', 'mxchat'); ?></strong>
489 <code>[Link text](https://example.com)</code>
490 </div>
491 </div>
492
493 <div class="mxch-card">
494 <div class="mxch-card-body mxchat-autosave-section">
495 <?php
496 // Render rate limits with accordion
497 mxchat_render_rate_limits_accordion($admin_instance);
498 ?>
499 </div>
500 </div>
501 </div>
502
503 <!-- ========================================
504 API KEYS
505 ======================================== -->
506 <div id="api-keys" class="mxch-section">
507 <div class="mxch-content-header">
508 <h1 class="mxch-content-title"><?php esc_html_e('API Keys', 'mxchat'); ?></h1>
509 <p class="mxch-content-subtitle"><?php esc_html_e('Manage API keys for AI providers and integrations.', 'mxchat'); ?></p>
510 </div>
511
512 <div class="mxch-card">
513 <div class="mxch-card-header">
514 <h3 class="mxch-card-title">
515 <svg class="mxch-card-title-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/></svg>
516 <?php esc_html_e('AI Providers', 'mxchat'); ?>
517 </h3>
518 </div>
519 <div class="mxch-card-body mxchat-autosave-section">
520 <table class="form-table">
521 <?php do_settings_fields('mxchat-api-keys', 'mxchat_api_keys_section'); ?>
522 </table>
523 </div>
524 </div>
525 </div>
526
527 <!-- ========================================
528 INTEGRATIONS - TOOLBAR
529 ======================================== -->
530 <div id="integrations-toolbar" class="mxch-section">
531 <div class="mxch-content-header">
532 <h1 class="mxch-content-title"><?php esc_html_e('Toolbar Settings', 'mxchat'); ?></h1>
533 <p class="mxch-content-subtitle"><?php esc_html_e('Configure the chat toolbar and document upload features.', 'mxchat'); ?></p>
534 </div>
535
536 <div class="mxch-card">
537 <div class="mxch-card-body mxchat-autosave-section">
538 <table class="form-table">
539 <?php do_settings_fields('mxchat-embed', 'mxchat_pdf_intent_section'); ?>
540 </table>
541 </div>
542 </div>
543 </div>
544
545 <!-- ========================================
546 INTEGRATIONS - LOOPS
547 ======================================== -->
548 <div id="integrations-loops" class="mxch-section">
549 <div class="mxch-content-header">
550 <h1 class="mxch-content-title"><?php esc_html_e('Loops Integration', 'mxchat'); ?></h1>
551 <p class="mxch-content-subtitle"><?php esc_html_e('Configure email capture with Loops for mailing list growth.', 'mxchat'); ?></p>
552 </div>
553
554 <div class="mxch-card">
555 <div class="mxch-card-body mxchat-autosave-section">
556 <table class="form-table">
557 <?php do_settings_fields('mxchat-embed', 'mxchat_loops_section'); ?>
558 </table>
559 </div>
560 </div>
561 </div>
562
563 <!-- ========================================
564 INTEGRATIONS - BRAVE SEARCH
565 ======================================== -->
566 <div id="integrations-brave" class="mxch-section">
567 <div class="mxch-content-header">
568 <h1 class="mxch-content-title"><?php esc_html_e('Brave Search', 'mxchat'); ?></h1>
569 <p class="mxch-content-subtitle"><?php esc_html_e('Configure Brave Search API for web search capabilities.', 'mxchat'); ?></p>
570 </div>
571
572 <div class="mxch-card">
573 <div class="mxch-card-body mxchat-autosave-section">
574 <table class="form-table">
575 <?php do_settings_fields('mxchat-embed', 'mxchat_brave_section'); ?>
576 </table>
577 </div>
578 </div>
579 </div>
580
581 <!-- ========================================
582 INTEGRATIONS - SLACK
583 ======================================== -->
584 <div id="integrations-slack" class="mxch-section">
585 <div class="mxch-content-header">
586 <h1 class="mxch-content-title"><?php esc_html_e('Slack', 'mxchat'); ?></h1>
587 <p class="mxch-content-subtitle"><?php esc_html_e('Connect your chatbot to Slack for live human support.', 'mxchat'); ?></p>
588 </div>
589
590 <div class="mxch-notice mxch-notice-info" style="margin-bottom: 24px;">
591 <svg class="mxch-notice-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
592 <div>
593 <?php printf(
594 esc_html__('Visit our %s for setup instructions.', 'mxchat'),
595 '<a href="https://mxchat.ai/documentation/#slack_integration" target="_blank">' . esc_html__('documentation page', 'mxchat') . '</a>'
596 ); ?>
597 </div>
598 </div>
599
600 <div class="mxch-card">
601 <div class="mxch-card-body mxchat-autosave-section">
602 <table class="form-table">
603 <?php do_settings_fields('mxchat-embed', 'mxchat_live_agent_section'); ?>
604 </table>
605 </div>
606 </div>
607
608 <div class="mxch-card" style="margin-top: 24px;">
609 <div class="mxch-card-header">
610 <h3 class="mxch-card-title">
611 <svg class="mxch-card-title-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
612 <?php esc_html_e('Test Connection', 'mxchat'); ?>
613 </h3>
614 </div>
615 <div class="mxch-card-body">
616 <p class="mxch-field-description" style="margin-bottom: 16px;">
617 <?php esc_html_e('Test your Slack bot token to verify it has the required permissions. This will check if the bot can authenticate and create channels.', 'mxchat'); ?>
618 </p>
619 <button type="button" id="mxchat-test-slack-connection" class="mxch-btn mxch-btn-secondary">
620 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 8px;"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
621 <?php esc_html_e('Test Slack Connection', 'mxchat'); ?>
622 </button>
623 <div id="mxchat-slack-test-result" style="margin-top: 16px; display: none;"></div>
624 </div>
625 </div>
626
627 <div class="mxch-card" style="margin-top: 24px;">
628 <div class="mxch-card-header">
629 <h3 class="mxch-card-title">
630 <svg class="mxch-card-title-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
631 <?php esc_html_e('Required OAuth Scopes', 'mxchat'); ?>
632 </h3>
633 </div>
634 <div class="mxch-card-body">
635 <p class="mxch-field-description" style="margin-bottom: 12px;">
636 <?php esc_html_e('Your Slack app needs these Bot Token Scopes (OAuth & Permissions > Scopes):', 'mxchat'); ?>
637 </p>
638 <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 8px; background: #f8f9fa; padding: 16px; border-radius: 8px; font-family: monospace; font-size: 13px;">
639 <code style="background: #e9ecef; padding: 4px 8px; border-radius: 4px;">channels:manage</code>
640 <code style="background: #e9ecef; padding: 4px 8px; border-radius: 4px;">channels:read</code>
641 <code style="background: #e9ecef; padding: 4px 8px; border-radius: 4px;">chat:write</code>
642 <code style="background: #e9ecef; padding: 4px 8px; border-radius: 4px;">chat:write.public</code>
643 <code style="background: #e9ecef; padding: 4px 8px; border-radius: 4px;">groups:write</code>
644 <code style="background: #e9ecef; padding: 4px 8px; border-radius: 4px;">users:read</code>
645 </div>
646 <p class="mxch-field-description" style="margin-top: 12px;">
647 <?php esc_html_e('After adding scopes, reinstall the app to your workspace.', 'mxchat'); ?>
648 </p>
649 </div>
650 </div>
651 </div>
652
653 <!-- ========================================
654 INTEGRATIONS - TELEGRAM
655 ======================================== -->
656 <div id="integrations-telegram" class="mxch-section">
657 <div class="mxch-content-header">
658 <h1 class="mxch-content-title"><?php esc_html_e('Telegram', 'mxchat'); ?></h1>
659 <p class="mxch-content-subtitle"><?php esc_html_e('Connect your chatbot to Telegram for live human support.', 'mxchat'); ?></p>
660 </div>
661
662 <div class="mxch-notice mxch-notice-info" style="margin-bottom: 24px;">
663 <svg class="mxch-notice-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
664 <div>
665 <?php esc_html_e('Telegram Live Agent requires a Telegram bot and a supergroup with forum topics enabled.', 'mxchat'); ?>
666 <a href="https://mxchat.ai/documentation-bot/" target="_blank" style="margin-left: 5px;"><?php esc_html_e('Chat with our advanced doc bot for assistance setting up.', 'mxchat'); ?></a>
667 </div>
668 </div>
669
670 <div class="mxch-card">
671 <div class="mxch-card-body mxchat-autosave-section">
672 <table class="form-table">
673 <?php do_settings_fields('mxchat-embed', 'mxchat_telegram_section'); ?>
674 </table>
675 </div>
676 </div>
677
678 <div class="mxch-card" style="margin-top: 24px;">
679 <div class="mxch-card-header">
680 <h3 class="mxch-card-title">
681 <svg class="mxch-card-title-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg>
682 <?php esc_html_e('Webhook Setup', 'mxchat'); ?>
683 </h3>
684 </div>
685 <div class="mxch-card-body">
686 <?php
687 $telegram_bot_token = $options['telegram_bot_token'] ?? '';
688 $telegram_webhook_secret = $options['telegram_webhook_secret'] ?? '';
689 $webhook_url = rest_url('mxchat/v1/telegram-webhook');
690 ?>
691
692 <p class="mxch-field-description" style="margin-bottom: 8px;">
693 <strong><?php esc_html_e('Your Webhook URL:', 'mxchat'); ?></strong>
694 </p>
695 <div class="mxch-webhook-url-display" style="margin-bottom: 20px;">
696 <code id="mxch-telegram-webhook-url"><?php echo esc_url($webhook_url); ?></code>
697 <button type="button" class="mxch-btn mxch-btn-secondary mxch-btn-sm" onclick="navigator.clipboard.writeText(document.getElementById('mxch-telegram-webhook-url').textContent); this.textContent='Copied!'; setTimeout(() => this.textContent='Copy', 2000);">
698 <?php esc_html_e('Copy', 'mxchat'); ?>
699 </button>
700 </div>
701
702 <?php if (!empty($telegram_bot_token)) : ?>
703 <p class="mxch-field-description" style="margin-bottom: 8px;">
704 <strong><?php esc_html_e('Register Webhook URL:', 'mxchat'); ?></strong><br>
705 <?php esc_html_e('Copy and paste this URL into your browser to register the webhook with Telegram:', 'mxchat'); ?>
706 </p>
707 <?php
708 $registration_url = 'https://api.telegram.org/bot' . $telegram_bot_token . '/setWebhook?url=' . urlencode($webhook_url);
709 if (!empty($telegram_webhook_secret)) {
710 $registration_url .= '&secret_token=' . urlencode($telegram_webhook_secret);
711 }
712 ?>
713 <div class="mxch-webhook-url-display" style="margin-bottom: 12px;">
714 <code id="mxch-telegram-registration-url" style="word-break: break-all; font-size: 12px;"><?php echo esc_url($registration_url); ?></code>
715 <button type="button" class="mxch-btn mxch-btn-secondary mxch-btn-sm" onclick="navigator.clipboard.writeText(document.getElementById('mxch-telegram-registration-url').textContent); this.textContent='Copied!'; setTimeout(() => this.textContent='Copy', 2000);">
716 <?php esc_html_e('Copy', 'mxchat'); ?>
717 </button>
718 </div>
719 <p class="mxch-field-description" style="color: #22c55e;">
720 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: middle; margin-right: 4px;"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
721 <?php esc_html_e('You should see {"ok":true,"result":true,"description":"Webhook was set"} after visiting the URL.', 'mxchat'); ?>
722 </p>
723 <?php else : ?>
724 <p class="mxch-field-description" style="color: #f59e0b;">
725 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: middle; margin-right: 4px;"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>
726 <?php esc_html_e('Enter your Bot Token above and save to generate the registration URL.', 'mxchat'); ?>
727 </p>
728 <?php endif; ?>
729 </div>
730 </div>
731 </div>
732
733 <!-- ========================================
734 TUTORIALS
735 ======================================== -->
736 <div id="tutorials" class="mxch-section">
737 <div class="mxch-content-header">
738 <h1 class="mxch-content-title"><?php esc_html_e('Video Tutorials', 'mxchat'); ?></h1>
739 <p class="mxch-content-subtitle"><?php esc_html_e('Learn how to get the most out of MxChat with our video guides.', 'mxchat'); ?></p>
740 </div>
741
742 <div class="mxch-card" style="margin-bottom: 24px;">
743 <div class="mxch-card-body">
744 <div style="display: flex; align-items: flex-start; gap: 16px;">
745 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="color: var(--mxch-warning); flex-shrink: 0;"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>
746 <div>
747 <h3 style="margin: 0 0 8px 0; font-size: 16px; font-weight: 600;"><?php esc_html_e('Need Help?', 'mxchat'); ?></h3>
748 <p style="margin: 0 0 12px 0; color: var(--mxch-text-secondary);"><?php esc_html_e('If you\'re having trouble or believe something is not working as expected, please submit a support ticket.', 'mxchat'); ?></p>
749 <a href="https://wordpress.org/support/plugin/mxchat-basic/" target="_blank" class="mxch-btn mxch-btn-secondary mxch-btn-sm">
750 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 9a2 2 0 0 1-2 2H6l-4 4V4c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2v5Z"/><path d="M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1"/></svg>
751 <?php esc_html_e('Submit Support Ticket', 'mxchat'); ?>
752 </a>
753 </div>
754 </div>
755 </div>
756 </div>
757
758 <div class="mxch-tutorials-grid">
759 <?php
760 $tutorials = array(
761 array(
762 'title' => __('AI Theme Generator', 'mxchat'),
763 'description' => __('Learn how to instantly restyle your chatbot using plain English prompts with real-time previews.', 'mxchat'),
764 'url' => 'https://www.youtube.com/watch?v=rSQDW2qbtRU&t'
765 ),
766 array(
767 'title' => __('MxChat Forms', 'mxchat'),
768 'description' => __('Create and manage smart forms that automatically trigger during chat conversations.', 'mxchat'),
769 'url' => 'https://www.youtube.com/watch?v=3MrWy5dRalA'
770 ),
771 array(
772 'title' => __('Admin Assistant Add-on', 'mxchat'),
773 'description' => __('Bring a ChatGPT-like experience directly inside your WordPress dashboard.', 'mxchat'),
774 'url' => 'https://youtu.be/AdEA1k-UCFM'
775 ),
776 array(
777 'title' => __('Intent Tester Guide', 'mxchat'),
778 'description' => __('Fine-tune your chatbot\'s responses and ensure accurate query understanding.', 'mxchat'),
779 'url' => 'https://www.youtube.com/watch?v=uTr14tn59Hc'
780 ),
781 array(
782 'title' => __('Theme Customizer', 'mxchat'),
783 'description' => __('Customize appearance with real-time previews to match your brand.', 'mxchat'),
784 'url' => 'https://youtu.be/MfbB9mZi6ag'
785 ),
786 array(
787 'title' => __('WooCommerce Integration', 'mxchat'),
788 'description' => __('Provide product recommendations and shopping assistance to customers.', 'mxchat'),
789 'url' => 'https://www.youtube.com/watch?v=WsqAppHRGdA'
790 ),
791 array(
792 'title' => __('Knowledge Base Setup', 'mxchat'),
793 'description' => __('Set up your knowledge base using PDFs, sitemaps, and manual entries.', 'mxchat'),
794 'url' => 'https://www.youtube.com/watch?v=8Ztjs66-VTo'
795 ),
796 array(
797 'title' => __('Document Chat', 'mxchat'),
798 'description' => __('Chat with PDF and Word documents for enhanced document analysis.', 'mxchat'),
799 'url' => 'https://www.youtube.com/watch?v=j_c45WWCTG0'
800 ),
801 array(
802 'title' => __('Perplexity Integration', 'mxchat'),
803 'description' => __('Enable real-time web search capabilities for your chatbot.', 'mxchat'),
804 'url' => 'https://youtu.be/wpKkbt24-bo'
805 ),
806 array(
807 'title' => __('Brave Search Intent', 'mxchat'),
808 'description' => __('Leverage Brave Search for improved query understanding.', 'mxchat'),
809 'url' => 'https://www.youtube.com/watch?v=7vDL5H7vToc'
810 ),
811 array(
812 'title' => __('Loops Email Capture', 'mxchat'),
813 'description' => __('Set up email capture with Loops to grow your mailing list.', 'mxchat'),
814 'url' => 'https://www.youtube.com/watch?v=CNgm5TYDyTc'
815 ),
816 array(
817 'title' => __('AI Agent Testing', 'mxchat'),
818 'description' => __('Evaluate and improve your chatbot\'s performance and accuracy.', 'mxchat'),
819 'url' => 'https://www.youtube.com/watch?v=A0jowbpyX54'
820 ),
821 );
822
823 foreach ($tutorials as $tutorial): ?>
824 <div class="mxch-tutorial-card">
825 <div class="mxch-tutorial-content">
826 <h3 class="mxch-tutorial-title"><?php echo esc_html($tutorial['title']); ?></h3>
827 <p class="mxch-tutorial-description"><?php echo esc_html($tutorial['description']); ?></p>
828 <a href="<?php echo esc_url($tutorial['url']); ?>" target="_blank" rel="noopener" class="mxch-tutorial-link">
829 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>
830 <?php esc_html_e('Watch Tutorial', 'mxchat'); ?>
831 </a>
832 </div>
833 </div>
834 <?php endforeach; ?>
835 </div>
836 </div>
837
838 </main>
839 </div>
840
841 <script>
842 document.addEventListener('DOMContentLoaded', function() {
843 // Sidebar navigation
844 const navLinks = document.querySelectorAll('.mxch-nav-link, .mxch-nav-sub-link');
845 const sections = document.querySelectorAll('.mxch-section');
846 const navItems = document.querySelectorAll('.mxch-nav-item');
847
848 function showSection(target) {
849 // Show target section
850 sections.forEach(section => {
851 section.classList.remove('active');
852 if (section.id === target) {
853 section.classList.add('active');
854 }
855 });
856
857 // Scroll content area to top
858 const contentArea = document.querySelector('.mxch-content');
859 if (contentArea) {
860 contentArea.scrollTop = 0;
861 }
862 }
863
864 function setActiveNav(clickedLink) {
865 // Remove active from all links
866 navLinks.forEach(l => l.classList.remove('active'));
867
868 // Add active to clicked link
869 clickedLink.classList.add('active');
870
871 // If clicking a sub-link, also highlight parent
872 if (clickedLink.classList.contains('mxch-nav-sub-link')) {
873 const parent = clickedLink.closest('.mxch-nav-item');
874 if (parent) {
875 parent.querySelector('.mxch-nav-link').classList.add('active');
876 }
877 }
878 }
879
880 navLinks.forEach(link => {
881 link.addEventListener('click', function(e) {
882 e.preventDefault();
883 e.stopPropagation();
884 const target = this.dataset.target;
885 const parentItem = this.closest('.mxch-nav-item');
886 const hasSubmenu = parentItem && parentItem.querySelector('.mxch-nav-sub');
887
888 // If this is a parent nav link WITH children (expandable menu)
889 if (this.classList.contains('mxch-nav-link') && hasSubmenu) {
890 const wasExpanded = parentItem.classList.contains('expanded');
891
892 // Collapse all other expandable items
893 navItems.forEach(item => {
894 if (item !== parentItem && item.querySelector('.mxch-nav-sub')) {
895 item.classList.remove('expanded');
896 }
897 });
898
899 // Toggle this item
900 parentItem.classList.toggle('expanded');
901
902 // If expanding, show the first sub-item's content and mark it active
903 if (!wasExpanded) {
904 const firstSubLink = parentItem.querySelector('.mxch-nav-sub-link');
905 if (firstSubLink) {
906 const firstTarget = firstSubLink.dataset.target;
907 showSection(firstTarget);
908 setActiveNav(firstSubLink);
909 // Also mark parent as active
910 this.classList.add('active');
911 history.replaceState(null, null, '#' + firstTarget);
912 }
913 }
914 }
915 // If this is a nav link WITHOUT children (like API Keys, Tutorials)
916 else if (this.classList.contains('mxch-nav-link') && !hasSubmenu && target) {
917 // Collapse all expandable items
918 navItems.forEach(item => {
919 if (item.querySelector('.mxch-nav-sub')) {
920 item.classList.remove('expanded');
921 }
922 });
923
924 // Show the section
925 showSection(target);
926 setActiveNav(this);
927 history.replaceState(null, null, '#' + target);
928 }
929 // If this is a sub-link
930 else if (this.classList.contains('mxch-nav-sub-link') && target) {
931 // Ensure parent stays expanded
932 if (parentItem) {
933 parentItem.classList.add('expanded');
934 }
935 showSection(target);
936 setActiveNav(this);
937 history.replaceState(null, null, '#' + target);
938 }
939 });
940 });
941
942 // Handle initial hash
943 const hash = window.location.hash.slice(1);
944 if (hash) {
945 const targetLink = document.querySelector('[data-target="' + hash + '"]');
946 if (targetLink) {
947 // Expand parent if it's a sub-link
948 const parentItem = targetLink.closest('.mxch-nav-item');
949 if (parentItem && targetLink.classList.contains('mxch-nav-sub-link')) {
950 parentItem.classList.add('expanded');
951 }
952 showSection(hash);
953 setActiveNav(targetLink);
954 }
955 }
956
957 // Rate limit accordion
958 const rateLimitHeaders = document.querySelectorAll('.mxch-rate-limit-header');
959 rateLimitHeaders.forEach(header => {
960 header.addEventListener('click', function(e) {
961 e.preventDefault();
962 e.stopPropagation();
963 const item = this.closest('.mxch-rate-limit-item');
964 item.classList.toggle('expanded');
965 });
966 });
967
968 // =====================================================
969 // Mobile Menu Functionality
970 // =====================================================
971 const mobileMenuBtn = document.querySelector('.mxch-mobile-menu-btn');
972 const mobileMenuClose = document.querySelector('.mxch-mobile-menu-close');
973 const mobileMenu = document.querySelector('.mxch-mobile-menu');
974 const mobileOverlay = document.querySelector('.mxch-mobile-overlay');
975 const mobileNavLinks = document.querySelectorAll('.mxch-mobile-nav-link, .mxch-mobile-nav-sub-link');
976
977 function openMobileMenu() {
978 mobileMenu.classList.add('open');
979 mobileOverlay.classList.add('open');
980 document.body.style.overflow = 'hidden';
981 }
982
983 function closeMobileMenu() {
984 mobileMenu.classList.remove('open');
985 mobileOverlay.classList.remove('open');
986 document.body.style.overflow = '';
987 }
988
989 if (mobileMenuBtn) {
990 mobileMenuBtn.addEventListener('click', openMobileMenu);
991 }
992
993 if (mobileMenuClose) {
994 mobileMenuClose.addEventListener('click', closeMobileMenu);
995 }
996
997 if (mobileOverlay) {
998 mobileOverlay.addEventListener('click', closeMobileMenu);
999 }
1000
1001 // Mobile navigation links
1002 mobileNavLinks.forEach(link => {
1003 link.addEventListener('click', function(e) {
1004 e.preventDefault();
1005 e.stopPropagation();
1006
1007 const target = this.dataset.target;
1008 const parentId = this.dataset.parent;
1009
1010 // If this is an expandable parent link
1011 if (parentId && !target) {
1012 const subNav = document.querySelector('.mxch-mobile-nav-sub[data-parent="' + parentId + '"]');
1013 if (subNav) {
1014 const isExpanded = subNav.classList.contains('expanded');
1015 // Collapse all sub navs
1016 document.querySelectorAll('.mxch-mobile-nav-sub').forEach(nav => {
1017 nav.classList.remove('expanded');
1018 });
1019 document.querySelectorAll('.mxch-mobile-nav-link').forEach(l => {
1020 l.classList.remove('expanded');
1021 });
1022 // Toggle this one
1023 if (!isExpanded) {
1024 subNav.classList.add('expanded');
1025 this.classList.add('expanded');
1026 }
1027 }
1028 }
1029 // If this is a direct link or sub-link with a target
1030 else if (target) {
1031 // Update mobile nav active state
1032 document.querySelectorAll('.mxch-mobile-nav-link, .mxch-mobile-nav-sub-link').forEach(l => {
1033 l.classList.remove('active');
1034 });
1035 this.classList.add('active');
1036
1037 // Also update desktop sidebar nav
1038 const desktopLink = document.querySelector('.mxch-sidebar [data-target="' + target + '"]');
1039 if (desktopLink) {
1040 setActiveNav(desktopLink);
1041 const parentItem = desktopLink.closest('.mxch-nav-item');
1042 if (parentItem && desktopLink.classList.contains('mxch-nav-sub-link')) {
1043 parentItem.classList.add('expanded');
1044 }
1045 }
1046
1047 // Show section and close menu
1048 showSection(target);
1049 history.replaceState(null, null, '#' + target);
1050 closeMobileMenu();
1051 }
1052 });
1053 });
1054
1055 // Close mobile menu on escape key
1056 document.addEventListener('keydown', function(e) {
1057 if (e.key === 'Escape' && mobileMenu && mobileMenu.classList.contains('open')) {
1058 closeMobileMenu();
1059 }
1060 });
1061 });
1062 </script>
1063 <?php
1064 }
1065
1066 /**
1067 * Helper function to render a field with consistent wrapper
1068 */
1069 function mxchat_render_field_wrapper($id, $label, $callback, $description = '') {
1070 ?>
1071 <div class="mxch-field">
1072 <label class="mxch-field-label"><?php echo esc_html($label); ?></label>
1073 <div class="mxch-field-control">
1074 <?php $callback(); ?>
1075 </div>
1076 <?php if ($description): ?>
1077 <p class="mxch-field-description"><?php echo esc_html($description); ?></p>
1078 <?php endif; ?>
1079 </div>
1080 <?php
1081 }
1082
1083 /**
1084 * Render rate limits as collapsible accordion
1085 */
1086 function mxchat_render_rate_limits_accordion($admin_instance) {
1087 $all_options = get_option('mxchat_options', []);
1088 $rate_limits = array('1', '3', '5', '10', '15', '20', '50', '100', 'unlimited');
1089 $timeframes = array(
1090 'hourly' => __('Per Hour', 'mxchat'),
1091 'daily' => __('Per Day', 'mxchat'),
1092 'weekly' => __('Per Week', 'mxchat'),
1093 'monthly' => __('Per Month', 'mxchat')
1094 );
1095
1096 $roles = wp_roles()->get_names();
1097 $roles['logged_out'] = __('Logged Out Users', 'mxchat');
1098
1099 echo '<div class="mxch-rate-limits">';
1100
1101 foreach ($roles as $role_id => $role_name) {
1102 $default_limit = ($role_id === 'logged_out') ? '10' : '100';
1103 $default_timeframe = 'daily';
1104 $default_message = __('Rate limit exceeded. Please try again later.', 'mxchat');
1105
1106 $selected_limit = isset($all_options['rate_limits'][$role_id]['limit'])
1107 ? $all_options['rate_limits'][$role_id]['limit']
1108 : $default_limit;
1109
1110 $selected_timeframe = isset($all_options['rate_limits'][$role_id]['timeframe'])
1111 ? $all_options['rate_limits'][$role_id]['timeframe']
1112 : $default_timeframe;
1113
1114 $custom_message = isset($all_options['rate_limits'][$role_id]['message'])
1115 ? $all_options['rate_limits'][$role_id]['message']
1116 : $default_message;
1117
1118 $timeframe_label = isset($timeframes[$selected_timeframe]) ? $timeframes[$selected_timeframe] : $selected_timeframe;
1119 ?>
1120 <div class="mxch-rate-limit-item">
1121 <div class="mxch-rate-limit-header">
1122 <span class="mxch-rate-limit-role"><?php echo esc_html($role_name); ?></span>
1123 <div class="mxch-rate-limit-summary">
1124 <span class="mxch-rate-limit-badge"><?php echo esc_html($selected_limit . ' / ' . $timeframe_label); ?></span>
1125 <svg class="mxch-rate-limit-arrow" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>
1126 </div>
1127 </div>
1128 <div class="mxch-rate-limit-body mxchat-autosave-section">
1129 <div class="mxch-rate-limit-controls">
1130 <div class="mxch-field">
1131 <label class="mxch-field-label" for="rate_limits_<?php echo esc_attr($role_id); ?>_limit"><?php esc_html_e('Limit', 'mxchat'); ?></label>
1132 <select id="rate_limits_<?php echo esc_attr($role_id); ?>_limit"
1133 name="mxchat_options[rate_limits][<?php echo esc_attr($role_id); ?>][limit]"
1134 class="mxch-select mxchat-autosave-field">
1135 <?php foreach ($rate_limits as $limit): ?>
1136 <option value="<?php echo esc_attr($limit); ?>" <?php selected($selected_limit, $limit); ?>><?php echo esc_html($limit); ?></option>
1137 <?php endforeach; ?>
1138 </select>
1139 </div>
1140 <div class="mxch-field">
1141 <label class="mxch-field-label" for="rate_limits_<?php echo esc_attr($role_id); ?>_timeframe"><?php esc_html_e('Timeframe', 'mxchat'); ?></label>
1142 <select id="rate_limits_<?php echo esc_attr($role_id); ?>_timeframe"
1143 name="mxchat_options[rate_limits][<?php echo esc_attr($role_id); ?>][timeframe]"
1144 class="mxch-select mxchat-autosave-field">
1145 <?php foreach ($timeframes as $value => $label): ?>
1146 <option value="<?php echo esc_attr($value); ?>" <?php selected($selected_timeframe, $value); ?>><?php echo esc_html($label); ?></option>
1147 <?php endforeach; ?>
1148 </select>
1149 </div>
1150 </div>
1151 <div class="mxch-field">
1152 <label class="mxch-field-label" for="rate_limits_<?php echo esc_attr($role_id); ?>_message"><?php esc_html_e('Custom Message', 'mxchat'); ?></label>
1153 <textarea id="rate_limits_<?php echo esc_attr($role_id); ?>_message"
1154 name="mxchat_options[rate_limits][<?php echo esc_attr($role_id); ?>][message]"
1155 class="mxch-textarea mxchat-autosave-field"
1156 rows="2"
1157 placeholder="<?php esc_attr_e('Message shown when rate limit is reached', 'mxchat'); ?>"><?php echo esc_textarea($custom_message); ?></textarea>
1158 </div>
1159 </div>
1160 </div>
1161 <?php
1162 }
1163
1164 echo '</div>';
1165 }
1166