278 lines
15 KiB
PHP
278 lines
15 KiB
PHP
<?php
|
||
/**
|
||
* صفحه فروشگاه (آرشیو محصولات) - مطابق با UI Kolli.html
|
||
*
|
||
* @package Motayeb
|
||
* @version 1.0.1
|
||
*
|
||
* تغییرات نسخه ۱.۰.۱:
|
||
* - guard کامل WooCommerce (بدون fatal error اگه غیرفعال باشه)
|
||
* - رفع term_description با wp_kses_post
|
||
* - افزودن دکمه toggle فیلتر در موبایل
|
||
* - افزودن نمایش فیلترهای فعال
|
||
* - استفاده از motayeb_count_category_products (شامل زیردستهها)
|
||
* - Breadcrumb Schema برای صفحات دستهبندی
|
||
* - aria-label روی sectionها
|
||
* - width/height + fetchpriority روی بنر
|
||
* - رفع sticky همپوشانی با هدر
|
||
* - استایل Tailwind-friendly برای pagination و ordering
|
||
* - اعتبارسنجی فیلتر قیمت
|
||
*/
|
||
|
||
get_header();
|
||
|
||
// guard: اگه ووکامرس غیرفعال باشه
|
||
if ( ! class_exists( 'WooCommerce' ) ) {
|
||
echo '<main class="pt-16 md:pt-20"><div class="max-w-7xl mx-auto px-4 py-20 text-center">';
|
||
echo '<h1 class="text-2xl font-bold mb-4">فروشگاه فعال نیست</h1>';
|
||
echo '<p class="text-cream-500">برای مشاهده محصولات، افزونه ووکامرس را فعال کنید.</p>';
|
||
echo '</div></main>';
|
||
get_footer();
|
||
return;
|
||
}
|
||
|
||
// دادههای صفحه
|
||
$banner_img = get_option( 'motayeb_shop_banner', '' );
|
||
$banner_img = $banner_img ? $banner_img : 'https://picsum.photos/seed/forest-shop/1600/600';
|
||
$is_category = is_product_category();
|
||
$current_term = $is_category ? get_queried_object() : null;
|
||
|
||
// بررسی اینکه آیا سایدبار فیلتر داره یا خیر
|
||
$has_shop_sidebar = is_active_sidebar( 'sidebar-shop' );
|
||
?>
|
||
|
||
<!-- ===== SHOP HEADER ===== -->
|
||
<section class="relative py-20 md:py-28 overflow-hidden" aria-label="عنوان فروشگاه">
|
||
<div class="absolute inset-0">
|
||
<img src="<?php echo esc_url( $banner_img ); ?>"
|
||
alt="<?php echo esc_attr( $is_category && $current_term ? $current_term->name : 'فروشگاه مطیب' ); ?>"
|
||
width="1600" height="600"
|
||
fetchpriority="high"
|
||
decoding="async"
|
||
class="w-full h-full object-cover">
|
||
</div>
|
||
<div class="absolute inset-0 bg-gradient-to-t from-forest-900/90 via-forest-700/70 to-forest-500/40" aria-hidden="true"></div>
|
||
<div class="relative max-w-7xl mx-auto px-4 md:px-6 text-center">
|
||
<h1 class="text-3xl md:text-4xl lg:text-5xl font-extrabold text-white drop-shadow-md">
|
||
<?php woocommerce_page_title(); ?>
|
||
</h1>
|
||
<?php if ( $is_category && $current_term && $current_term->description ) : ?>
|
||
<p class="text-white/90 text-center mt-3 max-w-2xl mx-auto drop-shadow-md text-sm md:text-base">
|
||
<?php echo wp_kses_post( wpautop( $current_term->description ) ); ?>
|
||
</p>
|
||
<?php endif; ?>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===== FEATURES ===== -->
|
||
<div class="relative z-10 -mt-8 lg:-mt-12 max-w-7xl mx-auto px-4 md:px-6 mb-8">
|
||
<div class="grid grid-cols-2 md:grid-cols-4 gap-3 md:gap-4 bg-white/90 dark:bg-dark-card/90 backdrop-blur-lg p-4 md:p-5 rounded-2xl shadow-lg border border-cream-200/50 dark:border-dark-border/50">
|
||
<?php for ( $i = 1; $i <= 4; $i++ ) : ?>
|
||
<?php
|
||
$default_icons = array( 1 => 'lucide:leaf', 2 => 'lucide:truck', 3 => 'lucide:shield-check', 4 => 'lucide:package' );
|
||
$icon = get_option( 'motayeb_feature_' . $i . '_icon', $default_icons[ $i ] );
|
||
$text = get_option( 'motayeb_feature_' . $i . '_text', 'ویژگی ' . $i );
|
||
?>
|
||
<div class="flex items-center gap-3 justify-center">
|
||
<iconify-icon icon="<?php echo esc_attr( $icon ); ?>" width="22" class="text-forest-500 dark:text-forest-300 flex-shrink-0"></iconify-icon>
|
||
<span class="text-xs md:text-sm font-medium text-earth-400 dark:text-dark-text"><?php echo esc_html( $text ); ?></span>
|
||
</div>
|
||
<?php endfor; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ===== Breadcrumb (برای صفحات دستهبندی) ===== -->
|
||
<?php if ( $is_category && $current_term ) :
|
||
// ساخت BreadcrumbList Schema
|
||
$crumbs = array(
|
||
array( 'name' => 'خانه', 'url' => home_url( '/' ) ),
|
||
array( 'name' => 'فروشگاه', 'url' => get_permalink( wc_get_page_id( 'shop' ) ) ),
|
||
);
|
||
// افزودن دستهبندیهای والد
|
||
$parents = get_ancestors( $current_term->term_id, 'product_cat' );
|
||
$parents = array_reverse( $parents );
|
||
foreach ( $parents as $parent_id ) {
|
||
$parent = get_term( $parent_id, 'product_cat' );
|
||
if ( $parent && ! is_wp_error( $parent ) ) {
|
||
$crumbs[] = array( 'name' => $parent->name, 'url' => get_term_link( $parent ) );
|
||
}
|
||
}
|
||
$crumbs[] = array( 'name' => $current_term->name, 'url' => get_term_link( $current_term ) );
|
||
|
||
$breadcrumb_schema = array(
|
||
'@context' => 'https://schema.org',
|
||
'@type' => 'BreadcrumbList',
|
||
'itemListElement' => array(),
|
||
);
|
||
foreach ( $crumbs as $index => $crumb ) {
|
||
$breadcrumb_schema['itemListElement'][] = array(
|
||
'@type' => 'ListItem',
|
||
'position' => $index + 1,
|
||
'name' => $crumb['name'],
|
||
'item' => $crumb['url'],
|
||
);
|
||
}
|
||
?>
|
||
<nav class="max-w-7xl mx-auto px-4 md:px-6 mb-4 text-xs text-cream-500 dark:text-dark-muted flex items-center gap-2 flex-wrap" aria-label="مسیر صفحه">
|
||
<?php foreach ( $crumbs as $index => $crumb ) :
|
||
$is_last = ( $index === count( $crumbs ) - 1 );
|
||
?>
|
||
<?php if ( ! $is_last ) : ?>
|
||
<a href="<?php echo esc_url( $crumb['url'] ); ?>" class="hover:text-forest-500 dark:hover:text-forest-300 transition"><?php echo esc_html( $crumb['name'] ); ?></a>
|
||
<iconify-icon icon="lucide:chevron-left" width="14"></iconify-icon>
|
||
<?php else : ?>
|
||
<span class="text-earth-400 dark:text-dark-text font-medium"><?php echo esc_html( $crumb['name'] ); ?></span>
|
||
<?php endif; ?>
|
||
<?php endforeach; ?>
|
||
</nav>
|
||
<script type="application/ld+json"><?php echo wp_json_encode( $breadcrumb_schema ); ?></script>
|
||
<?php endif; ?>
|
||
|
||
<!-- ===== SHOP CONTENT ===== -->
|
||
<section class="pb-8 md:pb-12 bg-cream-100 dark:bg-dark-bg" aria-label="محصولات فروشگاه">
|
||
<div class="max-w-7xl mx-auto px-4 md:px-6">
|
||
<!-- دکمه toggle فیلتر در موبایل -->
|
||
<button id="filter-toggle"
|
||
class="lg:hidden w-full mb-4 flex items-center justify-center gap-2 py-3 bg-white dark:bg-dark-card rounded-xl border border-cream-200 dark:border-dark-border text-sm font-medium hover:bg-cream-50 dark:hover:bg-dark-bg transition"
|
||
aria-label="نمایش فیلترها"
|
||
aria-expanded="false"
|
||
aria-controls="shop-sidebar">
|
||
<iconify-icon icon="lucide:sliders-horizontal" width="18"></iconify-icon>
|
||
<span>فیلترها</span>
|
||
<iconify-icon icon="lucide:chevron-down" width="16" class="transition-transform" id="filter-toggle-icon"></iconify-icon>
|
||
</button>
|
||
|
||
<div class="flex flex-col lg:flex-row gap-8">
|
||
<!-- Sidebar -->
|
||
<aside id="shop-sidebar"
|
||
class="lg:w-1/4 xl:w-1/5 flex-shrink-0 <?php echo $has_shop_sidebar ? '' : 'hidden lg:block'; ?> lg:!block"
|
||
aria-label="فیلترهای فروشگاه">
|
||
<div class="bg-white dark:bg-dark-card rounded-2xl p-5 border border-cream-200/50 dark:border-dark-border/50 lg:sticky lg:top-28">
|
||
<?php if ( $has_shop_sidebar ) : ?>
|
||
<?php dynamic_sidebar( 'sidebar-shop' ); ?>
|
||
<?php else : ?>
|
||
<!-- ===== پیشفرض: دستهبندیها ===== -->
|
||
<div class="mb-6">
|
||
<h3 class="font-bold text-sm mb-3 text-earth-400 dark:text-dark-text">دستهبندی محصولات</h3>
|
||
<ul class="space-y-2 text-sm">
|
||
<?php
|
||
$product_categories = get_terms( array(
|
||
'taxonomy' => 'product_cat',
|
||
'hide_empty' => true,
|
||
'parent' => 0,
|
||
) );
|
||
if ( ! empty( $product_categories ) && ! is_wp_error( $product_categories ) ) {
|
||
foreach ( $product_categories as $cat ) {
|
||
$count = motayeb_count_category_products( $cat->term_id );
|
||
$is_active = ( $is_category && $current_term && $current_term->term_id === $cat->term_id );
|
||
echo '<li><a href="' . esc_url( get_term_link( $cat ) ) . '" class="text-cream-500 dark:text-dark-muted hover:text-forest-500 dark:hover:text-forest-300 transition flex items-center justify-between py-1.5 px-2 rounded-lg ' . ( $is_active ? 'bg-forest-50 dark:bg-forest-900/30 text-forest-500 dark:text-forest-300 font-medium' : '' ) . '">';
|
||
echo '<span>' . esc_html( $cat->name ) . '</span>';
|
||
echo '<span class="text-xs bg-cream-100 dark:bg-dark-bg px-2 py-0.5 rounded-full">' . esc_html( motayeb_fa_count( $count ) ) . '</span>';
|
||
echo '</a></li>';
|
||
}
|
||
} else {
|
||
echo '<li class="text-cream-400 dark:text-dark-muted text-xs">هیچ دستهبندی وجود ندارد.</li>';
|
||
}
|
||
?>
|
||
</ul>
|
||
</div>
|
||
|
||
<!-- ===== فیلتر قیمت ===== -->
|
||
<div>
|
||
<h3 class="font-bold text-sm mb-3 text-earth-400 dark:text-dark-text">فیلتر قیمت</h3>
|
||
<form method="get" action="<?php echo esc_url( wc_get_page_permalink( 'shop' ) ); ?>">
|
||
<div class="flex items-center gap-2 mb-3">
|
||
<input type="number" name="min_price" placeholder="حداقل" min="0"
|
||
value="<?php echo esc_attr( isset( $_GET['min_price'] ) ? intval( $_GET['min_price'] ) : '' ); ?>"
|
||
class="w-1/2 px-3 py-2 bg-cream-50 dark:bg-dark-bg border border-cream-200 dark:border-dark-border rounded-xl text-sm outline-none focus:border-forest-500 dark:focus:border-forest-300 transition placeholder:text-cream-400 dark:placeholder:text-dark-muted">
|
||
<span class="text-cream-400 dark:text-dark-muted">تا</span>
|
||
<input type="number" name="max_price" placeholder="حداکثر" min="0"
|
||
value="<?php echo esc_attr( isset( $_GET['max_price'] ) ? intval( $_GET['max_price'] ) : '' ); ?>"
|
||
class="w-1/2 px-3 py-2 bg-cream-50 dark:bg-dark-bg border border-cream-200 dark:border-dark-border rounded-xl text-sm outline-none focus:border-forest-500 dark:focus:border-forest-300 transition placeholder:text-cream-400 dark:placeholder:text-dark-muted">
|
||
</div>
|
||
<button type="submit" class="w-full py-2 bg-forest-500 text-white rounded-xl text-sm font-medium hover:bg-forest-600 transition">اعمال فیلتر</button>
|
||
</form>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- Product Grid -->
|
||
<div class="lg:w-3/4 xl:w-4/5">
|
||
<!-- Toolbar -->
|
||
<div class="flex flex-wrap items-center justify-between gap-4 mb-6 bg-white dark:bg-dark-card rounded-2xl p-4 border border-cream-200/50 dark:border-dark-border/50 motayeb-shop-toolbar">
|
||
<div class="flex items-center gap-3 text-sm text-cream-500 dark:text-dark-muted">
|
||
<span class="motayeb-result-count"><?php woocommerce_result_count(); ?></span>
|
||
</div>
|
||
<div class="flex items-center gap-3 motayeb-ordering">
|
||
<?php woocommerce_catalog_ordering(); ?>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- نمایش فیلترهای فعال -->
|
||
<?php
|
||
// نمایش فیلترهای فعال (اگه ووکامرس ساپورت کنه)
|
||
if ( function_exists( 'woocommerce_output_active_filters' ) ) {
|
||
echo '<div class="mb-4 motayeb-active-filters">';
|
||
the_widget( 'WC_Widget_Price_Filter' );
|
||
echo '</div>';
|
||
}
|
||
?>
|
||
|
||
<!-- Products -->
|
||
<?php if ( woocommerce_product_loop() ) : ?>
|
||
<div class="grid grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6 motayeb-products-grid">
|
||
<?php while ( have_posts() ) : the_post(); ?>
|
||
<?php wc_get_template_part( 'content', 'product' ); ?>
|
||
<?php endwhile; ?>
|
||
</div>
|
||
<div class="mt-10 motayeb-pagination">
|
||
<?php woocommerce_pagination(); ?>
|
||
</div>
|
||
<?php else : ?>
|
||
<div class="text-center py-16">
|
||
<iconify-icon icon="lucide:package-x" width="64" class="text-cream-400 dark:text-dark-muted mx-auto mb-4"></iconify-icon>
|
||
<p class="text-cream-500 dark:text-dark-muted mb-4">محصولی یافت نشد.</p>
|
||
<a href="<?php echo esc_url( get_permalink( wc_get_page_id( 'shop' ) ) ); ?>" class="inline-flex items-center gap-2 px-6 py-2.5 bg-forest-500 text-white rounded-xl text-sm hover:bg-forest-600 transition">
|
||
<iconify-icon icon="lucide:rotate-ccw" width="16"></iconify-icon>
|
||
<span>نمایش همه محصولات</span>
|
||
</a>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<script>
|
||
// toggle فیلتر در موبایل
|
||
(function() {
|
||
var btn = document.getElementById('filter-toggle');
|
||
var sidebar = document.getElementById('shop-sidebar');
|
||
var icon = document.getElementById('filter-toggle-icon');
|
||
if (!btn || !sidebar) return;
|
||
|
||
btn.addEventListener('click', function() {
|
||
var isHidden = sidebar.classList.contains('hidden');
|
||
if (isHidden) {
|
||
sidebar.classList.remove('hidden');
|
||
btn.setAttribute('aria-expanded', 'true');
|
||
if (icon) icon.style.transform = 'rotate(180deg)';
|
||
} else {
|
||
sidebar.classList.add('hidden');
|
||
btn.setAttribute('aria-expanded', 'false');
|
||
if (icon) icon.style.transform = '';
|
||
}
|
||
});
|
||
|
||
// روی دسکتاپ، همیشه visible
|
||
window.addEventListener('resize', function() {
|
||
if (window.innerWidth >= 1024) {
|
||
sidebar.classList.remove('hidden');
|
||
}
|
||
});
|
||
})();
|
||
</script>
|
||
|
||
<?php
|
||
get_footer();
|