@php $productImages = \App\Support\StorefrontPresenter::productImages($product); $defaultVariant = $product->variants->firstWhere('is_default', true) ?: $product->variants->first(); $selectedVariant = $defaultVariant; $price = $selectedVariant?->price ?? $product->base_price; $comparePrice = $selectedVariant?->compare_price ?? $product->compare_price; $hasDiscount = $comparePrice && (float) $comparePrice > (float) $price; $discountPercent = $hasDiscount ? (int) round((((float) $comparePrice - (float) $price) / max((float) $comparePrice, 1)) * 100) : null; $ratingCount = (int) ($product->reviews_count ?? $product->reviews->count()); $rating = $product->reviews_avg_rating && $ratingCount > 0 ? number_format((float) $product->reviews_avg_rating, 1) : null; $etaMinutes = $product->preparation_time_minutes ?: data_get($product->store?->meta, 'eta_minutes'); $etaLabel = $etaMinutes ? ((int) $etaMinutes.' mins') : (data_get($product->store?->meta, 'eta_label') ?: 'Available now'); $variantStock = $product->track_inventory ? (int) ($selectedVariant?->stock_quantity ?? $product->available_quantity ?? $product->stock_quantity ?? 0) : null; $stockLabel = $product->track_inventory ? ($variantStock <= 0 ? 'Out of stock' : ($variantStock <= 5 ? 'Only '.$variantStock.' left' : 'In stock')) : 'In stock'; $stockClass = $product->track_inventory ? ($variantStock <= 0 ? 'fm-stock-out' : ($variantStock <= 5 ? 'fm-stock-low' : 'fm-stock-in')) : 'fm-stock-in'; $cartKey = $product->id.':'.($selectedVariant?->id ?? 0); $cartEntry = $cartLookup[$cartKey] ?? null; $quantity = (int) data_get($cartEntry, 'quantity', 0); $cartItemId = data_get($cartEntry, 'cart_item_id'); $isWishlisted = in_array($product->id, $wishlistIds ?? [], true); $description = trim((string) ($product->description ?: $product->short_description)); $attributes = collect($product->attributes ?? [])->filter(fn ($value) => filled(is_array($value) ? json_encode($value) : $value)); $ingredientSource = $product->ingredients_translations[app()->getLocale()] ?? $product->ingredients_translations['en'] ?? $product->ingredients_translations ?? []; $ingredients = collect(is_array($ingredientSource) ? $ingredientSource : preg_split('/[,|\\n]+/', (string) $ingredientSource))->map(fn ($item) => trim((string) $item))->filter()->take(10)->values(); $tagSource = $product->tags_translations[app()->getLocale()] ?? $product->tags_translations['en'] ?? $product->tags_translations ?? []; $tags = collect(is_array($tagSource) ? $tagSource : preg_split('/[,|\\n]+/', (string) $tagSource))->map(fn ($item) => trim((string) $item))->filter()->take(8)->values(); $variantPayload = $product->variants->map(function ($variant) use ($product, $productImages, $cartLookup) { $variantImages = collect($variant->images ?? []) ->map(fn ($image) => \App\Support\StorefrontPresenter::mediaUrl($image) ?: $image) ->filter() ->values() ->all(); $images = count($variantImages) ? $variantImages : $productImages; $price = (float) ($variant->price ?? $product->base_price ?? 0); $compare = (float) ($variant->compare_price ?? $product->compare_price ?? 0); $cartKey = $product->id.':'.($variant->id ?? 0); $cartEntry = $cartLookup[$cartKey] ?? null; $stock = $product->track_inventory ? (int) ($variant->stock_quantity ?? 0) : null; return [ 'id' => $variant->id, 'name' => $variant->name ?: 'Default', 'display_name' => $variant->name ?: ($product->short_description ?: 'Standard pack'), 'price' => $price, 'price_label' => \App\Support\StorefrontPresenter::money($price), 'compare_price' => $compare > $price ? $compare : null, 'compare_label' => $compare > $price ? \App\Support\StorefrontPresenter::money($compare) : null, 'discount' => $compare > $price ? (int) round((($compare - $price) / max($compare, 1)) * 100) : null, 'stock' => $stock, 'stock_label' => $stock === null ? 'In stock' : ($stock <= 0 ? 'Out of stock' : ($stock <= 5 ? 'Only '.$stock.' left' : 'In stock')), 'stock_class' => $stock === null ? 'fm-stock-in' : ($stock <= 0 ? 'fm-stock-out' : ($stock <= 5 ? 'fm-stock-low' : 'fm-stock-in')), 'sku' => (string) ($variant->sku ?? ''), 'weight' => (string) ($variant->weight ?? ''), 'color' => (string) ($variant->color ?? ''), 'color_hex' => (string) ($variant->color_hex ?? ''), 'size' => (string) ($variant->size ?? ''), 'custom_attributes' => $variant->custom_attributes ?? [], 'images' => $images, 'cart_key' => $cartKey, 'cart_quantity' => (int) data_get($cartEntry, 'quantity', 0), 'cart_item_id' => data_get($cartEntry, 'cart_item_id'), 'is_out_of_stock' => $stock !== null && $stock <= 0, ]; })->values(); if ($variantPayload->isEmpty()) { $fallbackPrice = (float) ($product->base_price ?? 0); $fallbackCompare = (float) ($product->compare_price ?? 0); $cartEntry = $cartLookup[$product->id.':0'] ?? null; $variantPayload = collect([[ 'id' => null, 'name' => 'Default', 'display_name' => $product->short_description ?: 'Standard pack', 'price' => $fallbackPrice, 'price_label' => \App\Support\StorefrontPresenter::money($fallbackPrice), 'compare_price' => $fallbackCompare > $fallbackPrice ? $fallbackCompare : null, 'compare_label' => $fallbackCompare > $fallbackPrice ? \App\Support\StorefrontPresenter::money($fallbackCompare) : null, 'discount' => $fallbackCompare > $fallbackPrice ? (int) round((($fallbackCompare - $fallbackPrice) / max($fallbackCompare, 1)) * 100) : null, 'stock' => $product->track_inventory ? (int) ($product->available_quantity ?? $product->stock_quantity ?? 0) : null, 'stock_label' => $product->track_inventory && (int) ($product->available_quantity ?? $product->stock_quantity ?? 0) <= 0 ? 'Out of stock' : 'In stock', 'stock_class' => $product->track_inventory && (int) ($product->available_quantity ?? $product->stock_quantity ?? 0) <= 0 ? 'fm-stock-out' : 'fm-stock-in', 'sku' => (string) ($product->sku ?? ''), 'weight' => '', 'color' => '', 'color_hex' => '', 'size' => '', 'custom_attributes' => [], 'images' => $productImages, 'cart_key' => $product->id.':0', 'cart_quantity' => (int) data_get($cartEntry, 'quantity', 0), 'cart_item_id' => data_get($cartEntry, 'cart_item_id'), 'is_out_of_stock' => $product->track_inventory && (int) ($product->available_quantity ?? $product->stock_quantity ?? 0) <= 0, ]]); } $initialImages = $variantPayload->first()['images'] ?: $productImages; $initialImage = $initialImages[0] ?? null; // Store URL $storeUrl = $product->store ? route('storefront.stores.show', ['store' => $product->store] + ($storefrontQuery ?? [])) : '#'; // Brand URL $brandUrl = $product->brand ? route('storefront.search', array_merge($storefrontQuery ?? [], ['brand' => $product->brand->slug])) : '#'; @endphp
{{-- ===== BREADCRUMB ===== --}} {{-- ===== HERO ===== --}}
{{-- Top Actions --}}
@auth @else @endauth
{{-- Discount Badge --}} @if($discountPercent) {{ $discountPercent }}%OFF @else @endif {{-- Main Image --}}
@if($initialImage) {{ $product->name }} @else
{{ Str::upper(Str::substr($product->name, 0, 1)) }} {{ $product->category?->name ?? trans_key('storefront.fallbacks.product') }}
@endif
{{-- Thumbnails --}} @if(count($initialImages) > 1)
@foreach($initialImages as $index => $galleryImage) @endforeach
@endif
{{-- Summary --}}
@if($etaLabel) {{ $etaLabel }} @endif @if($rating) {{ $rating }} ({{ $ratingCount }}) @endif

