Restore to commit 74e578279624c6045ca440a3459ebfa1f8d54191

This commit is contained in:
southseact-3d
2026-02-07 20:32:41 +00:00
commit ed67b7741b
252 changed files with 99814 additions and 0 deletions

View 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)));
}
}
}

View 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;
}
}

View 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();
}
});
});

View 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>

View 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">&times;</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>