PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 3.2.25
MxChat – AI Chatbot & Content Generation for WordPress v3.2.25
3.2.25 3.2.24 3.2.23 3.2.22 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 All 156 releases
← All changes | includes/admin-transcripts-page.php +341 -2 3.2.1 → 3.2.25 View file →
@@ -60,8 +60,12 @@
60 60 <button class="mxch-mobile-nav-link" data-target="all-chats">
61 61 <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 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
62 62 <span><?php esc_html_e('All Chats', 'mxchat'); ?></span>
63 63 </button>
64 + <button class="mxch-mobile-nav-link" data-target="leads">
65 + <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="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><polyline points="17 11 19 13 23 9"/></svg>
66 + <span><?php esc_html_e('Leads', 'mxchat'); ?></span>
67 + </button>
64 68 </div>
65 69 <!-- Settings Section -->
66 70 <div class="mxch-mobile-nav-section">
67 71 <div class="mxch-mobile-nav-section-title"><?php esc_html_e('Settings', 'mxchat'); ?></div>
@@ -120,8 +124,18 @@
120 124 <span class="mxch-nav-link-text"><?php esc_html_e('All Chats', 'mxchat'); ?></span>
121 125 <span class="mxch-nav-link-badge"><?php echo esc_html($total_chats); ?></span>
122 126 </button>
123 127 </div>
128 +
129 + <div class="mxch-nav-item" data-section="leads">
130 + <button class="mxch-nav-link" data-target="leads">
131 + <span class="mxch-nav-link-icon">
132 + <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="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><polyline points="17 11 19 13 23 9"/></svg>
133 + </span>
134 + <span class="mxch-nav-link-text"><?php esc_html_e('Leads', 'mxchat'); ?></span>
135 + <span class="mxch-nav-link-badge" id="mxch-leads-nav-badge" style="display:none;">0</span>
136 + </button>
137 + </div>
124 138 </div>
125 139
126 140 <!-- Settings Section -->
127 141 <div class="mxch-nav-section">
@@ -307,8 +321,65 @@
307 321 </div>
308 322 </div>
309 323 </div>
310 324
325 + <!-- Satisfaction (last 30 days) — plan-a5b006 -->
326 + <div class="mxch-card mxch-satisfaction-card">
327 + <div class="mxch-card-header">
328 + <h3 class="mxch-card-title">
329 + <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="M7 10v12"/><path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H7"/><path d="M3 10h4"/></svg>
330 + <?php esc_html_e('Satisfaction (last 30 days)', 'mxchat'); ?>
331 + </h3>
332 + </div>
333 + <div class="mxch-card-body">
334 + <?php
335 + $satisfaction_stats = isset($satisfaction_stats) && is_array($satisfaction_stats) ? $satisfaction_stats : array();
336 + if (empty($satisfaction_stats)) :
337 + ?>
338 + <p class="mxch-satisfaction-empty">
339 + <?php esc_html_e('No ratings yet. The widget shows the prompt after a conversation has had at least two bot replies and the visitor goes idle for 60 seconds.', 'mxchat'); ?>
340 + </p>
341 + <?php
342 + else :
343 + ?>
344 + <ul class="mxch-satisfaction-list">
345 + <?php foreach ($satisfaction_stats as $row) :
346 + $bot_label = $row['bot_id'] === 'default'
347 + ? esc_html__('Default bot', 'mxchat')
348 + : esc_html($row['bot_id']);
349 + ?>
350 + <li class="mxch-satisfaction-row">
351 + <span class="mxch-satisfaction-bot"><?php echo $bot_label; ?></span>
352 + <span class="mxch-satisfaction-meta">
353 + <span class="mxch-satisfaction-total"><?php
354 + echo esc_html(sprintf(
355 + /* translators: %d: number of rated sessions */
356 + _n('%d rated session', '%d rated sessions', $row['total'], 'mxchat'),
357 + $row['total']
358 + ));
359 + ?></span>
360 + <span class="mxch-satisfaction-bar" aria-hidden="true">
361 + <span class="mxch-satisfaction-bar-up" style="width: <?php echo esc_attr($row['positive_pct']); ?>%;"></span>
362 + <span class="mxch-satisfaction-bar-down" style="width: <?php echo esc_attr($row['negative_pct']); ?>%;"></span>
363 + </span>
364 + <span class="mxch-satisfaction-pct mxch-satisfaction-pct-up" title="<?php esc_attr_e('Positive ratings', 'mxchat'); ?>">
365 + <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 10v12"/><path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H7"/><path d="M3 10h4"/></svg>
366 + <?php echo esc_html($row['positive_pct']); ?>%
367 + </span>
368 + <span class="mxch-satisfaction-pct mxch-satisfaction-pct-down" title="<?php esc_attr_e('Negative ratings', 'mxchat'); ?>">
369 + <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 14V2"/><path d="M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H17"/><path d="M21 14h-4"/></svg>
370 + <?php echo esc_html($row['negative_pct']); ?>%
371 + </span>
372 + </span>
373 + </li>
374 + <?php endforeach; ?>
375 + </ul>
376 + <?php
377 + endif;
378 + ?>
379 + </div>
380 + </div>
381 +
311 382 <!-- Activity Chart -->
312 383 <div class="mxch-card mxch-activity-chart-card">
313 384 <div class="mxch-card-header">
314 385 <h3 class="mxch-card-title">
@@ -459,8 +530,12 @@
459 530 <div class="mxch-detail-row" id="mxch-detail-email-row" style="display: none;">
460 531 <span class="mxch-detail-label"><?php esc_html_e('Email', 'mxchat'); ?></span>
461 532 <span class="mxch-detail-value" id="mxch-detail-email">-</span>
462 533 </div>
534 + <div class="mxch-detail-row" id="mxch-detail-feedback-row" style="display: none;">
535 + <span class="mxch-detail-label"><?php esc_html_e('Feedback', 'mxchat'); ?></span>
536 + <span class="mxch-detail-value mxch-detail-feedback-value" id="mxch-detail-feedback">-</span>
537 + </div>
463 538 </div>
464 539 <div class="mxch-details-section" id="mxch-clicked-section" style="display: none;">
465 540 <h4><?php esc_html_e('Clicked Links', 'mxchat'); ?></h4>
466 541 <div class="mxch-clicked-links" id="mxch-clicked-links">
@@ -521,10 +596,204 @@
521 596 </div>
522 597 </div>
523 598
524 599 <?php wp_nonce_field('mxchat_delete_chat_history', 'mxchat_delete_chat_nonce'); ?>
600 +
601 + <!-- Transcript delete confirm modal (shared by bulk + individual delete) -->
602 + <div id="mxch-transcript-confirm" class="mxch-modal-overlay" style="display:none;">
603 + <div class="mxch-modal-content mxch-leads-confirm-box">
604 + <div class="mxch-modal-header">
605 + <h2 id="mxch-transcript-confirm-title"><?php esc_html_e('Delete conversation?', 'mxchat'); ?></h2>
606 + <button type="button" class="mxch-modal-close" data-mxch-transcript-close>&times;</button>
607 + </div>
608 + <div class="mxch-modal-body">
609 + <p id="mxch-transcript-confirm-body"></p>
610 + <label class="mxch-transcript-confirm-check">
611 + <input type="checkbox" id="mxch-transcript-also-delete-lead">
612 + <span>
613 + <strong><?php esc_html_e('Also remove the lead from the Leads tab', 'mxchat'); ?></strong>
614 + <em class="mxch-transcript-confirm-sublabel"><?php esc_html_e('By default, leads are kept and marked "Chat deleted" so your contact list is preserved.', 'mxchat'); ?></em>
615 + </span>
616 + </label>
617 + <p class="mxch-leads-confirm-warning"><?php esc_html_e('This cannot be undone.', 'mxchat'); ?></p>
618 + </div>
619 + <div class="mxch-leads-confirm-actions">
620 + <button type="button" class="mxch-btn mxch-btn-secondary" data-mxch-transcript-close><?php esc_html_e('Cancel', 'mxchat'); ?></button>
621 + <button type="button" class="mxch-btn mxch-btn-danger" id="mxch-transcript-confirm-go"><?php esc_html_e('Delete', 'mxchat'); ?></button>
622 + </div>
623 + </div>
624 + </div>
525 625 </div>
526 626
627 + <!-- Leads Section -->
628 + <div id="leads" class="mxch-section">
629 + <div class="mxch-content-header">
630 + <h1 class="mxch-content-title"><?php esc_html_e('Leads', 'mxchat'); ?></h1>
631 + <p class="mxch-content-subtitle"><?php esc_html_e('Captured visitor emails and names from the lead-capture form, grouped by unique lead.', 'mxchat'); ?></p>
632 + </div>
633 +
634 + <!-- Stats strip -->
635 + <div class="mxch-leads-stats">
636 + <div class="mxch-stat-card">
637 + <div class="mxch-stat-icon mxch-stat-icon-primary">
638 + <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="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
639 + </div>
640 + <div class="mxch-stat-content">
641 + <span class="mxch-stat-value" id="mxch-leads-stat-total">0</span>
642 + <span class="mxch-stat-label"><?php esc_html_e('Total Leads', 'mxchat'); ?></span>
643 + </div>
644 + </div>
645 + <div class="mxch-stat-card">
646 + <div class="mxch-stat-icon mxch-stat-icon-success">
647 + <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"><polyline points="23 6 13.5 15.5 8.5 10.5 1 18"/><polyline points="17 6 23 6 23 12"/></svg>
648 + </div>
649 + <div class="mxch-stat-content">
650 + <span class="mxch-stat-value" id="mxch-leads-stat-new">0</span>
651 + <span class="mxch-stat-label"><?php esc_html_e('New This Week', 'mxchat'); ?></span>
652 + </div>
653 + </div>
654 + <div class="mxch-stat-card">
655 + <div class="mxch-stat-icon mxch-stat-icon-info">
656 + <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 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
657 + </div>
658 + <div class="mxch-stat-content">
659 + <span class="mxch-stat-value" id="mxch-leads-stat-avg">0</span>
660 + <span class="mxch-stat-label"><?php esc_html_e('Avg Convos / Lead', 'mxchat'); ?></span>
661 + </div>
662 + </div>
663 + <div class="mxch-stat-card">
664 + <div class="mxch-stat-icon mxch-stat-icon-warning">
665 + <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="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
666 + </div>
667 + <div class="mxch-stat-content">
668 + <span class="mxch-stat-value" id="mxch-leads-stat-orphan">0%</span>
669 + <span class="mxch-stat-label"><?php esc_html_e('Orphan Leads', 'mxchat'); ?></span>
670 + <span class="mxch-stat-sublabel" id="mxch-leads-stat-orphan-sub"><?php esc_html_e('Captured but never chatted', 'mxchat'); ?></span>
671 + </div>
672 + </div>
673 + </div>
674 +
675 + <!-- Top pages card -->
676 + <div class="mxch-card mxch-leads-toppages">
677 + <div class="mxch-card-header">
678 + <h3 class="mxch-card-title">
679 + <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="M3 3h18v18H3z"/><path d="M3 9h18"/><path d="M9 21V9"/></svg>
680 + <?php esc_html_e('Top Pages Capturing Leads', 'mxchat'); ?>
681 + </h3>
682 + <span class="mxch-leads-toppages-hint"><?php esc_html_e('Click a page to filter the list below', 'mxchat'); ?></span>
683 + </div>
684 + <div class="mxch-card-body">
685 + <div class="mxch-leads-toppages-list" id="mxch-leads-toppages-list">
686 + <div class="mxch-leads-empty-mini"><?php esc_html_e('No page data yet.', 'mxchat'); ?></div>
687 + </div>
688 + </div>
689 + </div>
690 +
691 + <!-- Leads toolbar + table -->
692 + <div class="mxch-card mxch-leads-card">
693 + <div class="mxch-leads-toolbar">
694 + <div class="mxch-leads-toolbar-left">
695 + <label class="mxch-bulk-select-all">
696 + <input type="checkbox" id="mxch-leads-select-all">
697 + <span><?php esc_html_e('All', 'mxchat'); ?></span>
698 + </label>
699 + <span class="mxch-selected-count" id="mxch-leads-selected-count">0</span>
700 + <button type="button" class="mxch-bulk-btn mxch-bulk-delete" id="mxch-leads-delete-selected" disabled title="<?php esc_attr_e('Delete Selected', 'mxchat'); ?>">
701 + <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"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
702 + <span><?php esc_html_e('Delete', 'mxchat'); ?></span>
703 + </button>
704 + </div>
705 + <div class="mxch-leads-toolbar-right">
706 + <div class="mxch-leads-export" id="mxch-leads-export-wrap">
707 + <button type="button" class="mxch-btn mxch-btn-secondary mxch-btn-sm" id="mxch-leads-export-btn">
708 + <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="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
709 + <?php esc_html_e('Export', 'mxchat'); ?>
710 + <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" 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"/></svg>
711 + </button>
712 + <div class="mxch-leads-export-menu" id="mxch-leads-export-menu">
713 + <button type="button" data-fields="email_and_name" data-scope="all"><?php esc_html_e('All leads — email + name', 'mxchat'); ?></button>
714 + <button type="button" data-fields="email_only" data-scope="all"><?php esc_html_e('All leads — email only', 'mxchat'); ?></button>
715 + <button type="button" data-fields="email_and_name" data-scope="selected" disabled><?php esc_html_e('Selected — email + name', 'mxchat'); ?></button>
716 + <button type="button" data-fields="email_only" data-scope="selected" disabled><?php esc_html_e('Selected — email only', 'mxchat'); ?></button>
717 + </div>
718 + </div>
719 + </div>
720 + </div>
721 +
722 + <div class="mxch-leads-filters">
723 + <div class="mxch-search-wrapper">
724 + <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"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
725 + <input type="text" id="mxch-leads-search" class="mxch-search-input" placeholder="<?php esc_attr_e('Search by email or name...', 'mxchat'); ?>">
726 + </div>
727 + <select id="mxch-leads-date-range" class="mxch-select">
728 + <option value="all"><?php esc_html_e('All time', 'mxchat'); ?></option>
729 + <option value="today"><?php esc_html_e('Last 24 hours', 'mxchat'); ?></option>
730 + <option value="7d"><?php esc_html_e('Last 7 days', 'mxchat'); ?></option>
731 + <option value="30d"><?php esc_html_e('Last 30 days', 'mxchat'); ?></option>
732 + <option value="90d"><?php esc_html_e('Last 90 days', 'mxchat'); ?></option>
733 + </select>
734 + <select id="mxch-leads-status" class="mxch-select">
735 + <option value="all"><?php esc_html_e('All leads', 'mxchat'); ?></option>
736 + <option value="with"><?php esc_html_e('With conversation', 'mxchat'); ?></option>
737 + <option value="chat_deleted"><?php esc_html_e('Chat deleted', 'mxchat'); ?></option>
738 + <option value="orphan"><?php esc_html_e('Orphan (no chat)', 'mxchat'); ?></option>
739 + </select>
740 + <button type="button" class="mxch-btn mxch-btn-ghost mxch-btn-sm" id="mxch-leads-clear-filters" style="display:none;">
741 + <?php esc_html_e('Clear filters', 'mxchat'); ?>
742 + </button>
743 + <span class="mxch-leads-active-page-filter" id="mxch-leads-active-page-filter" style="display:none;">
744 + <span class="mxch-leads-page-chip-label"></span>
745 + <button type="button" class="mxch-leads-page-chip-remove" aria-label="<?php esc_attr_e('Remove page filter', 'mxchat'); ?>">&times;</button>
746 + </span>
747 + </div>
748 +
749 + <div class="mxch-leads-table-wrap">
750 + <table class="mxch-leads-table" id="mxch-leads-table">
751 + <thead>
752 + <tr>
753 + <th class="mxch-leads-col-check"></th>
754 + <th class="mxch-leads-col-lead"><?php esc_html_e('Lead', 'mxchat'); ?></th>
755 + <th class="mxch-leads-col-count"><?php esc_html_e('Conversations', 'mxchat'); ?></th>
756 + <th class="mxch-leads-col-last"><?php esc_html_e('Last seen', 'mxchat'); ?></th>
757 + <th class="mxch-leads-col-page"><?php esc_html_e('Top page', 'mxchat'); ?></th>
758 + <th class="mxch-leads-col-consent"><?php esc_html_e('Consent', 'mxchat'); ?></th>
759 + <th class="mxch-leads-col-actions"></th>
760 + </tr>
761 + </thead>
762 + <tbody id="mxch-leads-tbody">
763 + <tr><td colspan="7" class="mxch-leads-loading"><span class="spinner is-active"></span></td></tr>
764 + </tbody>
765 + </table>
766 + </div>
767 +
768 + <div class="mxch-panel-footer">
769 + <span class="mxch-leads-count" id="mxch-leads-count">0 leads</span>
770 + <div class="mxch-pagination-simple" id="mxch-leads-pagination"></div>
771 + </div>
772 + </div>
773 +
774 + <!-- Delete confirm modal -->
775 + <div id="mxch-leads-confirm" class="mxch-modal-overlay" style="display:none;">
776 + <div class="mxch-modal-content mxch-leads-confirm-box">
777 + <div class="mxch-modal-header">
778 + <h2><?php esc_html_e('Delete leads', 'mxchat'); ?></h2>
779 + <button type="button" class="mxch-modal-close" data-mxch-leads-close>&times;</button>
780 + </div>
781 + <div class="mxch-modal-body">
782 + <p id="mxch-leads-confirm-body"></p>
783 + <p class="mxch-leads-confirm-warning"><?php esc_html_e('This cannot be undone.', 'mxchat'); ?></p>
784 + </div>
785 + <div class="mxch-leads-confirm-actions">
786 + <button type="button" class="mxch-btn mxch-btn-secondary" data-mxch-leads-close><?php esc_html_e('Cancel', 'mxchat'); ?></button>
787 + <button type="button" class="mxch-btn mxch-btn-danger" id="mxch-leads-confirm-go"><?php esc_html_e('Delete permanently', 'mxchat'); ?></button>
788 + </div>
789 + </div>
790 + </div>
791 +
792 + <?php wp_nonce_field('mxchat_delete_leads', 'mxchat_leads_delete_nonce'); ?>
793 + <?php wp_nonce_field('mxchat_export_leads', 'mxchat_leads_export_nonce'); ?>
794 + </div>
795 +
527 796 <!-- Notifications Section -->
528 797 <div id="notifications" class="mxch-section">
529 798 <div class="mxch-content-header">
530 799 <h1 class="mxch-content-title"><?php esc_html_e('Notification Settings', 'mxchat'); ?></h1>
@@ -564,14 +833,15 @@
564 833 </div>
565 834
566 835 <div class="mxch-field">
567 836 <label class="mxch-field-label"><?php esc_html_e('Notification Email', 'mxchat'); ?></label>
568 - <input type="email"
837 + <?php /* type="text", not "email": the browser rejects a comma-separated list outright (plan 2f131a). Validation is server-side in MxChat_Utils. */ ?>
838 + <input type="text"
569 839 name="mxchat_transcripts_options[mxchat_notification_email]"
570 840 class="mxch-input mxchat-autosave-field"
571 841 value="<?php echo esc_attr($email); ?>"
572 842 data-nonce="<?php echo wp_create_nonce('mxchat_autosave_nonce'); ?>">
573 - <p class="mxch-field-description"><?php esc_html_e('Email address where notifications will be sent.', 'mxchat'); ?></p>
843 + <p class="mxch-field-description"><?php printf(esc_html__('Email address where notifications will be sent. Separate up to %d addresses with commas. Defaults to the site admin email.', 'mxchat'), (int) MxChat_Utils::NOTIFICATION_EMAIL_MAX); ?></p>
574 844 </div>
575 845 </div>
576 846 </div>
577 847
@@ -643,8 +913,9 @@
643 913 </div>
644 914 <div class="mxch-card-body">
645 915 <?php
646 916 $auto_delete = isset($options['mxchat_auto_delete_transcripts']) ? $options['mxchat_auto_delete_transcripts'] : 'never';
917 + $mxch_custom_retention = isset($options['mxchat_retention_days']) ? (int) $options['mxchat_retention_days'] : 0;
647 918 ?>
648 919 <div class="mxch-field">
649 920 <label class="mxch-field-label"><?php esc_html_e('Auto-Delete Old Transcripts', 'mxchat'); ?></label>
650 921 <select name="mxchat_transcripts_options[mxchat_auto_delete_transcripts]"
@@ -655,8 +926,76 @@
655 926 <option value="2weeks" <?php selected($auto_delete, '2weeks'); ?>><?php esc_html_e('After 2 Weeks', 'mxchat'); ?></option>
656 927 <option value="1month" <?php selected($auto_delete, '1month'); ?>><?php esc_html_e('After 1 Month', 'mxchat'); ?></option>
657 928 </select>
658 929 <p class="mxch-field-description"><?php esc_html_e('Automatically delete old chat transcripts to manage database size and privacy.', 'mxchat'); ?></p>
930 + <?php if ($mxch_custom_retention > 0) : ?>
931 + <p class="mxch-field-description" id="mxchat-retention-override-note">
932 + <strong><?php
933 + printf(
934 + /* translators: %d: the custom retention value in days */
935 + esc_html__('Overridden by Custom Retention below: transcripts are deleted after %d days.', 'mxchat'),
936 + $mxch_custom_retention
937 + );
938 + ?></strong>
939 + </p>
940 + <?php endif; ?>
941 + <?php
942 + // Surface the cron's real state next to the setting that
943 + // depends on it (plan-bc08a6): a configured retention whose
944 + // cleanup event is missing was previously invisible.
945 + $mxch_retention_days = isset($options['mxchat_retention_days']) ? (int) $options['mxchat_retention_days'] : 0;
946 + if ($auto_delete !== 'never' || $mxch_retention_days > 0) :
947 + $mxch_next_cleanup = wp_next_scheduled('mxchat_cleanup_old_transcripts');
948 + ?>
949 + <p class="mxch-field-description" id="mxchat-next-cleanup-status">
950 + <?php
951 + if ($mxch_next_cleanup) {
952 + printf(
953 + /* translators: %s: localized date and time of the next scheduled transcript cleanup */
954 + esc_html__('Next cleanup: %s', 'mxchat'),
955 + esc_html(wp_date(get_option('date_format') . ' ' . get_option('time_format'), $mxch_next_cleanup))
956 + );
957 + } else {
958 + esc_html_e('Next cleanup: not currently scheduled.', 'mxchat');
959 + }
960 + ?>
961 + </p>
962 + <?php endif; ?>
963 + </div>
964 +
965 + <div class="mxch-field">
966 + <label class="mxch-field-label" for="mxchat_retention_days"><?php esc_html_e('Custom Retention (Days)', 'mxchat'); ?></label>
967 + <input type="number"
968 + id="mxchat_retention_days"
969 + name="mxchat_transcripts_options[mxchat_retention_days]"
970 + class="mxch-input mxchat-autosave-field"
971 + value="<?php echo esc_attr($mxch_custom_retention); ?>"
972 + min="0"
973 + max="3650"
974 + step="1"
975 + data-nonce="<?php echo wp_create_nonce('mxchat_autosave_nonce'); ?>">
976 + <p class="mxch-field-description"><?php esc_html_e('Delete transcripts older than this many days (1&ndash;3650). When greater than 0 this overrides the dropdown above; set 0 to use the dropdown. Developers can adjust the final value with the mxchat_transcript_retention_days filter.', 'mxchat'); ?></p>
977 + </div>
978 + </div>
979 + </div>
980 +
981 + <!-- Privacy & Data Requests Card (plan b81e42) -->
982 + <div class="mxch-card">
983 + <div class="mxch-card-header">
984 + <h3 class="mxch-card-title">
985 + <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 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
986 + <?php esc_html_e('Privacy & Data Requests', 'mxchat'); ?>
987 + </h3>
988 + </div>
989 + <div class="mxch-card-body">
990 + <div class="mxch-field">
991 + <p class="mxch-field-description">
992 + <?php esc_html_e('Chat conversations — including captured emails, names, and visitor identifiers — are registered with WordPress\'s built-in privacy tools. When you run a personal data export or erasure request from the Tools menu, MxChat data is included automatically, so honouring a GDPR or CCPA request covers the chatbot with no extra steps.', 'mxchat'); ?>
993 + </p>
994 + <p>
995 + <a href="<?php echo esc_url(admin_url('export-personal-data.php')); ?>" class="mxch-btn mxch-btn-secondary mxch-btn-sm"><?php esc_html_e('Export Personal Data', 'mxchat'); ?></a>
996 + <a href="<?php echo esc_url(admin_url('erase-personal-data.php')); ?>" class="mxch-btn mxch-btn-secondary mxch-btn-sm"><?php esc_html_e('Erase Personal Data', 'mxchat'); ?></a>
997 + </p>
659 998 </div>
660 999 </div>
661 1000 </div>
662 1001 </div>