Files
tehnobox/resources/views/shop/product.blade.php
ssww23 93a655235a
Some checks failed
Deploy / deploy (push) Has been cancelled
Initial commit
2026-03-10 00:55:37 +03:00

222 lines
11 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.
@extends('layouts.shop')
@php
$productGallery = $product->gallery_urls;
$productImage = $productGallery[0] ?? ($product->image_url ?: config('seo.default_image'));
$productImageUrl = str_starts_with($productImage, 'http://') || str_starts_with($productImage, 'https://')
? $productImage
: url($productImage);
$productSchemaImages = array_map(
fn (string $image) => str_starts_with($image, 'http://') || str_starts_with($image, 'https://')
? $image
: url($image),
$productGallery !== [] ? array_values($productGallery) : [$productImageUrl]
);
$manufacturer = trim((string) ($product->specs['manufacturer'] ?? ''));
$conditionRaw = mb_strtolower(trim((string) ($product->specs['condition'] ?? '')));
$itemCondition = str_contains($conditionRaw, 'б/у') || str_contains($conditionRaw, 'used')
? 'https://schema.org/UsedCondition'
: 'https://schema.org/NewCondition';
$productSchema = [
'@context' => 'https://schema.org',
'@type' => 'Product',
'name' => $product->name,
'description' => $product->short_description ?: ($product->description ?: "Купить {$product->name} по выгодной цене."),
'sku' => $product->sku ?: null,
'category' => $product->category?->name,
'image' => $productSchemaImages,
'url' => route('products.show', $product),
'offers' => [
'@type' => 'Offer',
'priceCurrency' => config('shop.currency_code', 'RUB'),
'price' => (string) $product->price,
'availability' => $product->stock > 0 ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock',
'itemCondition' => $itemCondition,
'url' => route('products.show', $product),
],
];
if ($manufacturer !== '') {
$productSchema['brand'] = [
'@type' => 'Brand',
'name' => $manufacturer,
];
}
@endphp
@section('meta_title', $product->name)
@section('meta_description', \Illuminate\Support\Str::limit(strip_tags($product->short_description ?: ($product->description ?: "Купить {$product->name} по выгодной цене.")), 160))
@section('meta_keywords', $product->name . ', ' . ($product->category?->name ?? 'товар') . ', купить')
@section('meta_canonical', route('products.show', $product))
@section('meta_image', $productImageUrl)
@section('meta_image_alt', $product->name)
@section('meta_og_type', 'product')
@push('structured_data')
<script type="application/ld+json">
@json($productSchema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
</script>
@endpush
@section('content')
@php
$favoriteIds = array_map('intval', (array) session('favorites', []));
$compareIds = array_map('intval', (array) session('compare', []));
$isFavorite = in_array($product->id, $favoriteIds, true);
$isCompared = in_array($product->id, $compareIds, true);
$cartItems = (array) session('cart', []);
$isInCart = isset($cartItems[$product->id]);
@endphp
@include('partials.breadcrumbs', [
'items' => [
['label' => 'Главная', 'url' => route('home')],
['label' => 'Каталог', 'url' => route('catalog.index')],
['label' => $product->category?->name ?? 'Категория', 'url' => $product->category ? route('catalog.category', $product->category) : null],
['label' => $product->name, 'url' => null],
],
])
<section class="pc-section pc-product-page">
<div class="pc-product-hero">
<div class="pc-product-gallery" data-product-gallery>
@if ($productGallery !== [])
<img
class="pc-product-image-lg"
src="{{ $productGallery[0] }}"
alt="{{ $product->name }}"
loading="eager"
decoding="async"
data-product-gallery-main
>
@else
<div class="pc-product-image-lg" role="img" aria-label="{{ $product->name }}"></div>
@endif
@if (count($productGallery) > 1)
<div class="pc-product-thumbs" aria-label="Дополнительные изображения товара">
@foreach ($productGallery as $imageUrl)
<button
class="pc-product-thumb {{ $loop->first ? 'is-active' : '' }}"
type="button"
data-product-gallery-thumb
data-image-src="{{ $imageUrl }}"
data-image-alt="{{ $product->name }} - фото {{ $loop->iteration }}"
aria-label="Показать фото {{ $loop->iteration }}"
aria-pressed="{{ $loop->first ? 'true' : 'false' }}"
>
<img
src="{{ $imageUrl }}"
alt="{{ $product->name }} - миниатюра {{ $loop->iteration }}"
loading="lazy"
decoding="async"
>
</button>
@endforeach
</div>
@endif
</div>
<div class="pc-product-info">
<h1>{{ $product->name }}</h1>
<p class="pc-muted">{{ $product->short_description }}</p>
<div class="pc-product-badges">
@if ($product->sku)
<span class="pc-sku">Артикул: {{ $product->sku }}</span>
@endif
</div>
<div class="pc-product-price">
<strong>{{ number_format($product->price, 0, '.', ' ') }} {{ config('shop.currency_symbol', '₽') }}</strong>
@if (!empty($product->old_price))
<span class="pc-product-old">{{ number_format($product->old_price, 0, '.', ' ') }} {{ config('shop.currency_symbol', '₽') }}</span>
@endif
</div>
<div class="pc-product-actions">
@if ($product->stock > 0)
<form method="post" action="{{ route('cart.add', $product) }}" data-preserve-scroll="true">
@csrf
<button class="pc-btn primary {{ $isInCart ? 'is-active' : '' }}" type="submit">
{{ $isInCart ? 'В корзине' : 'В корзину' }}
</button>
</form>
@else
<button class="pc-btn primary" type="button" disabled>Нет в наличии</button>
@endif
<form method="post" action="{{ route('favorites.toggle', $product) }}" data-preserve-scroll="true">
@csrf
<button class="pc-btn ghost {{ $isFavorite ? 'is-active' : '' }}" type="submit">
{{ $isFavorite ? 'Убрать из избранного' : 'В избранное' }}
</button>
</form>
<form method="post" action="{{ route('compare.toggle', $product) }}" data-preserve-scroll="true">
@csrf
<button class="pc-btn ghost {{ $isCompared ? 'is-active' : '' }}" type="submit">
{{ $isCompared ? 'Убрать из сравнения' : 'В сравнение' }}
</button>
</form>
</div>
</div>
</div>
<div class="pc-tabs">
<input type="radio" name="product-tabs" id="tab-specs" checked>
<input type="radio" name="product-tabs" id="tab-desc">
<input type="radio" name="product-tabs" id="tab-shipping">
<input type="radio" name="product-tabs" id="tab-payment">
<div class="pc-tab-labels">
<label for="tab-specs">Характеристики</label>
<label for="tab-desc">Описание</label>
<label for="tab-shipping">Доставка</label>
<label for="tab-payment">Оплата</label>
</div>
<div class="pc-tab-content">
<section class="pc-tab-panel pc-tab-specs">
<div class="pc-specs-grid">
@forelse (($product->specs ?? []) as $key => $value)
<div class="pc-spec-row">
<span>{{ $specLabels[$key] ?? str_replace('_', ' ', $key) }}</span>
<strong>{{ $value }}</strong>
</div>
@empty
<p class="pc-muted">Характеристики еще не добавлены.</p>
@endforelse
</div>
</section>
<section class="pc-tab-panel pc-tab-desc">
<p class="pc-muted">{{ $product->description ?? 'Описание товара будет добавлено позже.' }}</p>
</section>
<section class="pc-tab-panel pc-tab-shipping">
<ul class="pc-list">
<li>Доставка курьером по городу</li>
<li>Самовывоз из пункта выдачи</li>
<li>Отправка по стране 1-3 дня</li>
</ul>
</section>
<section class="pc-tab-panel pc-tab-payment">
<ul class="pc-list">
<li>Оплата картой онлайн</li>
<li>Банковский перевод</li>
<li>Рассрочка на крупные заказы</li>
</ul>
</section>
</div>
</div>
</section>
@if ($related->isNotEmpty())
<section class="pc-section">
<div class="pc-section-title">
<h2>Что еще посмотреть в этой категории</h2>
</div>
<div class="pc-products-grid">
@foreach ($related as $item)
@include('partials.product-card', ['product' => $item])
@endforeach
</div>
</section>
@endif
@endsection