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,79 @@
<?php
/**
* FAQ Manager Public Interface
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
class PC_FAQ_Manager_Public {
/**
* Constructor
*/
public function __construct() {
add_action('wp_enqueue_scripts', array($this, 'enqueue_public_scripts'));
add_shortcode('pc_faq_page', array($this, 'render_faq_page'));
}
/**
* Enqueue public scripts and styles
*/
public function enqueue_public_scripts() {
wp_enqueue_style('pc-faq-manager-public', PC_FAQ_MANAGER_PLUGIN_URL . 'public/css/public-style.css', array(), PC_FAQ_MANAGER_VERSION);
wp_enqueue_script('pc-faq-manager-public', PC_FAQ_MANAGER_PLUGIN_URL . 'public/js/public-script.js', array('jquery'), PC_FAQ_MANAGER_VERSION, true);
}
/**
* Render FAQ page shortcode
*/
public function render_faq_page($atts) {
$atts = shortcode_atts(array(
'title' => __('Frequently Asked Questions', PC_FAQ_MANAGER_SLUG),
'show_count' => true,
), $atts);
$faqs = PC_FAQ_Manager_Helper::get_faqs();
if (empty($faqs)) {
return '<div class="pc-faq-empty">' . esc_html__('No FAQs available at this time.', PC_FAQ_MANAGER_SLUG) . '</div>';
}
ob_start();
if ($atts['show_count']) {
echo '<div class="pc-faq-header">';
echo '<h1 class="pc-faq-title">' . esc_html($atts['title']) . '</h1>';
echo '<div class="pc-faq-count">' . sprintf(esc_html__('%d FAQs available', PC_FAQ_MANAGER_SLUG), count($faqs)) . '</div>';
echo '</div>';
}
echo '<div class="pc-faq-container">';
echo '<div class="pc-faq-items">';
foreach ($faqs as $index => $faq) {
echo '<div class="pc-faq-item" data-faq-id="' . esc_attr($faq->ID) . '">';
echo '<div class="pc-faq-question">';
echo '<button class="pc-faq-toggle" aria-expanded="false" aria-controls="pc-faq-answer-' . esc_attr($faq->ID) . '">';
echo '<span class="pc-faq-question-text">' . esc_html($faq->post_title) . '</span>';
echo '<span class="pc-faq-toggle-icon"><span class="pc-faq-plus"></span><span class="pc-faq-minus"></span></span>';
echo '</button>';
echo '</div>';
echo '<div class="pc-faq-answer" id="pc-faq-answer-' . esc_attr($faq->ID) . '" style="display: none;">';
echo '<div class="pc-faq-answer-content">';
echo wp_kses_post($faq->post_content);
echo '</div>';
echo '</div>';
echo '</div>';
}
echo '</div>';
echo '</div>';
return ob_get_clean();
}
}

View File

