✏️ 编辑:product.blade.php
路径:
/home/boguraj1/.trash/product.blade.php
大小:11.8 KB · 修改:2026-07-23 16:13:46 · 权限:0644 · 可写
← 返回目录
👁 查看
⬇ 下载
@extends('layouts.app') @section('title', $product->name) @section('meta_description', $product->short_description) @section('extra-styles') .gallery-thumb { width:70px;height:70px;object-fit:cover;border:2px solid #eee;border-radius:6px;cursor:pointer;transition:.2s; } .gallery-thumb:hover,.gallery-thumb.active { border-color:var(--primary); } .main-product-img { width:100%;height:420px;object-fit:cover;border-radius:10px; } .variation-btn { border:2px solid #ddd;background:#fff;border-radius:6px;padding:6px 14px;font-size:13px;font-weight:500;cursor:pointer;transition:.2s; } .variation-btn:hover,.variation-btn.selected { border-color:var(--primary);color:var(--primary); } .price-regular { font-size:28px;font-weight:700;color:var(--primary); } .price-old { font-size:18px;text-decoration:line-through;color:#999; } .badge-offer { background:var(--primary);color:#fff;padding:4px 12px;border-radius:20px;font-size:12px;font-weight:600; } .qty-btn { width:36px;height:36px;border:1px solid #ddd;background:#f8f9fa;border-radius:6px;font-size:18px;line-height:1;cursor:pointer; } .qty-input { width:60px;text-align:center;border:1px solid #ddd;border-radius:6px;height:36px;font-weight:600; } @endsection @section('content') <div class="container py-5"> {{-- BREADCRUMB --}} <nav aria-label="breadcrumb" class="mb-4"> <ol class="breadcrumb"> <li class="breadcrumb-item"><a href="{{ route('home') }}" class="text-decoration-none">Home</a></li> @if($product->category) <li class="breadcrumb-item"><a href="{{ route('shop', ['category' => $product->category->slug]) }}" class="text-decoration-none">{{ $product->category->name }}</a></li> @endif <li class="breadcrumb-item active">{{ $product->name }}</li> </ol> </nav> <div class="row g-5"> {{-- PRODUCT IMAGES --}} <div class="col-lg-5"> <img id="mainImage" src="{{ $product->thumbnail_url }}" alt="{{ $product->name }}" class="main-product-img mb-3"> @if($product->images->count() > 0) <div class="d-flex gap-2 flex-wrap"> <img src="{{ $product->thumbnail_url }}" alt="Main" class="gallery-thumb active" onclick="changeImage(this, '{{ $product->thumbnail_url }}')"> @foreach($product->images as $img) <img src="{{ $img->image_url }}" alt="Gallery" class="gallery-thumb" onclick="changeImage(this, '{{ $img->image_url }}')"> @endforeach </div> @endif </div> {{-- PRODUCT DETAILS --}} <div class="col-lg-7"> @if($product->category) <span class="badge bg-secondary mb-2">{{ $product->category->name }}</span> @endif <h1 style="font-size:24px;font-weight:700;color:var(--dark)">{{ $product->name }}</h1> {{-- PRICE --}} <div class="d-flex align-items-center gap-3 my-3"> @if($product->is_on_sale) <span class="price-regular">৳{{ number_format($product->sale_price, 0) }}</span> <span class="price-old">৳{{ number_format($product->regular_price, 0) }}</span> @php $discount = round((($product->regular_price - $product->sale_price) / $product->regular_price) * 100); @endphp <span class="badge-offer">{{ $discount }}% OFF</span> @else <span class="price-regular">৳{{ number_format($product->regular_price, 0) }}</span> @endif </div> @if($product->offer_text) <div class="alert alert-warning py-2 d-inline-block"> <i class="bi bi-tag-fill me-1"></i> {{ $product->offer_text }} </div> @endif @if($product->short_description) <p class="text-muted mb-3">{{ $product->short_description }}</p> @endif <div class="mb-2"> <span class="{{ $product->stock > 0 ? 'text-success' : 'text-danger' }} fw-semibold"> <i class="bi bi-{{ $product->stock > 0 ? 'check-circle' : 'x-circle' }} me-1"></i> {{ $product->stock > 0 ? 'In Stock' : 'Out of Stock' }} </span> </div> {{-- VARIATIONS --}} @if($product->variations->count() > 0) @php $variationGroups = $product->variations->groupBy('type'); @endphp <div class="mb-4"> @foreach($variationGroups as $type => $variations) <div class="mb-3"> <label class="fw-semibold mb-2 d-block" style="color:var(--dark)">{{ ucfirst($type) }}:</label> <div class="d-flex gap-2 flex-wrap" data-variation-type="{{ $type }}"> @foreach($variations as $v) <button type="button" class="variation-btn" data-variation-id="{{ $v->id }}" data-price-adj="{{ $v->price_adjustment }}" onclick="selectVariation(this)"> {{ $v->value }} @if($v->price_adjustment > 0) (+৳{{ number_format($v->price_adjustment,0) }}) @endif </button> @endforeach </div> </div> @endforeach </div> @endif {{-- QUANTITY --}} <div class="mb-4"> <label class="fw-semibold mb-2 d-block" style="color:var(--dark)">Quantity:</label> <div class="d-flex align-items-center gap-2"> <button class="qty-btn" onclick="changeQty(-1)">−</button> <input type="number" id="quantity" value="1" min="1" max="{{ $product->stock }}" class="qty-input"> <button class="qty-btn" onclick="changeQty(1)">+</button> </div> </div> {{-- BUTTONS --}} @if($product->stock > 0) <div class="d-flex gap-3 flex-wrap"> <form action="{{ route('cart.add') }}" method="POST"> @csrf <input type="hidden" name="product_id" value="{{ $product->id }}"> <input type="hidden" name="variation_id" id="cart-variation-id" value=""> <input type="hidden" name="quantity" id="cart-quantity" value="1"> <button type="submit" class="btn btn-outline-danger btn-lg px-4"> <i class="bi bi-cart-plus me-2"></i>Add to Cart </button> </form> <form action="{{ route('buy.now') }}" method="POST"> @csrf <input type="hidden" name="product_id" value="{{ $product->id }}"> <input type="hidden" name="variation_id" id="buynow-variation-id" value=""> <input type="hidden" name="quantity" id="buynow-quantity" value="1"> <button type="submit" class="btn btn-danger btn-lg px-4"> <i class="bi bi-lightning-fill me-2"></i>Buy Now </button> </form> </div> @else <button class="btn btn-secondary btn-lg px-4" disabled>Out of Stock</button> @endif {{-- TAGS --}} @if($product->tags->count() > 0) <div class="mt-4"> <span class="fw-semibold me-2">Tags:</span> @foreach($product->tags as $tag) <span class="badge bg-light text-dark border me-1">{{ $tag->name }}</span> @endforeach </div> @endif </div> </div> {{-- DESCRIPTION TABS --}} @if($product->description) <div class="mt-5"> <ul class="nav nav-tabs" id="productTabs"> <li class="nav-item"> <button class="nav-link active fw-semibold" data-bs-toggle="tab" data-bs-target="#desc">Description</button> </li> </ul> <div class="tab-content border border-top-0 p-4 rounded-bottom"> <div class="tab-pane fade show active" id="desc"> {!! nl2br(e($product->description)) !!} </div> </div> </div> @endif {{-- RELATED PRODUCTS --}} @if($related->count() > 0) <div class="mt-5"> <h3 class="section-title">Related Products</h3> <div class="row row-cols-2 row-cols-sm-3 row-cols-md-4 row-cols-lg-5 g-3"> @foreach($related as $rp) <div class="col"> <div class="product-card h-100"> <a href="{{ route('product.show', $rp->slug) }}"> <img src="{{ $rp->thumbnail_url }}" alt="{{ $rp->name }}" loading="lazy"> </a> <div class="card-body"> <p class="product-title">{{ $rp->name }}</p> <div class="mb-2"> <span style="font-weight:700;color:var(--primary)">৳{{ number_format($rp->current_price, 0) }}</span> </div> <a href="{{ route('product.show', $rp->slug) }}" class="btn-buy d-block text-center text-decoration-none">Buy Now</a> </div> </div> </div> @endforeach </div> </div> @endif </div> @endsection @section('scripts') <script> {{-- Meta Pixel: ViewContent (eventID matches server CAPI for deduplication) --}} @if(!empty($settings['facebook_pixel_id'])) fbq('track', 'ViewContent', { content_name: '{{ addslashes($product->name) }}', content_ids: ['{{ $product->id }}'], content_type: 'product', value: {{ $product->sale_price ?? $product->regular_price ?? 0 }}, currency: 'BDT' }, { eventID: '{{ $pixelEventId ?? "" }}' }); @endif {{-- Meta Pixel: AddToCart (fires when Add to Cart button clicked) --}} @if(!empty($settings['facebook_pixel_id'])) document.addEventListener('DOMContentLoaded', function () { const addToCartForms = document.querySelectorAll('form[action*="cart/add"], form[action*="buy-now"]'); addToCartForms.forEach(function(form) { form.addEventListener('submit', function() { fbq('track', 'AddToCart', { content_name: '{{ addslashes($product->name) }}', content_ids: ['{{ $product->id }}'], content_type: 'product', value: {{ $product->sale_price ?? $product->regular_price ?? 0 }}, currency: 'BDT' }); }); }); }); @endif let selectedVariationId = null; function changeImage(el, src) { document.getElementById('mainImage').src = src; document.querySelectorAll('.gallery-thumb').forEach(t => t.classList.remove('active')); el.classList.add('active'); } function changeQty(delta) { const input = document.getElementById('quantity'); const max = parseInt(input.max) || 999; let val = parseInt(input.value) + delta; if (val < 1) val = 1; if (val > max) val = max; input.value = val; syncQuantity(); } document.getElementById('quantity').addEventListener('input', syncQuantity); function syncQuantity() { const q = document.getElementById('quantity').value; document.getElementById('cart-quantity').value = q; document.getElementById('buynow-quantity').value = q; } function selectVariation(btn) { const group = btn.closest('[data-variation-type]'); group.querySelectorAll('.variation-btn').forEach(b => b.classList.remove('selected')); btn.classList.add('selected'); selectedVariationId = btn.dataset.variationId; document.getElementById('cart-variation-id').value = selectedVariationId; document.getElementById('buynow-variation-id').value = selectedVariationId; } </script> @endsection
💾 保存
取消
保存为 UTF-8,换行统一为 LF