{{ $product->name }}

{{ $selectedVariant?->name ?: ($product->short_description ?: $product->category?->name) }}

{{ \App\Support\StorefrontPresenter::money($price) }} @if($hasDiscount) {{ \App\Support\StorefrontPresenter::money($comparePrice) }} Save {{ \App\Support\StorefrontPresenter::money((float) $comparePrice - (float) $price) }} @else @endif
{{ $stockLabel }} @if($selectedVariant?->sku) SKU {{ $selectedVariant->sku }} @else @endif @if($selectedVariant?->weight) {{ $selectedVariant->weight }} @else @endif
{{-- ===== HIGHLIGHTS ===== --}}
Returns 24 hrs
{{-- ===== VARIANTS ===== --}} @if($variantPayload->count() > 1)

Select variant

@foreach($variantPayload as $variant) @endforeach
@endif {{-- ===== OFFERS ===== --}} @if(($productCoupons ?? collect())->count() || ($productPromotions ?? collect())->count())

Available offers

@foreach(($productCoupons ?? collect())->take(3) as $coupon)
{{ $coupon->code }} {{ $coupon->title ?: \App\Support\StorefrontPresenter::couponDiscountLabel($coupon) }}

{{ \App\Support\StorefrontPresenter::couponMinimumLabel($coupon) }}

@endforeach @foreach(($productPromotions ?? collect())->take(2) as $promotion)
Offer {{ $promotion->title }}

{{ $promotion->subtitle ?: 'Limited time seller promotion.' }}

@endforeach
@endif {{-- ===== DESCRIPTION ===== --}} @if($description || $tags->isNotEmpty() || $ingredients->isNotEmpty())

Product details

@if($description)

{{ $description }}

@endif @if($tags->isNotEmpty())
@foreach($tags as $tag) {{ $tag }} @endforeach
@endif @if($ingredients->isNotEmpty())

Ingredients

@foreach($ingredients as $ingredient) {{ $ingredient }} @endforeach
@endif
@endif {{-- ===== RELATED PRODUCTS ===== --}} @if(($relatedProducts ?? collect())->count()) @endif
{{-- ===== BOTTOM PURCHASE BAR ===== --}}
{{ $selectedVariant?->name ?: 'Selected item' }} {{ \App\Support\StorefrontPresenter::money($price) }}
@auth
@csrf @if($variantStock !== null && $variantStock <= 0) @elseif($quantity > 0 && $cartItemId)
{{ $quantity }}
@else @endif
@else Sign in to buy @endauth
{{-- ===== DETAILS POPUP ===== --}} @if($product->brand) {{-- ===== BRAND POPUP ===== --}} @endif