@@ -0,0 +1,442 @@
/* FAQ Manager Public Styles */
/* Custom CSS Variables */
:root {
--pc-faq-primary-color: #0073aa;
--pc-faq-secondary-color: #f1f1f1;
--pc-faq-text-color: #333;
--pc-faq-text-light: #666;
--pc-faq-border-color: #ddd;
--pc-faq-hover-color: #005a87;
--pc-faq-success-color: #46b450;
--pc-faq-background: #fff;
--pc-faq-spacing: 20px;
--pc-faq-border-radius: 6px;
--pc-faq-transition: all 0.3s ease;
--pc-faq-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
--pc-faq-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.15);
}
/* Dark Mode Support */
@media (prefers-color-scheme: dark) {
:root {
--pc-faq-primary-color: #4fb3d9;
--pc-faq-secondary-color: #2c2c2c;
--pc-faq-text-color: #f0f0f0;
--pc-faq-text-light: #ccc;
--pc-faq-border-color: #555;
--pc-faq-hover-color: #6cc0e3;
--pc-faq-background: #1a1a1a;
--pc-faq-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
--pc-faq-shadow-hover: 0 4px 12px rgba(0, 0, 0, 0.5);
}
}
/* FAQ Container */
.pc-faq-container {
max-width: 900px;
margin: 0 auto;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
line-height: 1.6;
color: var(--pc-faq-text-color);
}
/* FAQ Header */
.pc-faq-header {
text-align: center;
margin-bottom: calc(var(--pc-faq-spacing) * 2);
padding: calc(var(--pc-faq-spacing) * 1.5);
background: linear-gradient(135deg, var(--pc-faq-primary-color) 0%, var(--pc-faq-hover-color) 100%);
color: white;
border-radius: var(--pc-faq-border-radius);
box-shadow: var(--pc-faq-shadow);
}
.pc-faq-title {
font-size: 2.5rem;
font-weight: 700;
margin: 0 0 10px 0;
line-height: 1.2;
}
.pc-faq-count {
font-size: 1.1rem;
opacity: 0.9;
font-weight: 300;
}
/* FAQ Items */
.pc-faq-items {
display: flex;
flex-direction: column;
gap: 15px;
}
.pc-faq-item {
background: var(--pc-faq-background);
border: 1px solid var(--pc-faq-border-color);
border-radius: var(--pc-faq-border-radius);
overflow: hidden;
transition: var(--pc-faq-transition);
box-shadow: var(--pc-faq-shadow);
}
.pc-faq-item:hover {
transform: translateY(-2px);
box-shadow: var(--pc-faq-shadow-hover);
border-color: var(--pc-faq-primary-color);
}
/* FAQ Question */
.pc-faq-question {
margin: 0;
}
.pc-faq-toggle {
width: 100%;
padding: 20px 25px;
background: none;
border: none;
text-align: left;
cursor: pointer;
font-size: 1.1rem;
font-weight: 600;
color: var(--pc-faq-text-color);
display: flex;
justify-content: space-between;
align-items: center;
transition: var(--pc-faq-transition);
position: relative;
}
.pc-faq-toggle:hover {
background: var(--pc-faq-secondary-color);
color: var(--pc-faq-primary-color);
}
.pc-faq-toggle:focus {
outline: 2px solid var(--pc-faq-primary-color);
outline-offset: -2px;
}
.pc-faq-question-text {
flex: 1;
padding-right: 15px;
line-height: 1.4;
}
/* Toggle Icon */
.pc-faq-toggle-icon {
position: relative;
width: 24px;
height: 24px;
flex-shrink: 0;
}
.pc-faq-plus,
.pc-faq-minus {
position: absolute;
background: var(--pc-faq-primary-color);
transition: var(--pc-faq-transition);
}
.pc-faq-plus {
width: 100%;
height: 2px;
top: 50%;
left: 0;
transform: translateY(-50%);
}
.pc-faq-minus {
width: 2px;
height: 100%;
top: 0;
left: 50%;
transform: translateX(-50%);
}
.pc-faq-item.is-open .pc-faq-minus {
opacity: 0;
transform: translateX(-50%) rotate(90deg);
}
.pc-faq-item.is-open .pc-faq-plus {
transform: translateY(-50%) rotate(90deg);
}
/* FAQ Answer */
.pc-faq-answer {
max-height: 0;
overflow: hidden;
transition: max-height 0.4s ease, padding 0.4s ease;
background: var(--pc-faq-secondary-color);
border-top: 1px solid var(--pc-faq-border-color);
}
.pc-faq-item.is-open .pc-faq-answer {
max-height: 1000px;
padding: 25px;
}
.pc-faq-answer-content {
color: var(--pc-faq-text-light);
font-size: 1rem;
line-height: 1.7;
}
.pc-faq-answer-content p:last-child {
margin-bottom: 0;
}
.pc-faq-answer-content h1,
.pc-faq-answer-content h2,
.pc-faq-answer-content h3,
.pc-faq-answer-content h4,
.pc-faq-answer-content h5,
.pc-faq-answer-content h6 {
color: var(--pc-faq-text-color);
margin-top: 20px;
margin-bottom: 15px;
}
.pc-faq-answer-content h1 { font-size: 1.8em; }
.pc-faq-answer-content h2 { font-size: 1.6em; }
.pc-faq-answer-content h3 { font-size: 1.4em; }
.pc-faq-answer-content h4 { font-size: 1.2em; }
.pc-faq-answer-content h5 { font-size: 1.1em; }
.pc-faq-answer-content h6 { font-size: 1em; }
.pc-faq-answer-content ul,
.pc-faq-answer-content ol {
margin: 15px 0;
padding-left: 25px;
}
.pc-faq-answer-content li {
margin-bottom: 8px;
}
.pc-faq-answer-content a {
color: var(--pc-faq-primary-color);
text-decoration: none;
border-bottom: 1px solid transparent;
transition: border-bottom-color 0.2s ease;
}
.pc-faq-answer-content a:hover {
border-bottom-color: var(--pc-faq-primary-color);
}
.pc-faq-answer-content blockquote {
margin: 20px 0;
padding: 15px 20px;
background: var(--pc-faq-background);
border-left: 4px solid var(--pc-faq-primary-color);
font-style: italic;
border-radius: 0 var(--pc-faq-border-radius) var(--pc-faq-border-radius) 0;
}
.pc-faq-answer-content code {
background: var(--pc-faq-background);
padding: 3px 6px;
border-radius: 3px;
font-family: 'Courier New', Courier, monospace;
font-size: 0.9em;
border: 1px solid var(--pc-faq-border-color);
}
.pc-faq-answer-content pre {
background: var(--pc-faq-background);
padding: 15px;
border-radius: var(--pc-faq-border-radius);
overflow-x: auto;
margin: 20px 0;
border: 1px solid var(--pc-faq-border-color);
}
.pc-faq-answer-content pre code {
background: none;
padding: 0;
border: none;
font-size: 0.9em;
}
.pc-faq-answer-content img {
max-width: 100%;
height: auto;
border-radius: var(--pc-faq-border-radius);
margin: 15px 0;
box-shadow: var(--pc-faq-shadow);
}
.pc-faq-answer-content table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
background: var(--pc-faq-background);
border-radius: var(--pc-faq-border-radius);
overflow: hidden;
}
.pc-faq-answer-content th,
.pc-faq-answer-content td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid var(--pc-faq-border-color);
}
.pc-faq-answer-content th {
background: var(--pc-faq-primary-color);
color: white;
font-weight: 600;
}
.pc-faq-answer-content tr:last-child td {
border-bottom: none;
}
/* Empty State */
.pc-faq-empty {
text-align: center;
padding: 60px 20px;
color: var(--pc-faq-text-light);
font-size: 1.1rem;
font-style: italic;
}
/* Accessibility */
.pc-faq-toggle[aria-expanded="true"] {
color: var(--pc-faq-primary-color);
font-weight: 700;
}
/* Focus visible for keyboard navigation */
.pc-faq-toggle:focus-visible {
outline: 3px solid var(--pc-faq-primary-color);
outline-offset: 2px;
}
/* Print Styles */
@media print {
.pc-faq-container {
max-width: none;
}
.pc-faq-item {
break-inside: avoid;
box-shadow: none;
border: 1px solid #333;
}
.pc-faq-answer {
display: block !important;
max-height: none !important;
padding: 20px !important;
}
.pc-faq-toggle-icon {
display: none;
}
}
/* Responsive Design */
@media screen and (max-width: 768px) {
.pc-faq-container {
margin: 0 15px;
}
.pc-faq-title {
font-size: 2rem;
}
.pc-faq-toggle {
padding: 15px 20px;
font-size: 1rem;
}
.pc-faq-item.is-open .pc-faq-answer {
padding: 20px;
}
.pc-faq-answer-content {
font-size: 0.95rem;
}
}
@media screen and (max-width: 480px) {
.pc-faq-header {
padding: 20px 15px;
margin-bottom: 30px;
}
.pc-faq-title {
font-size: 1.75rem;
}
.pc-faq-toggle {
padding: 12px 15px;
font-size: 0.95rem;
}
.pc-faq-question-text {
padding-right: 10px;
}
.pc-faq-toggle-icon {
width: 20px;
height: 20px;
}
.pc-faq-item.is-open .pc-faq-answer {
padding: 15px;
}
.pc-faq-answer-content {
font-size: 0.9rem;
}
}
/* Animation Enhancements */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.pc-faq-item {
animation: fadeIn 0.4s ease-out;
}
.pc-faq-item:nth-child(1) { animation-delay: 0.1s; }
.pc-faq-item:nth-child(2) { animation-delay: 0.2s; }
.pc-faq-item:nth-child(3) { animation-delay: 0.3s; }
.pc-faq-item:nth-child(4) { animation-delay: 0.4s; }
.pc-faq-item:nth-child(5) { animation-delay: 0.5s; }
/* RTL Support */
[dir="rtl"] .pc-faq-toggle {
text-align: right;
}
[dir="rtl"] .pc-faq-question-text {
padding-right: 0;
padding-left: 15px;
}
[dir="rtl"] .pc-faq-answer-content ul,
[dir="rtl"] .pc-faq-answer-content ol {
padding-left: 0;
padding-right: 25px;
}
[dir="rtl"] .pc-faq-answer-content blockquote {
border-left: none;
border-right: 4px solid var(--pc-faq-primary-color);
border-radius: var(--pc-faq-border-radius) 0 0 var(--pc-faq-border-radius);
}

