@php $hasOffer = $product->effective_price !== null && bccomp($product->effective_price, $product->price, 2) < 0; $hasPurchased = auth()->check() && \App\Models\Order::where('user_id', auth()->id()) ->whereIn('status', ['paid', 'processing', 'shipped', 'delivered']) ->whereHas('items', fn ($q) => $q->where('product_id', $product->id)) ->exists(); // Solo se permite una reseña por cliente por producto (el backend hace // updateOrCreate, no duplica) — si ya dejó una, el formulario debe // mostrarla como "editar", no como si fuera una reseña nueva en blanco. $myReview = auth()->check() ? $product->reviews->firstWhere('user_id', auth()->id()) : null; $displayPrice = $hasOffer ? $product->effective_price : $product->price; $productImageUrl = $product->cover_image_path ? asset('storage/'.$product->cover_image_path) : 'https://placehold.co/600x600?text='.urlencode($product->title); // Antes, un producto sin NINGUNA fila de variante (dato incompleto: ni // siquiera la variante simple implícita) se marcaba "InStock" en el // JSON-LD sin más — quedaba publicado ante buscadores como disponible // aunque el propio widget de "Agregar al carrito" ya no deja comprarlo. $inStock = $product->variants->where('active', true)->sum(fn ($variant) => $variant->availableStock()) > 0; $jsonLd = [ '@context' => 'https://schema.org', '@type' => 'Product', 'name' => $product->title, 'description' => $product->description ?? $product->subtitle, 'image' => [$productImageUrl], 'offers' => [ '@type' => 'Offer', 'url' => route('products.show', $product), 'priceCurrency' => 'PEN', 'price' => number_format((float) $displayPrice, 2, '.', ''), 'availability' => $inStock ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock', ], ]; if ($averageRating) { $jsonLd['aggregateRating'] = [ '@type' => 'AggregateRating', 'ratingValue' => round($averageRating, 1), 'reviewCount' => $product->reviews->count(), ]; } @endphp
@if ($product->images->isNotEmpty())
@foreach ($product->images as $image)
@endforeach
@endif

{{ $product->title }}

@if ($product->subtitle)

{{ $product->subtitle }}

@endif @if ($averageRating)

{{ str_repeat('★', round($averageRating)) }}{{ str_repeat('☆', 5 - round($averageRating)) }} ({{ $product->reviews->count() }} reseñas)

@endif
@if ($hasOffer) S/ {{ number_format($product->effective_price, 2) }} S/ {{ number_format($product->price, 2) }} @else S/ {{ number_format($product->price, 2) }} @endif
@livewire('storefront.add-to-cart', ['product' => $product])
@livewire('storefront.wishlist-button', ['product' => $product])
@php $productWhatsappLink = \App\Models\StoreSetting::first() ?->whatsappLink('Hola, tengo una consulta sobre '.$product->title.' ('.route('products.show', $product).')'); @endphp @if ($productWhatsappLink) ¿Dudas sobre este producto? Escríbenos por WhatsApp @endif @if ($product->description)
{{ $product->description }}
@endif

Reseñas

@if ($product->reviews->isEmpty())

Este producto todavía no tiene reseñas.

@else
@foreach ($product->reviews as $review)
{{ $review->user->name }} {{ str_repeat('★', $review->rating) }}{{ str_repeat('☆', 5 - $review->rating) }}
@if ($review->comment)

{{ $review->comment }}

@endif
@endforeach
@endif @auth @if ($hasPurchased)
@csrf

{{ $myReview ? 'Edita tu reseña' : 'Escribe tu reseña' }}

@if ($myReview)

Ya habías dejado una reseña de este producto — al publicar, se actualiza en vez de crear una nueva.

@endif
@else

Solo los clientes que compraron este producto pueden dejar una reseña.

@endif @else Inicia sesión para dejar una reseña @endauth
@if ($relatedProducts->isNotEmpty())

Productos relacionados

@foreach ($relatedProducts as $related) @include('catalog.partials.product-card', ['product' => $related]) @endforeach
@endif