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

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