motayeb/single-product.php
Kazem Alghasi c06ab0b8a2 feat(theme): implement full UI redesign and WooCommerce integration
Implement a complete overhaul of the theme templates to match the
Kolli UI design, including enhanced WooCommerce support, dark mode
functionality, and improved responsive layouts.

- Redesign core templates: front-page, archive, single, and product pages
- Implement dynamic WooCommerce templates for shop, single product, and checkout
- Add comprehensive asset structure including fonts, images, and custom CSS/JS
- Integrate Tailwind CSS via CDN with custom configuration for brand colors
- Add dark mode support with local storage persistence
- Refactor functions.php for better theme setup and script enqueuing
- Implement custom product meta fields for ingredients and health benefits
- Add responsive design improvements and custom animations
2026-08-18 02:28:57 +03:30

270 lines
17 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* صفحه تک محصول - مطابق با UI Kolli.html
* با پشتیبانی از محصولات ساده و متغیر + ترکیبات و خواص سلامت (متافیلد دستی)
*
* @package Motayeb
*/
get_header();
while ( have_posts() ) : the_post();
global $product;
$gallery_images = $product->get_gallery_image_ids();
$main_image = wp_get_attachment_image_src( get_post_thumbnail_id(), 'full' );
$main_img_src = $main_image ? $main_image[0] : 'https://picsum.photos/seed/' . get_the_ID() . '/600/600.jpg';
// دریافت متافیلدهای دستی
$ingredients = get_post_meta( get_the_ID(), '_ingredients', true );
$benefits = get_post_meta( get_the_ID(), '_health_benefits', true );
$benefits_title = get_post_meta( get_the_ID(), '_health_benefits_title', true );
if ( empty( $benefits_title ) ) {
$benefits_title = 'خواص سلامت';
}
?>
<!-- ===== PRODUCT DETAIL ===== -->
<section class="py-8 md:py-16 bg-cream-100 dark:bg-dark-bg">
<div class="max-w-7xl mx-auto px-4 md:px-6">
<!-- Breadcrumb -->
<div class="mb-6 text-sm text-cream-500 dark:text-dark-muted">
<?php woocommerce_breadcrumb(); ?>
</div>
<div class="grid md:grid-cols-2 gap-8 md:gap-12">
<!-- Gallery -->
<div>
<div class="relative rounded-2xl overflow-hidden bg-white dark:bg-dark-card border border-cream-200/50 dark:border-dark-border/50 mb-3">
<img id="main-product-img" src="<?php echo esc_url( $main_img_src ); ?>" alt="<?php the_title_attribute(); ?>" class="w-full h-[350px] md:h-[450px] object-cover zoom-lens">
<div class="absolute top-3 right-3 flex flex-col gap-2">
<?php if ( $product->is_featured() ) : ?>
<span class="px-3 py-1 bg-forest-500 text-white text-xs rounded-full font-medium">ارگانیک</span>
<?php endif; ?>
<?php if ( $product->is_on_sale() ) : ?>
<span class="px-3 py-1 bg-red-500 text-white text-xs rounded-full font-medium">تخفیف ویژه</span>
<?php endif; ?>
</div>
<button onclick="toggleWishlist(this)" class="absolute top-3 left-3 w-10 h-10 bg-white/80 dark:bg-dark-card/80 backdrop-blur rounded-full flex items-center justify-center hover:scale-110 transition">
<iconify-icon icon="lucide:heart" width="20" class="text-cream-500"></iconify-icon>
</button>
</div>
<!-- Thumbnails -->
<?php if ( ! empty( $gallery_images ) ) : ?>
<div class="flex gap-2 overflow-x-auto pb-1">
<button onclick="changeImage('<?php echo esc_js( $main_img_src ); ?>', this)" class="gallery-thumb active w-20 h-20 rounded-xl overflow-hidden border-2 border-transparent flex-shrink-0">
<img src="<?php echo esc_url( $main_img_src ); ?>" class="w-full h-full object-cover">
</button>
<?php foreach ( $gallery_images as $image_id ) :
$image_url = wp_get_attachment_image_src( $image_id, 'thumbnail' );
$image_full = wp_get_attachment_image_src( $image_id, 'full' );
if ( ! $image_url ) continue;
?>
<button onclick="changeImage('<?php echo esc_js( $image_full[0] ); ?>', this)" class="gallery-thumb w-20 h-20 rounded-xl overflow-hidden border-2 border-transparent flex-shrink-0">
<img src="<?php echo esc_url( $image_url[0] ); ?>" class="w-full h-full object-cover">
</button>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<!-- Product Info -->
<div>
<div class="flex items-center gap-2 mb-3">
<span class="text-xs text-cream-500 dark:text-dark-muted">برند: مطیب</span>
<span class="w-1 h-1 bg-cream-400 rounded-full"></span>
<span class="flex items-center gap-0.5 text-honey-400 text-sm">
<?php echo motayeb_get_rating_html( $product->get_average_rating(), $product->get_rating_count() ); ?>
</span>
</div>
<h1 class="text-2xl md:text-3xl font-extrabold mb-3"><?php the_title(); ?></h1>
<p class="text-cream-500 dark:text-dark-muted text-sm leading-relaxed mb-5"><?php echo wp_kses_post( $product->get_short_description() ); ?></p>
<!-- Stock -->
<?php if ( $product->is_in_stock() ) : ?>
<div class="flex items-center gap-2 mb-5">
<span class="w-2 h-2 bg-emerald-500 rounded-full"></span>
<span class="text-sm text-emerald-600 dark:text-emerald-400 font-medium">موجود در انبار</span>
</div>
<?php else : ?>
<div class="flex items-center gap-2 mb-5">
<span class="w-2 h-2 bg-red-500 rounded-full"></span>
<span class="text-sm text-red-600 dark:text-red-400 font-medium">ناموجود</span>
</div>
<?php endif; ?>
<!-- Price -->
<div class="flex items-end gap-3 mb-6">
<span class="text-3xl font-extrabold text-forest-500 dark:text-forest-300"><?php echo wp_kses_post( $product->get_price_html() ); ?></span>
<?php if ( $product->is_on_sale() ) : ?>
<span class="line-through text-sm text-cream-400 dark:text-dark-muted"><?php echo wp_kses_post( wc_price( $product->get_regular_price() ) ); ?></span>
<?php endif; ?>
</div>
<!-- ===== ویژگی‌های محصول (Attributes) ===== -->
<?php
$attributes = $product->get_attributes();
if ( ! empty( $attributes ) && $product->is_type( 'simple' ) ) :
?>
<div class="mb-6">
<h3 class="text-sm font-bold mb-3 text-earth-400 dark:text-dark-text">ویژگی‌های محصول</h3>
<div class="grid grid-cols-2 gap-3">
<?php foreach ( $attributes as $attribute ) :
$values = wc_get_product_terms( $product->get_id(), $attribute->get_name(), array( 'fields' => 'names' ) );
if ( empty( $values ) ) continue;
?>
<div class="bg-cream-50 dark:bg-dark-bg rounded-xl p-3 text-center">
<span class="text-xs text-cream-500 dark:text-dark-muted"><?php echo esc_html( wc_attribute_label( $attribute->get_name() ) ); ?></span>
<div class="font-bold text-sm mt-1"><?php echo esc_html( implode( ', ', $values ) ); ?></div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<!-- ===== دکمه افزودن به سبد (پشتیبانی از محصولات متغیر) ===== -->
<?php if ( $product->is_type( 'variable' ) ) : ?>
<div class="mb-6">
<?php woocommerce_template_single_add_to_cart(); ?>
</div>
<?php else : ?>
<div class="flex items-center gap-4 mb-6">
<label class="text-sm font-bold">تعداد:</label>
<div class="flex items-center border-2 border-cream-200 dark:border-dark-border rounded-xl overflow-hidden">
<button onclick="changeQty(-1)" class="w-10 h-10 flex items-center justify-center hover:bg-cream-100 dark:hover:bg-dark-bg transition">
<iconify-icon icon="lucide:minus" width="16"></iconify-icon>
</button>
<span id="product-qty" class="w-12 h-10 flex items-center justify-center font-bold text-sm border-x-2 border-cream-200 dark:border-dark-border">1</span>
<button onclick="changeQty(1)" class="w-10 h-10 flex items-center justify-center hover:bg-cream-100 dark:hover:bg-dark-bg transition">
<iconify-icon icon="lucide:plus" width="16"></iconify-icon>
</button>
</div>
</div>
<div class="flex gap-3 mb-6">
<button onclick="addToCartDetail(<?php echo esc_js( $product->get_id() ); ?>)" class="flex-1 py-3.5 bg-forest-500 text-white rounded-2xl font-bold hover:bg-forest-600 hover:-translate-y-0.5 transition-all shadow-lg shadow-forest-500/25 flex items-center justify-center gap-2">
<iconify-icon icon="lucide:shopping-bag" width="20"></iconify-icon>
<span>افزودن به سبد خرید</span>
</button>
<button onclick="toggleWishlist(this)" class="w-14 h-14 border-2 border-cream-200 dark:border-dark-border rounded-2xl flex items-center justify-center hover:border-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 transition">
<iconify-icon icon="lucide:heart" width="22" class="text-cream-400"></iconify-icon>
</button>
</div>
<?php endif; ?>
<!-- Delivery Info -->
<div class="bg-cream-50 dark:bg-dark-bg rounded-2xl p-4 space-y-3">
<div class="flex items-center gap-3 text-sm">
<iconify-icon icon="lucide:truck" width="18" class="text-forest-500 dark:text-forest-300"></iconify-icon>
<span>ارسال به تمامی نقاط کشور</span>
</div>
<div class="flex items-center gap-3 text-sm">
<iconify-icon icon="lucide:rotate-ccw" width="18" class="text-forest-500 dark:text-forest-300"></iconify-icon>
<span>ضمانت بازگشت ۷ روزه</span>
</div>
<div class="flex items-center gap-3 text-sm">
<iconify-icon icon="lucide:shield-check" width="18" class="text-forest-500 dark:text-forest-300"></iconify-icon>
<span>ضمانت اصالت و کیفیت</span>
</div>
</div>
</div>
</div>
<!-- ===== PRODUCT TABS ===== -->
<div class="mt-12 border-t border-cream-200 dark:border-dark-border pt-8">
<div class="flex gap-6 border-b border-cream-200 dark:border-dark-border mb-6 overflow-x-auto">
<button onclick="switchTab('desc', this)" class="tab-btn tab-active pb-3 text-sm font-bold border-b-2 border-transparent whitespace-nowrap transition">توضیحات</button>
<button onclick="switchTab('additional', this)" class="tab-btn pb-3 text-sm font-bold border-b-2 border-transparent text-cream-500 dark:text-dark-muted whitespace-nowrap transition">اطلاعات بیشتر</button>
<?php if ( ! empty( $ingredients ) ) : ?>
<button onclick="switchTab('ingredients', this)" class="tab-btn pb-3 text-sm font-bold border-b-2 border-transparent text-cream-500 dark:text-dark-muted whitespace-nowrap transition">ترکیبات</button>
<?php endif; ?>
<?php if ( ! empty( $benefits ) && is_array( $benefits ) ) : ?>
<button onclick="switchTab('benefits', this)" class="tab-btn pb-3 text-sm font-bold border-b-2 border-transparent text-cream-500 dark:text-dark-muted whitespace-nowrap transition"><?php echo esc_html( $benefits_title ); ?></button>
<?php endif; ?>
<button onclick="switchTab('reviews', this)" class="tab-btn pb-3 text-sm font-bold border-b-2 border-transparent text-cream-500 dark:text-dark-muted whitespace-nowrap transition">نظرات (<?php echo esc_html( $product->get_rating_count() ); ?>)</button>
</div>
<!-- تب توضیحات -->
<div id="tab-desc" class="tab-content">
<div class="max-w-3xl prose prose-sm dark:prose-invert text-cream-500 dark:text-dark-muted leading-relaxed">
<?php the_content(); ?>
</div>
</div>
<!-- تب اطلاعات بیشتر -->
<div id="tab-additional" class="tab-content hidden">
<div class="max-w-3xl">
<?php do_action( 'woocommerce_product_additional_information', $product ); ?>
</div>
</div>
<!-- ===== ترکیبات (از متافیلد) ===== -->
<?php if ( ! empty( $ingredients ) ) : ?>
<div id="tab-ingredients" class="tab-content hidden">
<div class="max-w-3xl prose prose-sm dark:prose-invert text-cream-500 dark:text-dark-muted leading-relaxed">
<?php echo wp_kses_post( $ingredients ); ?>
</div>
</div>
<?php endif; ?>
<!-- ===== خواص سلامت (از متافیلد آرایه‌ای با آیکون انتخابی) ===== -->
<?php if ( ! empty( $benefits ) && is_array( $benefits ) ) : ?>
<div id="tab-benefits" class="tab-content hidden">
<div class="max-w-3xl grid md:grid-cols-2 gap-4">
<?php foreach ( $benefits as $item ) :
$icon = isset( $item['icon'] ) && ! empty( $item['icon'] ) ? $item['icon'] : 'heart-pulse';
$color = isset( $item['color'] ) && ! empty( $item['color'] ) ? $item['color'] : 'text-red-400';
?>
<div class="flex items-start gap-3 p-4 bg-cream-50 dark:bg-dark-bg rounded-xl">
<iconify-icon icon="lucide:<?php echo esc_attr( $icon ); ?>" width="20" class="<?php echo esc_attr( $color ); ?> mt-0.5 flex-shrink-0"></iconify-icon>
<div>
<div class="font-bold text-sm mb-1"><?php echo esc_html( $item['title'] ); ?></div>
<p class="text-xs text-cream-500 dark:text-dark-muted"><?php echo esc_html( $item['description'] ); ?></p>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<!-- تب نظرات -->
<div id="tab-reviews" class="tab-content hidden">
<div class="max-w-3xl">
<?php comments_template(); ?>
</div>
</div>
</div>
<!-- ===== RELATED PRODUCTS ===== -->
<?php
$related = wc_get_related_products( $product->get_id(), 4 );
if ( ! empty( $related ) ) : ?>
<div class="mt-16">
<h3 class="text-xl font-bold mb-6">محصولات مرتبط</h3>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<?php foreach ( $related as $related_id ) :
$related_product = wc_get_product( $related_id );
if ( ! $related_product ) continue;
$image = wp_get_attachment_image_src( $related_product->get_image_id(), 'medium' );
$img_src = $image ? $image[0] : 'https://picsum.photos/seed/' . $related_id . '/300/300.jpg';
?>
<div class="product-card bg-cream-50 dark:bg-dark-bg rounded-2xl p-4 text-center group cursor-pointer border border-cream-200/50 dark:border-dark-border/50 hover:shadow-lg transition">
<a href="<?php echo esc_url( get_permalink( $related_id ) ); ?>">
<img src="<?php echo esc_url( $img_src ); ?>" class="product-img w-full h-32 object-cover rounded-xl mb-3">
<h4 class="font-bold text-sm line-clamp-2"><?php echo esc_html( $related_product->get_name() ); ?></h4>
<div class="text-forest-500 dark:text-forest-300 font-bold text-sm mt-2"><?php echo wp_kses_post( $related_product->get_price_html() ); ?></div>
</a>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
</div>
</section>
<?php
endwhile;
get_footer();