Restore to commit 74e578279624c6045ca440a3459ebfa1f8d54191
This commit is contained in:
221
chat/templates/FAQ Manager/admin/class-pc-faq-manager-admin.php
Normal file
221
chat/templates/FAQ Manager/admin/class-pc-faq-manager-admin.php
Normal file
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
/**
|
||||
* FAQ Manager Admin Interface
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class PC_FAQ_Manager_Admin {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action('admin_menu', array($this, 'add_admin_menu'));
|
||||
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
|
||||
add_action('wp_ajax_pc_faq_reorder', array($this, 'handle_ajax_reorder'));
|
||||
add_action('wp_ajax_pc_faq_add_new', array($this, 'handle_ajax_add_new'));
|
||||
add_action('wp_ajax_pc_faq_edit', array($this, 'handle_ajax_edit'));
|
||||
add_action('wp_ajax_pc_faq_delete', array($this, 'handle_ajax_delete'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add admin menu
|
||||
*/
|
||||
public function add_admin_menu() {
|
||||
add_menu_page(
|
||||
__('FAQ Manager', PC_FAQ_MANAGER_SLUG),
|
||||
__('FAQ', PC_FAQ_MANAGER_SLUG),
|
||||
'manage_options',
|
||||
'pc-faq-manager',
|
||||
array($this, 'render_main_page'),
|
||||
'dashicons-editor-help',
|
||||
25
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'pc-faq-manager',
|
||||
__('All FAQs', PC_FAQ_MANAGER_SLUG),
|
||||
__('All FAQs', PC_FAQ_MANAGER_SLUG),
|
||||
'manage_options',
|
||||
'pc-faq-manager',
|
||||
array($this, 'render_main_page')
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'pc-faq-manager',
|
||||
__('Add New FAQ', PC_FAQ_MANAGER_SLUG),
|
||||
__('Add New', PC_FAQ_MANAGER_SLUG),
|
||||
'manage_options',
|
||||
'pc-faq-manager-add',
|
||||
array($this, 'render_add_page')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue admin scripts and styles
|
||||
*/
|
||||
public function enqueue_admin_scripts($hook) {
|
||||
if (strpos($hook, 'pc-faq-manager') !== false) {
|
||||
wp_enqueue_style('pc-faq-manager-admin', PC_FAQ_MANAGER_PLUGIN_URL . 'admin/css/admin-style.css', array(), PC_FAQ_MANAGER_VERSION);
|
||||
wp_enqueue_script('jquery-ui-sortable');
|
||||
wp_enqueue_script('pc-faq-manager-admin', PC_FAQ_MANAGER_PLUGIN_URL . 'admin/js/admin-script.js', array('jquery', 'jquery-ui-sortable'), PC_FAQ_MANAGER_VERSION, true);
|
||||
wp_localize_script('pc-faq-manager-admin', 'pc_faq_manager', array(
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'nonce' => wp_create_nonce('pc_faq_manager_nonce'),
|
||||
'confirm_delete' => __('Are you sure you want to delete this FAQ?', PC_FAQ_MANAGER_SLUG),
|
||||
'saving' => __('Saving...', PC_FAQ_MANAGER_SLUG),
|
||||
'saved' => __('Saved!', PC_FAQ_MANAGER_SLUG),
|
||||
'error' => __('Error occurred. Please try again.', PC_FAQ_MANAGER_SLUG),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render main admin page
|
||||
*/
|
||||
public function render_main_page() {
|
||||
if (!PC_FAQ_Manager_Helper::can_manage_faqs()) {
|
||||
wp_die(__('You do not have sufficient permissions to access this page.', PC_FAQ_MANAGER_SLUG));
|
||||
}
|
||||
|
||||
$faqs = PC_FAQ_Manager_Helper::get_faqs();
|
||||
$faq_count = PC_FAQ_Manager_Helper::get_faq_count();
|
||||
|
||||
include PC_FAQ_MANAGER_PLUGIN_DIR . 'admin/templates/main-page.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render add new FAQ page
|
||||
*/
|
||||
public function render_add_page() {
|
||||
if (!PC_FAQ_Manager_Helper::can_manage_faqs()) {
|
||||
wp_die(__('You do not have sufficient permissions to access this page.', PC_FAQ_MANAGER_SLUG));
|
||||
}
|
||||
|
||||
include PC_FAQ_MANAGER_PLUGIN_DIR . 'admin/templates/add-page.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle AJAX reorder request
|
||||
*/
|
||||
public function handle_ajax_reorder() {
|
||||
check_ajax_referer('pc_faq_manager_nonce', 'nonce');
|
||||
|
||||
if (!PC_FAQ_Manager_Helper::can_manage_faqs()) {
|
||||
wp_die(__('Permission denied.', PC_FAQ_MANAGER_SLUG));
|
||||
}
|
||||
|
||||
if (isset($_POST['faq_ids']) && is_array($_POST['faq_ids'])) {
|
||||
$result = PC_FAQ_Manager_Helper::reorder_faqs($_POST['faq_ids']);
|
||||
|
||||
if ($result) {
|
||||
wp_send_json_success(array('message' => __('FAQs reordered successfully.', PC_FAQ_MANAGER_SLUG)));
|
||||
} else {
|
||||
wp_send_json_error(array('message' => __('Failed to reorder FAQs.', PC_FAQ_MANAGER_SLUG)));
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_error(array('message' => __('Invalid request.', PC_FAQ_MANAGER_SLUG)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle AJAX add new FAQ
|
||||
*/
|
||||
public function handle_ajax_add_new() {
|
||||
check_ajax_referer('pc_faq_manager_nonce', 'nonce');
|
||||
|
||||
if (!PC_FAQ_Manager_Helper::can_manage_faqs()) {
|
||||
wp_die(__('Permission denied.', PC_FAQ_MANAGER_SLUG));
|
||||
}
|
||||
|
||||
$title = sanitize_text_field($_POST['title'] ?? '');
|
||||
$content = wp_kses_post($_POST['content'] ?? '');
|
||||
|
||||
if (empty($title) || empty($content)) {
|
||||
wp_send_json_error(array('message' => __('Title and content are required.', PC_FAQ_MANAGER_SLUG)));
|
||||
}
|
||||
|
||||
$faq_data = array(
|
||||
'post_title' => $title,
|
||||
'post_content' => $content,
|
||||
'post_status' => 'publish',
|
||||
'post_type' => 'pc_faq',
|
||||
);
|
||||
|
||||
$faq_id = wp_insert_post($faq_data);
|
||||
|
||||
if ($faq_id && !is_wp_error($faq_id)) {
|
||||
$max_order = PC_FAQ_Manager_Helper::get_max_order();
|
||||
update_post_meta($faq_id, '_pc_faq_order', $max_order + 1);
|
||||
|
||||
wp_send_json_success(array(
|
||||
'message' => __('FAQ added successfully.', PC_FAQ_MANAGER_SLUG),
|
||||
'faq_id' => $faq_id,
|
||||
));
|
||||
} else {
|
||||
wp_send_json_error(array('message' => __('Failed to add FAQ.', PC_FAQ_MANAGER_SLUG)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle AJAX edit FAQ
|
||||
*/
|
||||
public function handle_ajax_edit() {
|
||||
check_ajax_referer('pc_faq_manager_nonce', 'nonce');
|
||||
|
||||
if (!PC_FAQ_Manager_Helper::can_manage_faqs()) {
|
||||
wp_die(__('Permission denied.', PC_FAQ_MANAGER_SLUG));
|
||||
}
|
||||
|
||||
$faq_id = intval($_POST['faq_id'] ?? 0);
|
||||
$title = sanitize_text_field($_POST['title'] ?? '');
|
||||
$content = wp_kses_post($_POST['content'] ?? '');
|
||||
|
||||
if (!$faq_id || empty($title) || empty($content)) {
|
||||
wp_send_json_error(array('message' => __('Invalid data provided.', PC_FAQ_MANAGER_SLUG)));
|
||||
}
|
||||
|
||||
$faq_data = array(
|
||||
'ID' => $faq_id,
|
||||
'post_title' => $title,
|
||||
'post_content' => $content,
|
||||
);
|
||||
|
||||
$result = wp_update_post($faq_data);
|
||||
|
||||
if ($result && !is_wp_error($result)) {
|
||||
wp_send_json_success(array('message' => __('FAQ updated successfully.', PC_FAQ_MANAGER_SLUG)));
|
||||
} else {
|
||||
wp_send_json_error(array('message' => __('Failed to update FAQ.', PC_FAQ_MANAGER_SLUG)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle AJAX delete FAQ
|
||||
*/
|
||||
public function handle_ajax_delete() {
|
||||
check_ajax_referer('pc_faq_manager_nonce', 'nonce');
|
||||
|
||||
if (!PC_FAQ_Manager_Helper::can_manage_faqs()) {
|
||||
wp_die(__('Permission denied.', PC_FAQ_MANAGER_SLUG));
|
||||
}
|
||||
|
||||
$faq_id = intval($_POST['faq_id'] ?? 0);
|
||||
|
||||
if (!$faq_id) {
|
||||
wp_send_json_error(array('message' => __('Invalid FAQ ID.', PC_FAQ_MANAGER_SLUG)));
|
||||
}
|
||||
|
||||
$result = wp_delete_post($faq_id, true);
|
||||
|
||||
if ($result) {
|
||||
wp_send_json_success(array('message' => __('FAQ deleted successfully.', PC_FAQ_MANAGER_SLUG)));
|
||||
} else {
|
||||
wp_send_json_error(array('message' => __('Failed to delete FAQ.', PC_FAQ_MANAGER_SLUG)));
|
||||
}
|
||||
}
|
||||
}
|
||||
439
chat/templates/FAQ Manager/admin/css/admin-style.css
Normal file
439
chat/templates/FAQ Manager/admin/css/admin-style.css
Normal file
@@ -0,0 +1,439 @@
|
||||
/* FAQ Manager Admin Styles */
|
||||
.pc-faq-manager-admin {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Header Section */
|
||||
.pc-faq-manager-header {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 2fr;
|
||||
gap: 20px;
|
||||
margin: 20px 0;
|
||||
padding: 20px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.pc-faq-manager-stats .stat-card {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 2.5em;
|
||||
font-weight: 600;
|
||||
color: #0073aa;
|
||||
line-height: 1;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
color: #666;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.pc-faq-manager-instructions h3 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
color: #23282d;
|
||||
}
|
||||
|
||||
.pc-faq-manager-instructions ul {
|
||||
margin: 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.pc-faq-manager-instructions li {
|
||||
margin-bottom: 5px;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
/* FAQ List */
|
||||
.pc-faq-manager-list {
|
||||
background: #fff;
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.pc-faq-manager-list-header {
|
||||
display: grid;
|
||||
grid-template-columns: 40px 1fr 1fr 150px;
|
||||
background: #fcfcfc;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
padding: 12px 16px;
|
||||
font-weight: 600;
|
||||
color: #23282d;
|
||||
}
|
||||
|
||||
.pc-faq-manager-items {
|
||||
max-height: 600px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.pc-faq-item {
|
||||
display: grid;
|
||||
grid-template-columns: 40px 1fr 1fr 150px;
|
||||
padding: 16px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
align-items: start;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.pc-faq-item:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.pc-faq-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.sort-handle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: move;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.sort-handle:hover {
|
||||
color: #0073aa;
|
||||
}
|
||||
|
||||
.faq-content h4 {
|
||||
margin: 0 0 5px 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #23282d;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.faq-excerpt {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.faq-content {
|
||||
color: #444;
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.faq-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.faq-actions .button {
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
height: auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.faq-actions .dashicons {
|
||||
font-size: 14px;
|
||||
margin-right: 4px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* Draggable state */
|
||||
.pc-faq-manager-items.ui-sortable .pc-faq-item {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.pc-faq-manager-items.ui-sortable-helper {
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.pc-faq-manager-items.ui-sortable-placeholder {
|
||||
background: #f0f6fc;
|
||||
border: 2px dashed #0073aa;
|
||||
margin: 4px 16px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.pc-faq-manager-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
margin-top: 20px;
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.pc-faq-save-status {
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.pc-faq-save-status.saving {
|
||||
color: #f0ad4e;
|
||||
}
|
||||
|
||||
.pc-faq-save-status.saved {
|
||||
color: #5cb85c;
|
||||
}
|
||||
|
||||
.pc-faq-save-status.error {
|
||||
color: #d9534f;
|
||||
}
|
||||
|
||||
/* Empty State */
|
||||
.pc-faq-manager-empty {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
background: #fff;
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.pc-faq-manager-empty-icon {
|
||||
font-size: 48px;
|
||||
color: #666;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.pc-faq-manager-empty h2 {
|
||||
margin: 0 0 15px 0;
|
||||
color: #23282d;
|
||||
}
|
||||
|
||||
.pc-faq-manager-empty p {
|
||||
margin: 0 0 20px 0;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Add Form */
|
||||
.pc-faq-manager-add-form {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
.pc-faq-form-container {
|
||||
background: #fff;
|
||||
padding: 25px;
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.pc-faq-form-container h2 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 25px;
|
||||
color: #23282d;
|
||||
}
|
||||
|
||||
.form-field {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.form-field label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 600;
|
||||
color: #23282d;
|
||||
}
|
||||
|
||||
.form-field input[type="text"],
|
||||
.form-field textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-field .description {
|
||||
margin-top: 8px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.wp-editor-container {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
/* Help Section */
|
||||
.pc-faq-manager-help {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.help-card {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.help-card h3 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 15px;
|
||||
color: #23282d;
|
||||
}
|
||||
|
||||
.help-card ul {
|
||||
margin: 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.help-card li {
|
||||
margin-bottom: 8px;
|
||||
color: #444;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.help-card code {
|
||||
background: #f5f5f5;
|
||||
padding: 4px 8px;
|
||||
border-radius: 3px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* Modal */
|
||||
.pc-faq-modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 100000;
|
||||
}
|
||||
|
||||
.pc-faq-modal-backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
.pc-faq-modal-content {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
margin: 50px auto;
|
||||
max-width: 700px;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
||||
z-index: 100001;
|
||||
}
|
||||
|
||||
.pc-faq-modal-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20px 25px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
background: #fcfcfc;
|
||||
border-radius: 8px 8px 0 0;
|
||||
}
|
||||
|
||||
.pc-faq-modal-header h2 {
|
||||
margin: 0;
|
||||
color: #23282d;
|
||||
}
|
||||
|
||||
.pc-faq-modal-close {
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
color: #666;
|
||||
padding: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.pc-faq-modal-close:hover {
|
||||
color: #d9534f;
|
||||
}
|
||||
|
||||
.pc-faq-modal-body {
|
||||
padding: 25px;
|
||||
}
|
||||
|
||||
.pc-faq-modal-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 15px;
|
||||
padding: 20px 25px;
|
||||
border-top: 1px solid #e5e5e5;
|
||||
background: #fcfcfc;
|
||||
border-radius: 0 0 8px 8px;
|
||||
}
|
||||
|
||||
/* Notice styling */
|
||||
.notice.is-dismissible {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media screen and (max-width: 1200px) {
|
||||
.pc-faq-manager-admin {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 980px) {
|
||||
.pc-faq-manager-header {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.pc-faq-manager-add-form {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.pc-faq-manager-list-header,
|
||||
.pc-faq-item {
|
||||
grid-template-columns: 40px 1fr 80px;
|
||||
}
|
||||
|
||||
.faq-answer {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.pc-faq-manager-list-header,
|
||||
.pc-faq-item {
|
||||
grid-template-columns: 30px 1fr;
|
||||
}
|
||||
|
||||
.faq-actions {
|
||||
grid-column: 1 / -1;
|
||||
flex-direction: row;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.sort-handle {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.pc-faq-modal-content {
|
||||
margin: 10px;
|
||||
max-height: 90vh;
|
||||
}
|
||||
|
||||
.pc-faq-modal-header,
|
||||
.pc-faq-modal-body,
|
||||
.pc-faq-modal-footer {
|
||||
padding: 15px 20px;
|
||||
}
|
||||
}
|
||||
250
chat/templates/FAQ Manager/admin/js/admin-script.js
Normal file
250
chat/templates/FAQ Manager/admin/js/admin-script.js
Normal file
@@ -0,0 +1,250 @@
|
||||
jQuery(document).ready(function($) {
|
||||
|
||||
// Sortable functionality
|
||||
$('#pc-faq-sortable').sortable({
|
||||
handle: '.sort-handle',
|
||||
placeholder: 'pc-faq-sortable-placeholder',
|
||||
helper: 'clone',
|
||||
opacity: 0.9,
|
||||
cursor: 'move',
|
||||
tolerance: 'pointer',
|
||||
start: function(event, ui) {
|
||||
ui.placeholder.height(ui.item.outerHeight());
|
||||
},
|
||||
update: function(event, ui) {
|
||||
$('#pc-faq-save-order').addClass('highlight');
|
||||
}
|
||||
});
|
||||
|
||||
// Save order
|
||||
$('#pc-faq-save-order').on('click', function() {
|
||||
var $button = $(this);
|
||||
var $status = $('.pc-faq-save-status');
|
||||
|
||||
if ($button.prop('disabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var faqIds = [];
|
||||
$('#pc-faq-sortable .pc-faq-item').each(function() {
|
||||
faqIds.push($(this).data('faq-id'));
|
||||
});
|
||||
|
||||
$button.prop('disabled', true);
|
||||
$status.text(pc_faq_manager.saving).removeClass('saved error').addClass('saving');
|
||||
|
||||
$.post(pc_faq_manager.ajax_url, {
|
||||
action: 'pc_faq_reorder',
|
||||
nonce: pc_faq_manager.nonce,
|
||||
faq_ids: faqIds
|
||||
})
|
||||
.done(function(response) {
|
||||
if (response.success) {
|
||||
$status.text(pc_faq_manager.saved).removeClass('saving error').addClass('saved');
|
||||
$button.removeClass('highlight');
|
||||
} else {
|
||||
$status.text(pc_faq_manager.error).removeClass('saving saved').addClass('error');
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
$status.text(pc_faq_manager.error).removeClass('saving saved').addClass('error');
|
||||
})
|
||||
.always(function() {
|
||||
$button.prop('disabled', false);
|
||||
setTimeout(function() {
|
||||
$status.text('').removeClass('saving saved error');
|
||||
}, 3000);
|
||||
});
|
||||
});
|
||||
|
||||
// Edit FAQ modal
|
||||
var $modal = $('#pc-faq-edit-modal');
|
||||
var $backdrop = $('.pc-faq-modal-backdrop');
|
||||
var currentEditingId = null;
|
||||
|
||||
function openEditModal(faqId) {
|
||||
var $item = $('.pc-faq-item[data-faq-id="' + faqId + '"]');
|
||||
var title = $item.find('.faq-question h4').text();
|
||||
var content = $item.find('.faq-content').text();
|
||||
|
||||
$('#pc-faq-edit-title').val(title);
|
||||
$('#pc-faq-edit-content').val(content);
|
||||
currentEditingId = faqId;
|
||||
|
||||
$modal.show();
|
||||
$backdrop.show();
|
||||
$('body').css('overflow', 'hidden');
|
||||
}
|
||||
|
||||
function closeEditModal() {
|
||||
$modal.hide();
|
||||
$backdrop.hide();
|
||||
$('body').css('overflow', '');
|
||||
currentEditingId = null;
|
||||
}
|
||||
|
||||
$('.pc-faq-edit').on('click', function() {
|
||||
var faqId = $(this).data('faq-id');
|
||||
openEditModal(faqId);
|
||||
});
|
||||
|
||||
$('.pc-faq-modal-close, .pc-faq-modal-cancel, .pc-faq-modal-backdrop').on('click', function() {
|
||||
closeEditModal();
|
||||
});
|
||||
|
||||
// Save edited FAQ
|
||||
$('.pc-faq-modal-save').on('click', function() {
|
||||
if (!currentEditingId) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $button = $(this);
|
||||
var title = $('#pc-faq-edit-title').val().trim();
|
||||
var content = $('#pc-faq-edit-content').val();
|
||||
|
||||
if (!title || !content) {
|
||||
alert('Please fill in both the question and answer.');
|
||||
return;
|
||||
}
|
||||
|
||||
if ($button.prop('disabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$button.prop('disabled', true);
|
||||
|
||||
$.post(pc_faq_manager.ajax_url, {
|
||||
action: 'pc_faq_edit',
|
||||
nonce: pc_faq_manager.nonce,
|
||||
faq_id: currentEditingId,
|
||||
title: title,
|
||||
content: content
|
||||
})
|
||||
.done(function(response) {
|
||||
if (response.success) {
|
||||
// Update the item in the list
|
||||
var $item = $('.pc-faq-item[data-faq-id="' + currentEditingId + '"]');
|
||||
$item.find('.faq-question h4').text(title);
|
||||
$item.find('.faq-content').text(content.replace(/<[^>]*>/g, '').substring(0, 100) + '...');
|
||||
$item.find('.faq-excerpt').text(content.replace(/<[^>]*>/g, '').substring(0, 50) + '...');
|
||||
|
||||
closeEditModal();
|
||||
} else {
|
||||
alert('Failed to update FAQ: ' + (response.data.message || 'Unknown error'));
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
alert('Failed to update FAQ. Please try again.');
|
||||
})
|
||||
.always(function() {
|
||||
$button.prop('disabled', false);
|
||||
});
|
||||
});
|
||||
|
||||
// Delete FAQ
|
||||
$('.pc-faq-delete').on('click', function() {
|
||||
var $button = $(this);
|
||||
var faqId = $button.data('faq-id');
|
||||
var $item = $button.closest('.pc-faq-item');
|
||||
|
||||
if (!confirm(pc_faq_manager.confirm_delete)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($button.prop('disabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$button.prop('disabled', true);
|
||||
|
||||
$.post(pc_faq_manager.ajax_url, {
|
||||
action: 'pc_faq_delete',
|
||||
nonce: pc_faq_manager.nonce,
|
||||
faq_id: faqId
|
||||
})
|
||||
.done(function(response) {
|
||||
if (response.success) {
|
||||
$item.fadeOut(300, function() {
|
||||
$(this).remove();
|
||||
|
||||
// Check if we need to show empty state
|
||||
var remainingItems = $('#pc-faq-sortable .pc-faq-item').length;
|
||||
if (remainingItems === 0) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
alert('Failed to delete FAQ: ' + (response.data.message || 'Unknown error'));
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
alert('Failed to delete FAQ. Please try again.');
|
||||
})
|
||||
.always(function() {
|
||||
$button.prop('disabled', false);
|
||||
});
|
||||
});
|
||||
|
||||
// Add new FAQ form
|
||||
$('#pc-faq-add-form').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var $form = $(this);
|
||||
var $button = $form.find('button[type="submit"]');
|
||||
var title = $('#pc-faq-title').val().trim();
|
||||
var content = $('#pc-faq-content').val();
|
||||
|
||||
if (!title || !content) {
|
||||
showMessage('Please fill in both the question and answer.', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
if ($button.prop('disabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$button.prop('disabled', true);
|
||||
|
||||
$.post(pc_faq_manager.ajax_url, {
|
||||
action: 'pc_faq_add_new',
|
||||
nonce: pc_faq_manager.nonce,
|
||||
title: title,
|
||||
content: content
|
||||
})
|
||||
.done(function(response) {
|
||||
if (response.success) {
|
||||
showMessage('FAQ created successfully! Redirecting...', 'success');
|
||||
setTimeout(function() {
|
||||
window.location.href = 'admin.php?page=pc-faq-manager';
|
||||
}, 1500);
|
||||
} else {
|
||||
showMessage('Failed to create FAQ: ' + (response.data.message || 'Unknown error'), 'error');
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
showMessage('Failed to create FAQ. Please try again.', 'error');
|
||||
})
|
||||
.always(function() {
|
||||
$button.prop('disabled', false);
|
||||
});
|
||||
});
|
||||
|
||||
function showMessage(message, type) {
|
||||
var $message = $('#pc-faq-add-message');
|
||||
$message.removeClass('notice-success notice-error')
|
||||
.addClass('notice-' + type)
|
||||
.html('<p>' + message + '</p>')
|
||||
.show();
|
||||
|
||||
setTimeout(function() {
|
||||
$message.fadeOut();
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
// ESC key to close modal
|
||||
$(document).on('keydown', function(e) {
|
||||
if (e.keyCode === 27 && $modal.is(':visible')) {
|
||||
closeEditModal();
|
||||
}
|
||||
});
|
||||
});
|
||||
74
chat/templates/FAQ Manager/admin/templates/add-page.php
Normal file
74
chat/templates/FAQ Manager/admin/templates/add-page.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Add New FAQ admin page template
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="wrap pc-faq-manager-admin">
|
||||
<h1 class="wp-heading-inline">
|
||||
<?php esc_html_e('Add New FAQ', PC_FAQ_MANAGER_SLUG); ?>
|
||||
</h1>
|
||||
|
||||
<a href="<?php echo admin_url('admin.php?page=pc-faq-manager'); ?>" class="page-title-action">
|
||||
<?php esc_html_e('View All FAQs', PC_FAQ_MANAGER_SLUG); ?>
|
||||
</a>
|
||||
|
||||
<hr class="wp-header-end">
|
||||
|
||||
<div class="pc-faq-manager-add-form">
|
||||
<div class="pc-faq-form-container">
|
||||
<h2><?php esc_html_e('Create New FAQ', PC_FAQ_MANAGER_SLUG); ?></h2>
|
||||
|
||||
<form id="pc-faq-add-form">
|
||||
<div class="form-field">
|
||||
<label for="pc-faq-title"><?php esc_html_e('Question', PC_FAQ_MANAGER_SLUG); ?></label>
|
||||
<input type="text" id="pc-faq-title" class="widefat" placeholder="<?php esc_attr_e('Enter your question here...', PC_FAQ_MANAGER_SLUG); ?>" required>
|
||||
<p class="description"><?php esc_html_e('This will be displayed as the question on your FAQ page.', PC_FAQ_MANAGER_SLUG); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="form-field">
|
||||
<label for="pc-faq-content"><?php esc_html_e('Answer', PC_FAQ_MANAGER_SLUG); ?></label>
|
||||
<textarea id="pc-faq-content" name="content" class="widefat" rows="10" placeholder="<?php esc_attr_e('Enter your answer here...', PC_FAQ_MANAGER_SLUG); ?>" required></textarea>
|
||||
<p class="description"><?php esc_html_e('Provide a detailed answer to the question above.', PC_FAQ_MANAGER_SLUG); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="form-field">
|
||||
<button type="submit" class="button button-primary button-large">
|
||||
<span class="dashicons dashicons-plus-alt"></span>
|
||||
<?php esc_html_e('Create FAQ', PC_FAQ_MANAGER_SLUG); ?>
|
||||
</button>
|
||||
<a href="<?php echo admin_url('admin.php?page=pc-faq-manager'); ?>" class="button button-large">
|
||||
<?php esc_html_e('Cancel', PC_FAQ_MANAGER_SLUG); ?>
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="pc-faq-manager-help">
|
||||
<div class="help-card">
|
||||
<h3><?php esc_html_e('Pro Tips', PC_FAQ_MANAGER_SLUG); ?></h3>
|
||||
<ul>
|
||||
<li><?php esc_html_e('Keep questions clear and concise', PC_FAQ_MANAGER_SLUG); ?></li>
|
||||
<li><?php esc_html_e('Provide comprehensive answers', PC_FAQ_MANAGER_SLUG); ?></li>
|
||||
<li><?php esc_html_e('Use formatting to improve readability', PC_FAQ_MANAGER_SLUG); ?></li>
|
||||
<li><?php esc_html_e('Consider adding images or links if helpful', PC_FAQ_MANAGER_SLUG); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="help-card">
|
||||
<h3><?php esc_html_e('FAQ Page', PC_FAQ_MANAGER_SLUG); ?></h3>
|
||||
<p><?php esc_html_e('Your FAQs will automatically appear on the FAQ page. You can find it at:', PC_FAQ_MANAGER_SLUG); ?></p>
|
||||
<p><code><?php echo home_url('/faq/'); ?></code></p>
|
||||
<p><a href="<?php echo home_url('/faq/'); ?>" target="_blank" class="button"><?php esc_html_e('View FAQ Page', PC_FAQ_MANAGER_SLUG); ?></a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Success/Error Messages -->
|
||||
<div id="pc-faq-add-message" class="notice is-dismissible" style="display: none;"></div>
|
||||
</div>
|
||||
140
chat/templates/FAQ Manager/admin/templates/main-page.php
Normal file
140
chat/templates/FAQ Manager/admin/templates/main-page.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
/**
|
||||
* Main FAQ Manager admin page template
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="wrap pc-faq-manager-admin">
|
||||
<h1 class="wp-heading-inline">
|
||||
<?php esc_html_e('FAQ Manager', PC_FAQ_MANAGER_SLUG); ?>
|
||||
</h1>
|
||||
|
||||
<a href="<?php echo admin_url('admin.php?page=pc-faq-manager-add'); ?>" class="page-title-action">
|
||||
<?php esc_html_e('Add New FAQ', PC_FAQ_MANAGER_SLUG); ?>
|
||||
</a>
|
||||
|
||||
<hr class="wp-header-end">
|
||||
|
||||
<?php if ($faq_count > 0): ?>
|
||||
<div class="pc-faq-manager-header">
|
||||
<div class="pc-faq-manager-stats">
|
||||
<div class="stat-card">
|
||||
<div class="stat-number"><?php echo esc_html($faq_count); ?></div>
|
||||
<div class="stat-label"><?php esc_html_e('Total FAQs', PC_FAQ_MANAGER_SLUG); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pc-faq-manager-instructions">
|
||||
<h3><?php esc_html_e('How to use', PC_FAQ_MANAGER_SLUG); ?></h3>
|
||||
<ul>
|
||||
<li><?php esc_html_e('Drag and drop FAQs to reorder them', PC_FAQ_MANAGER_SLUG); ?></li>
|
||||
<li><?php esc_html_e('Click on any FAQ to edit it inline', PC_FAQ_MANAGER_SLUG); ?></li>
|
||||
<li><?php esc_html_e('Use the delete button to remove an FAQ', PC_FAQ_MANAGER_SLUG); ?></li>
|
||||
<li><?php esc_html_e('The FAQ page will automatically update on your website', PC_FAQ_MANAGER_SLUG); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pc-faq-manager-list">
|
||||
<div class="pc-faq-manager-list-header">
|
||||
<div class="sort-handle"></div>
|
||||
<div class="faq-question"><?php esc_html_e('Question', PC_FAQ_MANAGER_SLUG); ?></div>
|
||||
<div class="faq-answer"><?php esc_html_e('Answer', PC_FAQ_MANAGER_SLUG); ?></div>
|
||||
<div class="faq-actions"><?php esc_html_e('Actions', PC_FAQ_MANAGER_SLUG); ?></div>
|
||||
</div>
|
||||
|
||||
<div class="pc-faq-manager-items" id="pc-faq-sortable">
|
||||
<?php foreach ($faqs as $faq): ?>
|
||||
<div class="pc-faq-item" data-faq-id="<?php echo esc_attr($faq->ID); ?>">
|
||||
<div class="sort-handle">
|
||||
<span class="dashicons dashicons-menu"></span>
|
||||
</div>
|
||||
<div class="faq-question">
|
||||
<div class="faq-content">
|
||||
<h4><?php echo esc_html($faq->post_title); ?></h4>
|
||||
<div class="faq-excerpt">
|
||||
<?php echo wp_trim_words($faq->post_content, 15, '...'); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="faq-answer">
|
||||
<div class="faq-content">
|
||||
<?php echo wp_trim_words($faq->post_content, 20, '...'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="faq-actions">
|
||||
<button type="button" class="button button-secondary pc-faq-edit" data-faq-id="<?php echo esc_attr($faq->ID); ?>">
|
||||
<span class="dashicons dashicons-edit"></span>
|
||||
<?php esc_html_e('Edit', PC_FAQ_MANAGER_SLUG); ?>
|
||||
</button>
|
||||
<button type="button" class="button pc-faq-delete" data-faq-id="<?php echo esc_attr($faq->ID); ?>">
|
||||
<span class="dashicons dashicons-trash"></span>
|
||||
<?php esc_html_e('Delete', PC_FAQ_MANAGER_SLUG); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pc-faq-manager-footer">
|
||||
<button type="button" class="button button-primary" id="pc-faq-save-order">
|
||||
<span class="dashicons dashicons-yes"></span>
|
||||
<?php esc_html_e('Save Order', PC_FAQ_MANAGER_SLUG); ?>
|
||||
</button>
|
||||
<span class="pc-faq-save-status"></span>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<div class="pc-faq-manager-empty">
|
||||
<div class="pc-faq-manager-empty-icon">
|
||||
<span class="dashicons dashicons-editor-help"></span>
|
||||
</div>
|
||||
<h2><?php esc_html_e('No FAQs yet', PC_FAQ_MANAGER_SLUG); ?></h2>
|
||||
<p><?php esc_html_e('Create your first FAQ to get started with the FAQ Manager.', PC_FAQ_MANAGER_SLUG); ?></p>
|
||||
<p>
|
||||
<a href="<?php echo admin_url('admin.php?page=pc-faq-manager-add'); ?>" class="button button-primary">
|
||||
<?php esc_html_e('Create Your First FAQ', PC_FAQ_MANAGER_SLUG); ?>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Edit Modal -->
|
||||
<div id="pc-faq-edit-modal" class="pc-faq-modal" style="display: none;">
|
||||
<div class="pc-faq-modal-content">
|
||||
<div class="pc-faq-modal-header">
|
||||
<h2><?php esc_html_e('Edit FAQ', PC_FAQ_MANAGER_SLUG); ?></h2>
|
||||
<button type="button" class="pc-faq-modal-close">×</button>
|
||||
</div>
|
||||
<div class="pc-faq-modal-body">
|
||||
<div class="form-field">
|
||||
<label for="pc-faq-edit-title"><?php esc_html_e('Question', PC_FAQ_MANAGER_SLUG); ?></label>
|
||||
<input type="text" id="pc-faq-edit-title" class="widefat" placeholder="<?php esc_attr_e('Enter your question here...', PC_FAQ_MANAGER_SLUG); ?>">
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="pc-faq-edit-content"><?php esc_html_e('Answer', PC_FAQ_MANAGER_SLUG); ?></label>
|
||||
<?php
|
||||
wp_editor('', 'pc-faq-edit-content', array(
|
||||
'textarea_name' => 'content',
|
||||
'textarea_rows' => 10,
|
||||
'media_buttons' => false,
|
||||
'teeny' => true,
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pc-faq-modal-footer">
|
||||
<button type="button" class="button button-secondary pc-faq-modal-cancel"><?php esc_html_e('Cancel', PC_FAQ_MANAGER_SLUG); ?></button>
|
||||
<button type="button" class="button button-primary pc-faq-modal-save"><?php esc_html_e('Update FAQ', PC_FAQ_MANAGER_SLUG); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pc-faq-modal-backdrop" style="display: none;"></div>
|
||||
Reference in New Issue
Block a user