general products page and small rewrite of search and category controllers etc

This commit is contained in:
elvira
2026-09-03 21:32:40 +03:00
parent b2207a622c
commit 1f0612861b
23 changed files with 564 additions and 108 deletions
+10 -2
View File
@@ -11,7 +11,7 @@
{{-- Products (CSS-only hover dropdown) --}}
<div class="group relative h-full flex items-center">
<a href="{{ url('/'.app()->getLocale().'/products') }}" class="nav-link uppercase inline-flex items-center gap-1 relative font-display font-extrabold italic text-black no-underline py-8">
<a href="{{ route('products') }}" class="nav-link uppercase inline-flex items-center gap-1 relative font-display font-extrabold italic text-black no-underline py-8">
<span>{{ __('storefront.nav.products') }}</span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-4 not-italic transition-transform group-hover:rotate-180">
<path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
@@ -47,10 +47,18 @@
</a>
{{-- Search --}}
<button type="button" class="flex items-center justify-center w-10 h-10 hover:opacity-70 transition-opacity" aria-label="Search">
<button
type="button"
popovertarget="search-overlay"
popovertargetaction="toggle"
class="flex items-center justify-center w-10 h-10 hover:opacity-70 transition-opacity"
aria-label="{{ __('storefront.shop.search_label') }}"
>
<x-ui.icon name="search" :size="40" />
</button>
</div>
</div>
<x-search-overlay />
</header>
@@ -0,0 +1,41 @@
{{--
Full-width search bar that covers the header. A [popover] (top layer, so it
sits over the sticky header with no z-index juggling; Escape and click-away
close come for free). The header's search button opens it via popovertarget.
The `nav-search` controller measures the header on open (→ --search-overlay-h,
since the header isn't a fixed height below `lg`) and focuses the field.
Fade transition lives in app.css (#search-overlay).
--}}
<div
id="search-overlay"
popover
data-controller="nav-search"
class="fixed w-full inset-x-0 top-0 bottom-auto m-0 h-[var(--search-overlay-h)] border-0 bg-brand p-0"
>
<form
method="get"
action="{{ route('search') }}"
class="flex h-full items-center gap-6 px-10"
>
<label for="search-overlay-input" class="sr-only">{{ __('storefront.shop.search_label') }}</label>
<input
id="search-overlay-input"
type="search"
name="q"
required
autocomplete="off"
data-nav-search-target="input"
placeholder="{{ __('storefront.search.placeholder') }}"
class="min-w-0 flex-1 appearance-none border-0 border-b border-black bg-transparent pb-2 placeholder:text-black/60 focus:outline-none [&::-webkit-search-cancel-button]:appearance-none"
>
<button
type="button"
popovertarget="search-overlay"
popovertargetaction="hide"
aria-label="{{ __('storefront.nav.close') }}"
class="shrink-0 text-black transition-opacity hover:opacity-70"
>
<x-ui.icon name="close" :size="44" />
</button>
</form>
</div>
@@ -0,0 +1,11 @@
@props(['paginator'])
{{-- "Showing 1–12 of 48 products" — takes any LengthAwarePaginator. Shared by
the category listing and the search results page. --}}
<p {{ $attributes }}>
{{ trans_choice('storefront.shop.showing_results', $paginator->total(), [
'first' => $paginator->firstItem() ?? 0,
'last' => $paginator->lastItem() ?? 0,
'total' => $paginator->total(),
]) }}
</p>
@@ -0,0 +1,24 @@
@props([
'options', // [['label' => string, 'href' => string, 'current' => bool], ...] — build with App\Catalog\ProductSortOptions
'id' => 'sort',
])
{{-- Product sort dropdown. Options are plain links (built per page, so each can
carry its own state); following one navigates the enclosing turbo-frame and
advances the URL. Shared by the category listing and search results. --}}
@php
$active = collect($options)->firstWhere('current', true) ?? ($options[0] ?? ['label' => '']);
@endphp
<x-ui.dropdown
:id="$id"
:label="$active['label']"
:ariaLabel="__('storefront.shop.sort_label')"
triggerClass="min-w-48"
>
@foreach ($options as $option)
<x-ui.dropdown.item :href="$option['href']" :current="$option['current'] ?? false">
{{ $option['label'] }}
</x-ui.dropdown.item>
@endforeach
</x-ui.dropdown>