View File

@@ -0,0 +1,250 @@
jQuery(document).ready(function($) {
// FAQ Toggle functionality
$('.pc-faq-toggle').on('click', function(e) {
e.preventDefault();
var $button = $(this);
var $faqItem = $button.closest('.pc-faq-item');
var $answer = $faqItem.find('.pc-faq-answer');
var isExpanded = $button.attr('aria-expanded') === 'true';
// Close all other FAQs (optional accordion behavior)
$('.pc-faq-item').each(function() {
if ($(this)[0] !== $faqItem[0]) {
$(this).removeClass('is-open');
$(this).find('.pc-faq-answer').slideUp(300);
$(this).find('.pc-faq-toggle').attr('aria-expanded', 'false');
}
});
// Toggle current FAQ
if (isExpanded) {
$faqItem.removeClass('is-open');
$answer.slideUp(300);
$button.attr('aria-expanded', 'false');
} else {
$faqItem.addClass('is-open');
$answer.slideDown(300);
$button.attr('aria-expanded', 'true');
// Smooth scroll to the FAQ
setTimeout(function() {
$('html, body').animate({
scrollTop: $faqItem.offset().top - 20
}, 300);
}, 100);
}
});
// Keyboard navigation
$('.pc-faq-toggle').on('keydown', function(e) {
var $button = $(this);
var $faqItem = $button.closest('.pc-faq-item');
var $allItems = $('.pc-faq-item');
var currentIndex = $allItems.index($faqItem);
switch (e.keyCode) {
case 38: // Up arrow
e.preventDefault();
if (currentIndex > 0) {
$allItems.eq(currentIndex - 1).find('.pc-faq-toggle').focus();
}
break;
case 40: // Down arrow
e.preventDefault();
if (currentIndex < $allItems.length - 1) {
$allItems.eq(currentIndex + 1).find('.pc-faq-toggle').focus();
}
break;
case 36: // Home
e.preventDefault();
$allItems.first().find('.pc-faq-toggle').focus();
break;
case 35: // End
e.preventDefault();
$allItems.last().find('.pc-faq-toggle').focus();
break;
}
});
// Search functionality (if search box is added)
function initSearch() {
var $searchBox = $('#pc-faq-search');
if ($searchBox.length === 0) return;
$searchBox.on('input', function() {
var searchTerm = $(this).val().toLowerCase();
var $faqs = $('.pc-faq-item');
var visibleCount = 0;
$faqs.each(function() {
var $faqItem = $(this);
var question = $faqItem.find('.pc-faq-question-text').text().toLowerCase();
var answer = $faqItem.find('.pc-faq-answer-content').text().toLowerCase();
if (question.includes(searchTerm) || answer.includes(searchTerm)) {
$faqItem.show();
visibleCount++;
} else {
$faqItem.hide();
}
});
// Show no results message
var $noResults = $('.pc-faq-no-results');
if (visibleCount === 0 && searchTerm !== '') {
if ($noResults.length === 0) {
$noResults = $('<div class="pc-faq-no-results" style="text-align: center; padding: 40px 20px; color: #666; font-style: italic;"></div>');
$('.pc-faq-items').append($noResults);
}
$noResults.text('No FAQs found matching "' + searchTerm + '"');
} else {
$noResults.remove();
}
// Update count
var $count = $('.pc-faq-count');
if ($count.length > 0) {
if (searchTerm === '') {
$count.text($faqs.length + ' FAQs available');
} else {
$count.text(visibleCount + ' of ' + $faqs.length + ' FAQs matching "' + searchTerm + '"');
}
}
});
}
// Initialize search if present
initSearch();
// Expand/Collapse All functionality
function initExpandCollapseAll() {
var $expandAll = $('#pc-faq-expand-all');
var $collapseAll = $('#pc-faq-collapse-all');
if ($expandAll.length === 0 && $collapseAll.length === 0) return;
$expandAll.on('click', function() {
$('.pc-faq-item').addClass('is-open');
$('.pc-faq-answer').slideDown(300);
$('.pc-faq-toggle').attr('aria-expanded', 'true');
});
$collapseAll.on('click', function() {
$('.pc-faq-item').removeClass('is-open');
$('.pc-faq-answer').slideUp(300);
$('.pc-faq-toggle').attr('aria-expanded', 'false');
});
}
initExpandCollapseAll();
// Print functionality
function initPrintButton() {
var $printButton = $('#pc-faq-print');
if ($printButton.length === 0) return;
$printButton.on('click', function(e) {
e.preventDefault();
window.print();
});
}
initPrintButton();
// URL hash functionality
function initHashNavigation() {
if (window.location.hash) {
var hash = window.location.hash.substring(1);
var $targetFaq = $('#pc-faq-' + hash);
if ($targetFaq.length > 0) {
// Close all FAQs first
$('.pc-faq-item').removeClass('is-open');
$('.pc-faq-answer').slideUp(300);
$('.pc-faq-toggle').attr('aria-expanded', 'false');
// Open the target FAQ
setTimeout(function() {
$targetFaq.find('.pc-faq-toggle').trigger('click');
}, 500);
}
}
}
initHashNavigation();
// Update hash when FAQ is opened
$('.pc-faq-toggle').on('click', function() {
var $faqItem = $(this).closest('.pc-faq-item');
var faqId = $faqItem.attr('id');
if (faqId && $faqItem.hasClass('is-open')) {
history.pushState(null, null, '#' + faqId.replace('pc-faq-', ''));
} else {
if (window.location.hash) {
history.pushState(null, null, window.location.pathname);
}
}
});
// Analytics tracking (if available)
function trackFAQInteraction(action, faqId) {
if (typeof gtag !== 'undefined') {
gtag('event', 'faq_' + action, {
'faq_id': faqId
});
} else if (typeof ga !== 'undefined') {
ga('send', 'event', 'FAQ', action, faqId);
}
}
// Track FAQ opens
$('.pc-faq-toggle').on('click', function() {
var $faqItem = $(this).closest('.pc-faq-item');
var faqId = $faqItem.data('faq-id') || $faqItem.attr('id');
var question = $faqItem.find('.pc-faq-question-text').text();
trackFAQInteraction('open', faqId);
trackFAQInteraction('open_question', question);
});
// Performance optimization: Lazy load images in answers
function lazyLoadImages() {
if ('IntersectionObserver' in window) {
var imageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var img = entry.target;
if (img.dataset.src) {
img.src = img.dataset.src;
img.removeAttribute('data-src');
observer.unobserve(img);
}
}
});
});
$('.pc-faq-answer-content img[data-src]').each(function() {
imageObserver.observe(this);
});
}
}
lazyLoadImages();
// Smooth scroll behavior for anchor links within answers
$('.pc-faq-answer-content a[href^="#"]').on('click', function(e) {
var target = $(this.getAttribute('href'));
if (target.length) {
e.preventDefault();
$('html, body').animate({
scrollTop: target.offset().top - 20
}, 300);
}
});
});