PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 3.1.1
MxChat – AI Chatbot & Content Generation for WordPress v3.1.1
3.2.21 3.2.20 3.2.19 3.2.18 3.2.17 3.2.16 3.2.15 3.2.14 3.2.12 3.2.13 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 3.2.6 3.2.5 3.2.4 3.2.3 3.2.2 3.2.1 2.0.3 2.0.4 2.0.5 2.0.6 All 152 releases
← All changes | includes/admin-content-page.php +25 -402 3.2.213.1.1 View file →
@@ -22,10 +22,8 @@
22 22 $pro_tool_use = apply_filters('mxchat_content_pro_feature', false, 'tool_use');
23 23 $pro_image_management = apply_filters('mxchat_content_pro_feature', false, 'image_management');
24 24 $pro_meta_management = apply_filters('mxchat_content_pro_feature', false, 'meta_management');
25 25 $pro_gsc_integration = apply_filters('mxchat_content_pro_feature', false, 'gsc_integration');
26 - $pro_content_calendar = apply_filters('mxchat_content_pro_feature', false, 'content_calendar');
27 - $pro_template_generator = apply_filters('mxchat_content_pro_feature', false, 'template_generator');
28 26 ?>
29 27 <div class="mxch-admin-wrapper">
30 28 <!-- Mobile Header -->
31 29 <header class="mxch-mobile-header">
@@ -69,16 +67,8 @@
69 67 <button class="mxch-mobile-nav-link" data-target="content-seo">
70 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="M12 20V10"/><path d="M18 20V4"/><path d="M6 20v-4"/></svg>
71 69 <span><?php esc_html_e('SEO', 'mxchat'); ?></span>
72 70 </button>
73 - <button class="mxch-mobile-nav-link" data-target="content-calendar">
74 - <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"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
75 - <span><?php esc_html_e('Calendar', 'mxchat'); ?></span>
76 - </button>
77 - <button class="mxch-mobile-nav-link" data-target="content-templates">
78 - <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"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18"/><path d="M9 21V9"/></svg>
79 - <span><?php esc_html_e('Templates', 'mxchat'); ?></span>
80 - </button>
81 71 </div>
82 72 </nav>
83 73 </div>
84 74
@@ -132,26 +122,8 @@
132 122 </span>
133 123 <span class="mxch-nav-link-text"><?php esc_html_e('SEO', 'mxchat'); ?></span>
134 124 </button>
135 125 </div>
136 -
137 - <div class="mxch-nav-item" data-section="content-calendar">
138 - <button class="mxch-nav-link" data-target="content-calendar">
139 - <span class="mxch-nav-link-icon">
140 - <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"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
141 - </span>
142 - <span class="mxch-nav-link-text"><?php esc_html_e('Calendar', 'mxchat'); ?></span>
143 - </button>
144 - </div>
145 -
146 - <div class="mxch-nav-item" data-section="content-templates">
147 - <button class="mxch-nav-link" data-target="content-templates">
148 - <span class="mxch-nav-link-icon">
149 - <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"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18"/><path d="M9 21V9"/></svg>
150 - </span>
151 - <span class="mxch-nav-link-text"><?php esc_html_e('Templates', 'mxchat'); ?></span>
152 - </button>
153 - </div>
154 126 </div>
155 127 </nav>
156 128 </aside>
157 129
@@ -232,12 +204,8 @@
232 204 </div>
233 205 </div>
234 206 <div class="mxch-cg-form">
235 207 <textarea id="mxch-cg-prompt" class="mxch-cg-prompt" rows="3" placeholder="<?php esc_attr_e('Describe the content you want to generate...', 'mxchat'); ?>"></textarea>
236 - <button type="button" id="mxch-cg-edit-prompt-btn" class="mxch-cg-edit-prompt-btn">
237 - <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"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
238 - <?php esc_html_e('Edit Default Prompt', 'mxchat'); ?>
239 - </button>
240 208 <div class="mxch-cg-options">
241 209 <div class="mxch-cg-option">
242 210 <label class="mxch-cg-option-label" for="mxch-cg-type"><?php esc_html_e('Type', 'mxchat'); ?></label>
243 211 <select id="mxch-cg-type" class="mxch-cg-select">
@@ -272,15 +240,8 @@
272 240 <option value="show"><?php esc_html_e('Show', 'mxchat'); ?></option>
273 241 <option value="hide" selected><?php esc_html_e('Hide (title in content)', 'mxchat'); ?></option>
274 242 </select>
275 243 </div>
276 - <div class="mxch-cg-option">
277 - <label class="mxch-cg-option-label" for="mxch-cg-template-mode"><?php esc_html_e('Template Mode', 'mxchat'); ?></label>
278 - <select id="mxch-cg-template-mode" class="mxch-cg-select">
279 - <option value="off" selected><?php esc_html_e('Off', 'mxchat'); ?></option>
280 - <option value="on"><?php esc_html_e('On (Spintax)', 'mxchat'); ?></option>
281 - </select>
282 - </div>
283 244 </div>
284 245 <button type="button" id="mxch-cg-generate-btn" class="mxch-cg-generate-btn mxch-cg-generate-btn-full">
285 246 <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="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>
286 247 <span><?php esc_html_e('Generate Content', 'mxchat'); ?></span>
@@ -294,29 +255,8 @@
294 255 <p class="mxch-cg-progress-text"><?php esc_html_e('Starting...', 'mxchat'); ?></p>
295 256 </div>
296 257 </div>
297 258 </div>
298 - <!-- Edit Default Prompt Modal -->
299 - <div id="mxch-cg-prompt-modal" class="mxch-cg-prompt-modal" style="display:none;">
300 - <div class="mxch-cg-prompt-modal-overlay"></div>
301 - <div class="mxch-cg-prompt-modal-content">
302 - <div class="mxch-cg-prompt-modal-header">
303 - <h3><?php esc_html_e('Edit Default System Prompt', 'mxchat'); ?></h3>
304 - <button type="button" id="mxch-cg-prompt-modal-close" class="mxch-cg-prompt-modal-close">&times;</button>
305 - </div>
306 - <div class="mxch-cg-prompt-modal-body">
307 - <p class="mxch-cg-prompt-modal-desc"><?php esc_html_e('This is the system prompt sent to the AI when generating content. Edit it to customize how your content is generated.', 'mxchat'); ?></p>
308 - <textarea id="mxch-cg-system-prompt-editor" class="mxch-cg-system-prompt-editor" rows="20"></textarea>
309 - </div>
310 - <div class="mxch-cg-prompt-modal-footer">
311 - <button type="button" id="mxch-cg-prompt-reset" class="button"><?php esc_html_e('Reset to Default', 'mxchat'); ?></button>
312 - <div class="mxch-cg-prompt-modal-footer-right">
313 - <button type="button" id="mxch-cg-prompt-cancel" class="button"><?php esc_html_e('Cancel', 'mxchat'); ?></button>
314 - <button type="button" id="mxch-cg-prompt-save" class="button button-primary"><?php esc_html_e('Save Changes', 'mxchat'); ?></button>
315 - </div>
316 - </div>
317 - </div>
318 - </div>
319 259 <!-- Loading indicator (shown during async generation) -->
320 260 <div id="mxch-cg-loading-indicator" class="mxch-cg-loading-indicator" style="display:none;">
321 261 <div class="mxch-cg-loading-spinner">
322 262 <div class="mxch-cg-loading-spinner-ring"></div>
@@ -430,11 +370,11 @@
430 370 </div>
431 371 </div>
432 372 <!-- AI Optimize -->
433 373 <div class="mxch-seo-actions" id="mxch-seo-actions" style="display:none;">
434 - <button type="button" class="mxch-seo-fix-btn" id="mxch-seo-ai-optimize" title="<?php esc_attr_e('AI optimizes all failing SEO checks', 'mxchat'); ?>">
374 + <button type="button" class="mxch-seo-fix-btn" id="mxch-seo-ai-optimize" title="<?php esc_attr_e('AI generates optimized meta description, title, and slug', 'mxchat'); ?>">
435 375 <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"><path d="m12 3-1.9 5.8a2 2 0 0 1-1.287 1.288L3 12l5.8 1.9a2 2 0 0 1 1.288 1.287L12 21l1.9-5.8a2 2 0 0 1 1.287-1.288L21 12l-5.8-1.9a2 2 0 0 1-1.288-1.287Z"/></svg>
436 - <?php esc_html_e('Optimize All', 'mxchat'); ?>
376 + <?php esc_html_e('AI Optimize', 'mxchat'); ?>
437 377 </button>
438 378 </div>
439 379 </div>
440 380 </div>
@@ -512,40 +452,31 @@
512 452 <label class="mxch-field-label" for="mxch-content-model"><?php esc_html_e('Content Model', 'mxchat'); ?></label>
513 453 <div class="mxch-field-control">
514 454 <select id="mxch-content-model" data-field="content_model" class="mxch-cg-select">
515 455 <?php
516 - $content_model = $options['content_model'] ?? ($options['model'] ?? 'gpt-5.6-sol');
517 - // Catalog-derived (plan ccb751): this select was the seventh
518 - // hand-maintained model map and had drifted (it still offered
519 - // a code model for content generation). It now renders from
520 - // MxChat_Model_Catalog, restricted to the providers the
521 - // generator can actually dispatch to — see
522 - // MxChat_Content_Generator::supported_content_providers().
523 - $model_groups = MxChat_Model_Catalog::settings_dropdown_groups(
524 - $content_model,
525 - MxChat_Content_Generator::supported_content_providers()
456 + $content_model = $options['content_model'] ?? ($options['model'] ?? 'gpt-5.1-chat-latest');
457 + $models = array(
458 + 'OpenAI' => array(
459 + 'gpt-5.2' => 'GPT-5.2',
460 + 'gpt-5.1-chat-latest' => 'GPT-5.1',
461 + 'gpt-5' => 'GPT-5',
462 + ),
463 + 'Anthropic' => array(
464 + 'claude-opus-4-6' => 'Claude Opus 4.6',
465 + 'claude-sonnet-4-6' => 'Claude Sonnet 4.6',
466 + 'claude-haiku-4-5-20251001' => 'Claude Haiku 4.5',
467 + ),
468 + 'Google' => array(
469 + 'gemini-3-pro-preview' => 'Gemini 3 Pro',
470 + 'gemini-2.5-pro' => 'Gemini 2.5 Pro',
471 + ),
472 + 'xAI' => array(
473 + 'grok-4-0709' => 'Grok 4',
474 + 'grok-4-1-fast-non-reasoning' => 'Grok 4.1 Fast',
475 + 'grok-code-fast-1' => 'Grok Code Fast',
476 + ),
526 477 );
527 - // Round-trip guard: an install saved on an id the catalog no
528 - // longer lists (e.g. grok-code-fast-1) keeps its selection
529 - // rendered instead of silently snapping to the first option
530 - // on the next save.
531 - $mxch_cg_model_in_groups = false;
532 - foreach ($model_groups as $group_models) {
533 - if (array_key_exists($content_model, $group_models)) {
534 - $mxch_cg_model_in_groups = true;
535 - break;
536 - }
537 - }
538 - if (!$mxch_cg_model_in_groups && $content_model !== '') {
539 - $model_groups[__('Currently saved', 'mxchat')] = array(
540 - /* translators: %s: model id */
541 - $content_model => sprintf(__('%s — no longer offered, choose a replacement', 'mxchat'), $content_model),
542 - );
543 - }
544 - foreach ($model_groups as $group => $group_models) {
545 - if (empty($group_models)) {
546 - continue;
547 - }
478 + foreach ($models as $group => $group_models) {
548 479 echo '<optgroup label="' . esc_attr($group) . '">';
549 480 foreach ($group_models as $value => $label) {
550 481 $selected = selected($content_model, $value, false);
551 482 echo '<option value="' . esc_attr($value) . '" ' . $selected . '>' . esc_html($label) . '</option>';
@@ -564,9 +495,8 @@
564 495 <div class="mxch-field-control">
565 496 <?php $image_model = $options['content_image_model'] ?? 'gpt-image-1.5'; ?>
566 497 <select id="mxch-image-model" data-field="content_image_model" class="mxch-cg-select">
567 498 <optgroup label="<?php esc_attr_e('OpenAI', 'mxchat'); ?>">
568 - <option value="gpt-image-2" <?php selected($image_model, 'gpt-image-2'); ?>><?php esc_html_e('GPT Image 2 (Latest)', 'mxchat'); ?></option>
569 499 <option value="gpt-image-1.5" <?php selected($image_model, 'gpt-image-1.5'); ?>><?php esc_html_e('GPT Image 1.5', 'mxchat'); ?></option>
570 500 </optgroup>
571 501 <optgroup label="<?php esc_attr_e('xAI', 'mxchat'); ?>">
572 502 <option value="grok-imagine-image-pro" <?php selected($image_model, 'grok-imagine-image-pro'); ?>><?php esc_html_e('Grok Imagine Pro', 'mxchat'); ?></option>
@@ -580,32 +510,8 @@
580 510 </div>
581 511 <p class="mxch-field-description"><?php esc_html_e('Select the AI model used for generating images within your content.', 'mxchat'); ?></p>
582 512 </div>
583 513
584 - <!-- Image Quality (GPT Image only) -->
585 - <div class="mxch-field">
586 - <label class="mxch-field-label" for="mxch-image-quality"><?php esc_html_e('Image Quality', 'mxchat'); ?></label>
587 - <div class="mxch-field-control">
588 - <?php $image_quality = $options['content_image_quality'] ?? 'auto'; ?>
589 - <?php $quality_supported = (strpos($image_model, 'gpt-image') === 0); ?>
590 - <select id="mxch-image-quality" data-field="content_image_quality" class="mxch-cg-select"<?php echo $quality_supported ? '' : ' disabled'; ?>>
591 - <option value="auto" <?php selected($image_quality, 'auto'); ?>><?php esc_html_e('Auto (default)', 'mxchat'); ?></option>
592 - <option value="low" <?php selected($image_quality, 'low'); ?>><?php esc_html_e('Low (fastest, cheapest)', 'mxchat'); ?></option>
593 - <option value="medium" <?php selected($image_quality, 'medium'); ?>><?php esc_html_e('Medium', 'mxchat'); ?></option>
594 - <option value="high" <?php selected($image_quality, 'high'); ?>><?php esc_html_e('High (best, slowest)', 'mxchat'); ?></option>
595 - </select>
596 - </div>
597 - <p class="mxch-field-description"><?php esc_html_e('Quality control for OpenAI GPT Image models only. Grok Imagine and Gemini image models ignore this setting (their APIs do not expose an equivalent parameter).', 'mxchat'); ?></p>
598 - </div>
599 - <script>(function(){
600 - var m = document.getElementById('mxch-image-model');
601 - var q = document.getElementById('mxch-image-quality');
602 - if (!m || !q || q._wired) { return; } q._wired = true;
603 - function sync(){ q.disabled = (m.value || '').indexOf('gpt-image') !== 0; }
604 - m.addEventListener('change', sync);
605 - sync();
606 - })();</script>
607 -
608 514 <!-- Enable Image Generation -->
609 515 <div class="mxch-field">
610 516 <label class="mxch-toggle">
611 517 <?php $enable_images = $options['content_enable_images'] ?? 'on'; ?>
@@ -615,35 +521,8 @@
615 521 </label>
616 522 <p class="mxch-field-description"><?php esc_html_e('When enabled, AI will generate and place images throughout your content. When disabled, pages are generated with text-only layouts.', 'mxchat'); ?></p>
617 523 </div>
618 524
619 - <!-- Images per Article -->
620 - <div class="mxch-field">
621 - <label class="mxch-field-label" for="mxch-image-count"><?php esc_html_e('Images per Article', 'mxchat'); ?></label>
622 - <div class="mxch-field-control">
623 - <?php $image_count = max(1, min(5, (int) ($options['content_image_count'] ?? 3))); ?>
624 - <?php $images_on = ($options['content_enable_images'] ?? 'on') === 'on'; ?>
625 - <div class="mxch-cg-slider-row">
626 - <input type="range" min="1" max="5" step="1" value="<?php echo esc_attr($image_count); ?>"
627 - data-field="content_image_count" id="mxch-image-count" class="mxch-cg-slider"<?php echo $images_on ? '' : ' disabled'; ?>>
628 - <span id="mxch-image-count-val" class="mxch-cg-slider-value"><?php echo esc_html($image_count); ?></span>
629 - </div>
630 - </div>
631 - <p class="mxch-field-description"><?php esc_html_e('How many images to generate and place in each article (1–5). Default 3. The AI may generate fewer if the article has few sections suited to imagery.', 'mxchat'); ?></p>
632 - </div>
633 - <script>(function(){
634 - var s = document.getElementById('mxch-image-count');
635 - var v = document.getElementById('mxch-image-count-val');
636 - if (!s || !v || s._wired) { return; } s._wired = true;
637 - s.addEventListener('input', function(){ v.textContent = s.value; });
638 - var e = document.querySelector('[data-field="content_enable_images"]');
639 - if (e) {
640 - var syncCount = function(){ s.disabled = !e.checked; };
641 - e.addEventListener('change', syncCount);
642 - syncCount();
643 - }
644 - })();</script>
645 -
646 525 <!-- Internal Linking (Pro) -->
647 526 <div class="mxch-field mxch-cg-pro-field<?php echo $pro_internal_linking ? '' : ' mxch-cg-pro-locked'; ?>">
648 527 <label class="mxch-toggle">
649 528 <?php $internal_linking_val = $options['content_internal_linking'] ?? 'off'; ?>
@@ -691,29 +570,8 @@
691 570
692 571 </div>
693 572 </div>
694 573
695 - <!-- ── Editor Assistant (moved from Settings → Behavior, plan-f7df40) ── -->
696 - <div class="mxch-card">
697 - <div class="mxch-card-header">
698 - <h3 class="mxch-card-title">
699 - <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="M15 4V2"/><path d="M15 16v-2"/><path d="M8 9h2"/><path d="M20 9h2"/><path d="M17.8 11.8 19 13"/><path d="M15 9h.01"/><path d="M17.8 6.2 19 5"/><path d="m3 21 9-9"/><path d="M12.2 6.2 11 5"/></svg>
700 - <?php esc_html_e('Editor Assistant', 'mxchat'); ?>
701 - </h3>
702 - </div>
703 - <?php // mxchat-autosave-section: this toggle saves through the shared
704 - // settings transport (mxchat-admin.js + the ajax-handler's
705 - // mxchat_editor_assistant_enabled case), NOT the data-field
706 - // transport the rest of this tab uses — keep those apart. ?>
707 - <div class="mxch-card-body mxchat-autosave-section">
708 - <?php
709 - mxchat_render_field_wrapper('mxchat_editor_assistant_enabled', __('Editor Assistant', 'mxchat'), function() use ($admin_instance) {
710 - $admin_instance->mxchat_editor_assistant_toggle_callback();
711 - }, __('Add magic-wand AI writing actions (rewrite, summarize, translate, continue, fix grammar) to the WordPress block editor. Opens a sidebar in the post editor. Uses the chat AI model configured in MxChat Settings. Off by default.', 'mxchat'));
712 - ?>
713 - </div>
714 - </div>
715 -
716 574 <!-- ── SEO Settings ── -->
717 575 <div class="mxch-card" style="margin-top: 16px;">
718 576 <div class="mxch-card-header">
719 577 <h3 class="mxch-card-title"><?php esc_html_e('SEO', 'mxchat'); ?></h3>
@@ -727,9 +585,9 @@
727 585 <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"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18"/><path d="M9 21V9"/></svg>
728 586 <span><?php esc_html_e('Google Search Console', 'mxchat'); ?></span>
729 587 <span class="mxch-cg-pro-badge"><?php echo $is_activated ? esc_html__('ADD-ON', 'mxchat') : esc_html__('PRO', 'mxchat'); ?></span>
730 588 </div>
731 - <p class="mxch-field-description"><?php esc_html_e('Connect Google Search Console to see real search performance data — clicks, impressions, CTR, and keyword rankings — directly in your SEO dashboard. Chat with your GSC data using the AI Admin Assistant add-on.', 'mxchat'); ?></p>
589 + <p class="mxch-field-description"><?php esc_html_e('Connect Google Search Console to see real search performance data — clicks, impressions, CTR, and keyword rankings — directly in your SEO dashboard.', 'mxchat'); ?></p>
732 590 <button type="button" class="mxch-gsc-connect-btn" disabled>
733 591 <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"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
734 592 <?php esc_html_e('Connect Google Search Console', 'mxchat'); ?>
735 593 </button>
@@ -820,15 +678,8 @@
820 678 <select id="mxch-seod-post-type" class="mxch-seod-select">
821 679 <option value="any"><?php esc_html_e('All Types', 'mxchat'); ?></option>
822 680 <option value="post"><?php esc_html_e('Posts', 'mxchat'); ?></option>
823 681 <option value="page"><?php esc_html_e('Pages', 'mxchat'); ?></option>
824 - <?php
825 - $extra_types = get_post_types(array('public' => true, '_builtin' => false), 'objects');
826 - foreach ($extra_types as $pt) {
827 - if (in_array($pt->name, array('attachment', 'elementor_library', 'e-landing-page'), true)) continue;
828 - printf('<option value="%s">%s</option>', esc_attr($pt->name), esc_html($pt->labels->name));
829 - }
830 - ?>
831 682 </select>
832 683 <div class="mxch-seod-filter-pills">
833 684 <button type="button" class="mxch-seod-pill active" data-filter="all"><?php esc_html_e('All', 'mxchat'); ?></button>
834 685 <button type="button" class="mxch-seod-pill" data-filter="issues"><?php esc_html_e('Issues', 'mxchat'); ?></button>
@@ -836,22 +687,8 @@
836 687 <button type="button" class="mxch-seod-pill" data-filter="unscored"><?php esc_html_e('Not Scanned', 'mxchat'); ?></button>
837 688 </div>
838 689 </div>
839 690 <div class="mxch-seod-filters-right">
840 - <?php if (!$has_addon): ?>
841 - <span class="mxch-seod-bulk-note" id="mxch-seod-bulk-note" style="display:none;"><?php echo $is_activated ? esc_html__('Bulk optimize requires the Advanced Content Editor add-on', 'mxchat') : esc_html__('Bulk optimize requires MxChat Pro', 'mxchat'); ?></span>
842 - <?php endif; ?>
843 - <button type="button" class="mxch-seod-scan-btn mxch-seod-optimize-selected-btn<?php echo $has_addon ? '' : ' mxch-seod-bulk-locked'; ?>" id="mxch-seod-optimize-selected" style="display:none;"<?php echo $has_addon ? '' : ' disabled title="' . esc_attr__('Pro required for bulk optimization', 'mxchat') . '"'; ?>>
844 - <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"><path d="m12 3-1.9 5.8a2 2 0 0 1-1.287 1.288L3 12l5.8 1.9a2 2 0 0 1 1.288 1.287L12 21l1.9-5.8a2 2 0 0 1 1.287-1.288L21 12l-5.8-1.9a2 2 0 0 1-1.288-1.287Z"/></svg>
845 - <span><?php esc_html_e('Optimize Selected', 'mxchat'); ?></span>
846 - <?php if (!$has_addon): ?>
847 - <span class="mxch-cg-pro-badge"><?php echo $is_activated ? esc_html__('ADD-ON', 'mxchat') : esc_html__('PRO', 'mxchat'); ?></span>
848 - <?php endif; ?>
849 - </button>
850 - <button type="button" class="mxch-seod-scan-btn mxch-seod-scan-stop-btn" id="mxch-seod-optimize-stop" style="display:none;">
851 - <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"><rect x="6" y="6" width="12" height="12" rx="2"/></svg>
852 - <span><?php esc_html_e('Stop', 'mxchat'); ?></span>
853 - </button>
854 691 <div class="mxch-seod-search-wrap">
855 692 <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"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
856 693 <input type="text" id="mxch-seod-search" class="mxch-seod-search" placeholder="<?php esc_attr_e('Search posts...', 'mxchat'); ?>">
857 694 </div>
@@ -887,222 +724,8 @@
887 724 </div>
888 725 </div>
889 726 </div>
890 727 </div>
891 - </div>
892 -
893 - <!-- ========================================
894 - CALENDAR
895 - ======================================== -->
896 - <div id="content-calendar" class="mxch-section">
897 - <?php if ($pro_content_calendar) : ?>
898 - <!-- Add-on is active — container for calendar JS to populate -->
899 - <div class="mxcal-container" id="mxcal-container"></div>
900 - <?php else : ?>
901 - <!-- Add-on not installed — show blurred demo calendar -->
902 - <style>
903 - .mxcal-demo-wrap { position: relative; }
904 - .mxcal-demo-blur { filter: blur(3px); pointer-events: none; user-select: none; opacity: 0.7; }
905 - .mxcal-demo-overlay {
906 - position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
907 - z-index: 10; text-align: center; background: rgba(255,255,255,0.95);
908 - border-radius: 16px; padding: 40px 48px; box-shadow: 0 8px 40px rgba(120,115,245,0.15);
909 - border: 1px solid rgba(120,115,245,0.12); max-width: 460px; width: 90%;
910 - }
911 - .mxcal-demo-overlay h2 {
912 - font-size: 22px; font-weight: 700; margin: 0 0 8px; color: #1A202C;
913 - }
914 - .mxcal-demo-overlay p { font-size: 14px; color: #718096; line-height: 1.6; margin: 0 0 20px; }
915 - .mxcal-demo-overlay .mxcal-demo-badge {
916 - display: inline-block; background: linear-gradient(135deg, #fa73e6, #7873f5);
917 - color: #fff; font-size: 11px; font-weight: 700; padding: 4px 12px;
918 - border-radius: 20px; margin-bottom: 16px; letter-spacing: 0.5px;
919 - }
920 - .mxcal-demo-overlay a.mxcal-demo-btn {
921 - display: inline-block; background: linear-gradient(135deg, #fa73e6, #7873f5);
922 - color: #fff; font-size: 14px; font-weight: 600; padding: 12px 28px;
923 - border-radius: 10px; text-decoration: none; transition: all 0.2s;
924 - box-shadow: 0 4px 14px rgba(120,115,245,0.25);
925 - }
926 - .mxcal-demo-overlay a.mxcal-demo-btn:hover {
927 - box-shadow: 0 6px 20px rgba(120,115,245,0.35); transform: translateY(-1px);
928 - }
929 - .mxcal-demo-grid {
930 - display: grid; grid-template-columns: repeat(7, 1fr);
931 - border: 1px solid #E2E8F0; border-radius: 12px; overflow: hidden; background: #fff;
932 - }
933 - .mxcal-demo-hdr {
934 - background: #F7FAFC; padding: 10px 6px; text-align: center;
935 - font-size: 11px; font-weight: 600; color: #A0AEC0; text-transform: uppercase;
936 - border-bottom: 1px solid #E2E8F0;
937 - }
938 - .mxcal-demo-day {
939 - min-height: 90px; padding: 8px; border-right: 1px solid #F0F0F5;
940 - border-bottom: 1px solid #F0F0F5; display: flex; flex-direction: column; gap: 4px;
941 - }
942 - .mxcal-demo-day:nth-child(7n) { border-right: none; }
943 - .mxcal-demo-num { font-size: 12px; font-weight: 600; color: #A0AEC0; }
944 - .mxcal-demo-kw { font-size: 10px; font-weight: 600; color: #2D3748; line-height: 1.2; }
945 - .mxcal-demo-stats { display: flex; gap: 4px; margin-top: auto; }
946 - .mxcal-demo-vol { font-size: 9px; background: #EDF2F7; padding: 1px 5px; border-radius: 3px; color: #718096; }
947 - .mxcal-demo-kd { font-size: 9px; padding: 1px 5px; border-radius: 3px; font-weight: 700; }
948 - .mxcal-demo-easy { background: rgba(16,185,129,0.1); color: #059669; }
949 - .mxcal-demo-med { background: rgba(245,158,11,0.1); color: #d97706; }
950 - .mxcal-demo-hard { background: rgba(239,68,68,0.1); color: #dc2626; }
951 - .mxcal-demo-planned { border-left: 3px solid #CBD5E0; }
952 - .mxcal-demo-done { border-left: 3px solid #10b981; }
953 - .mxcal-demo-empty { background: #FAFAFA; }
954 - .mxcal-demo-header {
955 - display: flex; justify-content: space-between; align-items: center;
956 - margin-bottom: 16px; flex-wrap: wrap; gap: 12px;
957 - }
958 - .mxcal-demo-header h3 { font-size: 18px; font-weight: 700; color: #1A202C; margin: 0; }
959 - .mxcal-demo-month {
960 - display: flex; align-items: center; gap: 16px; justify-content: center; margin-bottom: 14px;
961 - }
962 - .mxcal-demo-month span { font-size: 16px; font-weight: 700; color: #2D3748; }
963 - .mxcal-demo-month-btn {
964 - background: none; border: 1px solid #E2E8F0; border-radius: 6px;
965 - padding: 4px 12px; font-size: 12px; color: #718096;
966 - }
967 - </style>
968 - <div class="mxcal-demo-wrap">
969 - <div class="mxcal-demo-blur">
970 - <div class="mxcal-demo-header">
971 - <h3>Content Calendar</h3>
972 - <div style="display:flex;gap:8px;">
973 - <span style="background:#EDF2F7;padding:4px 12px;border-radius:20px;font-size:12px;color:#4A5568;">mxchat.ai</span>
974 - <span style="background:linear-gradient(135deg,#fa73e6,#7873f5);padding:4px 12px;border-radius:20px;font-size:11px;color:#fff;font-weight:600;">AI Chatbot Plugin</span>
975 - </div>
976 - </div>
977 - <div class="mxcal-demo-month">
978 - <button class="mxcal-demo-month-btn">&larr;</button>
979 - <span><?php echo esc_html(wp_date('F Y')); ?></span>
980 - <button class="mxcal-demo-month-btn">&rarr;</button>
981 - </div>
982 - <div class="mxcal-demo-grid">
983 - <?php
984 - $days = array('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
985 - foreach ($days as $d) echo '<div class="mxcal-demo-hdr">' . $d . '</div>';
986 -
987 - $demo_posts = array(
988 - array('kw' => 'wordpress chatbot plugin', 'vol' => '2,400', 'kd' => 'KD 28', 'cls' => 'easy', 'st' => 'done'),
989 - array('kw' => 'ai customer support', 'vol' => '1,900', 'kd' => 'KD 35', 'cls' => 'med', 'st' => 'done'),
990 - array('kw' => 'chatbot for ecommerce', 'vol' => '1,600', 'kd' => 'KD 22', 'cls' => 'easy', 'st' => 'done'),
991 - array('kw' => 'gpt wordpress integration', 'vol' => '1,100', 'kd' => 'KD 41', 'cls' => 'med', 'st' => 'planned'),
992 - array('kw' => 'live chat vs chatbot', 'vol' => '3,200', 'kd' => 'KD 18', 'cls' => 'easy', 'st' => 'planned'),
993 - array('kw' => 'ai lead generation', 'vol' => '2,800', 'kd' => 'KD 52', 'cls' => 'med', 'st' => 'planned'),
994 - array('kw' => 'reduce support tickets ai', 'vol' => '880', 'kd' => 'KD 15', 'cls' => 'easy', 'st' => 'planned'),
995 - array('kw' => 'best chatbot plugins 2026', 'vol' => '4,100', 'kd' => 'KD 62', 'cls' => 'hard', 'st' => 'planned'),
996 - array('kw' => 'woocommerce chatbot', 'vol' => '1,400', 'kd' => 'KD 30', 'cls' => 'med', 'st' => 'planned'),
997 - array('kw' => 'automate faq wordpress', 'vol' => '720', 'kd' => 'KD 12', 'cls' => 'easy', 'st' => 'planned'),
998 - array('kw' => 'claude vs chatgpt wordpress', 'vol' => '2,100', 'kd' => 'KD 38', 'cls' => 'med', 'st' => 'planned'),
999 - array('kw' => 'ai content generation', 'vol' => '5,400', 'kd' => 'KD 68', 'cls' => 'hard', 'st' => 'planned'),
1000 - );
1001 -
1002 - $first_day = (int) wp_date('w', strtotime('first day of this month'));
1003 - $days_in_month = (int) wp_date('t');
1004 - $post_idx = 0;
1005 -
1006 - for ($i = 0; $i < $first_day; $i++) echo '<div class="mxcal-demo-day mxcal-demo-empty"></div>';
1007 -
1008 - for ($d = 1; $d <= $days_in_month; $d++) {
1009 - if ($post_idx < count($demo_posts)) {
1010 - $p = $demo_posts[$post_idx];
1011 - $st_cls = $p['st'] === 'done' ? 'mxcal-demo-done' : 'mxcal-demo-planned';
1012 - echo '<div class="mxcal-demo-day ' . $st_cls . '">';
1013 - echo '<span class="mxcal-demo-num">' . $d . '</span>';
1014 - echo '<span class="mxcal-demo-kw">' . esc_html($p['kw']) . '</span>';
1015 - echo '<div class="mxcal-demo-stats">';
1016 - echo '<span class="mxcal-demo-vol">' . $p['vol'] . '</span>';
1017 - echo '<span class="mxcal-demo-kd mxcal-demo-' . $p['cls'] . '">' . $p['kd'] . '</span>';
1018 - echo '</div></div>';
1019 - $post_idx++;
1020 - } else {
1021 - echo '<div class="mxcal-demo-day mxcal-demo-empty"><span class="mxcal-demo-num">' . $d . '</span></div>';
1022 - }
1023 - }
1024 -
1025 - $total = $first_day + $days_in_month;
1026 - $remaining = $total % 7 === 0 ? 0 : 7 - ($total % 7);
1027 - for ($i = 0; $i < $remaining; $i++) echo '<div class="mxcal-demo-day mxcal-demo-empty"></div>';
1028 - ?>
1029 - </div>
1030 - </div>
1031 - <div class="mxcal-demo-overlay">
1032 - <span class="mxcal-demo-badge">PRO ADD-ON</span>
1033 - <h2>AI Content Calendar</h2>
1034 - <p>Import SEO data and let AI generate a 30-day blog plan with targeted keywords, difficulty scores, and automated post scheduling.</p>
1035 - <a href="https://mxchat.ai/advanced-content-editor/" target="_blank" class="mxcal-demo-btn">Get Advanced Content Editor</a>
1036 - </div>
1037 - </div>
1038 - <?php endif; ?>
1039 - </div>
1040 -
1041 - <!-- ========================================
1042 - TEMPLATES
1043 - ======================================== -->
1044 - <div id="content-templates" class="mxch-section">
1045 - <?php if ($pro_template_generator) : ?>
1046 - <div id="mxtpl-container"></div>
1047 - <?php else : ?>
1048 - <style>
1049 - .mxtpl-demo-wrap { position: relative; }
1050 - .mxtpl-demo-blur { filter: blur(3px); pointer-events: none; user-select: none; opacity: 0.7; padding: 24px; }
1051 - .mxtpl-demo-overlay {
1052 - position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
1053 - z-index: 10; text-align: center; background: rgba(255,255,255,0.95);
1054 - border-radius: 16px; padding: 40px 48px; box-shadow: 0 8px 40px rgba(120,115,245,0.15);
1055 - border: 1px solid rgba(120,115,245,0.12); max-width: 460px; width: 90%;
1056 - }
1057 - .mxtpl-demo-overlay h2 { font-size: 22px; font-weight: 700; margin: 0 0 8px; color: #1A202C; }
1058 - .mxtpl-demo-overlay p { font-size: 14px; color: #718096; line-height: 1.6; margin: 0 0 20px; }
1059 - .mxtpl-demo-badge { display: inline-block; background: linear-gradient(135deg, #fa73e6, #7873f5); color: #fff; font-size: 11px; font-weight: 700; padding: 4px 12px; border-radius: 20px; margin-bottom: 16px; letter-spacing: 0.5px; }
1060 - .mxtpl-demo-btn { display: inline-block; background: linear-gradient(135deg, #fa73e6, #7873f5); color: #fff; font-size: 14px; font-weight: 600; padding: 12px 28px; border-radius: 10px; text-decoration: none; box-shadow: 0 4px 14px rgba(120,115,245,0.25); }
1061 - .mxtpl-demo-section { margin-bottom: 20px; }
1062 - .mxtpl-demo-label { font-size: 14px; font-weight: 700; color: #2D3748; margin-bottom: 8px; }
1063 - .mxtpl-demo-textarea { width: 100%; padding: 12px; border: 2px solid #E2E8F0; border-radius: 8px; font-size: 13px; color: #4A5568; background: #F7FAFC; resize: none; font-family: inherit; }
1064 - .mxtpl-demo-pills { display: flex; gap: 6px; margin-bottom: 12px; flex-wrap: wrap; }
1065 - .mxtpl-demo-pill { background: rgba(120,115,245,0.08); color: #7873f5; padding: 3px 10px; border-radius: 20px; font-size: 11px; font-weight: 600; font-family: monospace; }
1066 - .mxtpl-demo-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; }
1067 - .mxtpl-demo-field { display: flex; flex-direction: column; gap: 4px; }
1068 - .mxtpl-demo-field label { font-size: 12px; font-weight: 600; color: #718096; }
1069 - .mxtpl-demo-field select, .mxtpl-demo-field input { padding: 8px 10px; border: 2px solid #E2E8F0; border-radius: 6px; font-size: 13px; background: #F7FAFC; }
1070 - </style>
1071 - <div class="mxtpl-demo-wrap">
1072 - <div class="mxtpl-demo-blur">
1073 - <div class="mxtpl-demo-section">
1074 - <div class="mxtpl-demo-label">1. Upload Data</div>
1075 - <button style="padding:8px 18px;border:1px solid #E2E8F0;border-radius:8px;background:#F7FAFC;color:#718096;font-size:13px;cursor:default;">Upload CSV</button>
1076 - <span style="font-size:12px;color:#10b981;margin-left:8px;">24 rows loaded</span>
1077 - </div>
1078 - <div class="mxtpl-demo-section">
1079 - <div class="mxtpl-demo-label">2. Content Source</div>
1080 - <div class="mxtpl-demo-pills">
1081 - <span class="mxtpl-demo-pill">{city}</span>
1082 - <span class="mxtpl-demo-pill">{state}</span>
1083 - <span class="mxtpl-demo-pill">{service}</span>
1084 - <span class="mxtpl-demo-pill">{phone}</span>
1085 - </div>
1086 - <textarea class="mxtpl-demo-textarea" rows="3" readonly>Write a {comprehensive|detailed|in-depth} service page about {service} in {city}, {state}. Highlight our expertise and include a call to action with {phone}.</textarea>
1087 - </div>
1088 - <div class="mxtpl-demo-section">
1089 - <div class="mxtpl-demo-label">3. Settings</div>
1090 - <div class="mxtpl-demo-grid">
1091 - <div class="mxtpl-demo-field"><label>Content Type</label><select><option>Page</option></select></div>
1092 - <div class="mxtpl-demo-field"><label>Status</label><select><option>Draft</option></select></div>
1093 - <div class="mxtpl-demo-field"><label>Slug Template</label><input type="text" value="{service}-in-{city}" readonly /></div>
1094 - </div>
1095 - </div>
1096 - </div>
1097 - <div class="mxtpl-demo-overlay">
1098 - <span class="mxtpl-demo-badge">PRO ADD-ON</span>
1099 - <h2>Spintax & Template Generator</h2>
1100 - <p>Generate bulk pages from CSV data with spintax variations. Create hundreds of unique, AI-written city pages, service pages, and landing pages.</p>
1101 - <a href="https://mxchat.ai/advanced-content-editor/" target="_blank" class="mxtpl-demo-btn">Get Advanced Content Editor</a>
1102 - </div>
1103 - </div>
1104 - <?php endif; ?>
1105 728 </div>
1106 729
1107 730 </main>
1108 731 </div>