222 lines
11 KiB
PHP
222 lines
11 KiB
PHP
@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 по выгодной цене.', ['product' => $product->name]))),
|
||
'sku' => $product->sku ?: null,
|
||
'category' => $product->category?->name ? __($product->category->name) : null,
|
||
'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 по выгодной цене.', ['product' => $product->name])))), 160))
|
||
@section('meta_keywords', __(':product, :category, купить', ['product' => $product->name, 'category' => $product->category?->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 ? __($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 - фото :number', ['product' => $product->name, 'number' => $loop->iteration]) }}"
|
||
aria-label="{{ __('Показать фото :number', ['number' => $loop->iteration]) }}"
|
||
aria-pressed="{{ $loop->first ? 'true' : 'false' }}"
|
||
>
|
||
<img
|
||
src="{{ $imageUrl }}"
|
||
alt="{{ __(':product - миниатюра :number', ['product' => $product->name, 'number' => $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>{{ __((string) $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
|