Files
hoshal-market/resources/views/home.blade.php
Mekan1206 cc0c29bd72 Enhance product card filtering and animation in Home view
- Added dynamic transition delay for product cards based on visible items to improve animation effects.
- Reset animation state and transition delay for hidden cards to ensure smooth filtering experience.
- Improved overall user interaction with category-based product visibility.
2026-06-06 00:24:02 +05:00

182 lines
12 KiB
PHP

<x-layouts.app :settings="$settings">
<section class="relative h-screen w-full overflow-hidden flex items-center justify-center bg-surface-variant pt-20" id="hero">
<div id="hero-carousel">
@foreach($slides as $index => $slide)
<div class="carousel-slide {{ $index === 0 ? 'active' : '' }} bg-cover bg-center" data-alt="{{ $slide->subtitle }}" style="background-image: url('{{ $slide->image ? Storage::url($slide->image) : asset('assets/images/hero-cake.jpg') }}');">
<div class="absolute inset-0 bg-primary/40"></div>
<div class="absolute inset-0 flex items-center justify-center">
<div class="relative z-20 text-center px-6 max-w-4xl mx-auto mt-16 animate-on-scroll">
<h1 class="font-display-lg-mobile md:font-display-lg text-display-lg-mobile md:text-display-lg text-surface-container-lowest italic mb-6 drop-shadow-lg">{!! nl2br(e($slide->title)) !!}</h1>
<a class="inline-block mt-8 bg-ink-brown text-surface-container-lowest font-subheading-caps text-subheading-caps uppercase py-4 px-10 rounded-full tracking-wider hover:bg-on-background transition-colors border border-antique-gold/30 backdrop-blur-sm" href="#menu">Menýumyzy gözden geçiriň</a>
</div>
</div>
</div>
@endforeach
</div>
<div class="absolute top-32 left-8 md:left-16 z-20 opacity-40 hidden md:block">
<svg class="text-surface-container-lowest" fill="none" height="60" stroke="currentColor" stroke-width="0.5" viewbox="0 0 24 24" width="60">
<path d="M12 2L2 22h20L12 2zm0 4l7 14H5l7-14z"></path>
</svg>
</div>
<div class="absolute bottom-16 right-8 md:right-16 z-20 opacity-40 hidden md:block">
<svg class="text-surface-container-lowest" fill="none" height="60" stroke="currentColor" stroke-width="0.5" viewbox="0 0 24 24" width="60">
<circle cx="12" cy="12" r="10"></circle>
<path d="M12 6v6l4 2"></path>
</svg>
</div>
</section>
<div class="bg-primary-container text-antique-gold py-4 overflow-hidden border-y border-antique-gold/20">
<div class="flex whitespace-nowrap animate-marquee font-subheading-caps text-subheading-caps uppercase tracking-[0.2em]">
@for($i = 0; $i < 6; $i++)
<span class="mx-8">{{ $settings->marquee_text ?? 'Her gün täze bişirilen · Kiçi partýalarda taýýarlanylýar · Hünärmen iýmitçilik harytlary' }}</span>
<span class="mx-8">·</span>
@endfor
</div>
</div>
<section class="pt-24 px-margin-mobile md:px-margin-desktop max-w-[1440px] mx-auto bg-surface" id="collections">
@foreach($collections as $collection)
<div class="mb-20">
<div class="flex flex-col md:flex-row justify-between items-end mb-12 animate-on-scroll">
<div>
<h2 class="font-headline-md text-headline-md text-on-background mb-2">{{ $collection->title }}</h2>
@if($collection->subtitle)
<p class="font-body-md text-body-md text-on-surface-variant max-w-lg">{{ $collection->subtitle }}</p>
@endif
</div>
<div class="flex gap-4 mt-6 md:mt-0">
<button aria-label="Öňki" class="w-10 h-10 rounded-full border border-antique-gold flex items-center justify-center text-ink-brown hover:bg-surface-variant transition-colors btn-prev-collection" data-target="carousel-{{ $collection->id }}">
<span class="material-symbols-outlined">arrow_left</span>
</button>
<button aria-label="Indiki" class="w-10 h-10 rounded-full border border-antique-gold flex items-center justify-center text-ink-brown hover:bg-surface-variant transition-colors btn-next-collection" data-target="carousel-{{ $collection->id }}">
<span class="material-symbols-outlined">arrow_right</span>
</button>
</div>
</div>
<div class="flex overflow-x-auto hide-scrollbar gap-6 pb-8 snap-x snap-mandatory" id="carousel-{{ $collection->id }}">
@foreach($collection->collectionItems as $item)
<div style="max-height: 420px;" class="min-w-[280px] md:min-w-[320px] aspect-[3/4] relative snap-start group cursor-pointer border border-antique-gold/40 bg-surface-container-low p-4 flex flex-col justify-end overflow-hidden">
<div class="absolute inset-4 border border-outline/30 z-10 pointer-events-none transition-transform duration-500 group-hover:scale-95"></div>
<div class="absolute inset-0 bg-cover bg-center transition-transform duration-700 group-hover:scale-105 opacity-80" data-alt="{{ $item->subtitle }}" style="background-image: url('{{ $item->image ? Storage::url($item->image) : asset('assets/images/collection-chocolate-cake.jpg') }}');"></div>
<div class="absolute inset-0 bg-gradient-to-t from-primary-container/90 via-primary-container/30 to-transparent"></div>
<div class="relative z-20 p-6 text-center">
<h3 class="font-headline-md text-headline-md text-surface-container-lowest mb-1">{{ $item->title }}</h3>
<p class="font-label-sm text-label-sm text-antique-gold uppercase tracking-widest">{{ $item->subtitle }}</p>
</div>
</div>
@endforeach
</div>
</div>
@endforeach
</section>
<section class="py-16 px-margin-mobile md:px-margin-desktop max-w-container-max mx-auto bg-surface-container-low border-y border-outline/10" id="menu">
<div class="flex overflow-x-auto hide-scrollbar gap-4 pb-8 mb-8 justify-center animate-on-scroll">
<button class="filter-btn px-6 py-2 rounded-full bg-ink-brown text-surface-container-lowest font-label-sm text-label-sm uppercase tracking-wide flex items-center gap-2 whitespace-nowrap" data-category="all">
<span class="material-symbols-outlined text-[16px]">cake</span> Hemmesi
</button>
@foreach($categories as $category)
<button class="filter-btn px-6 py-2 rounded-full border border-outline/30 text-on-surface-variant hover:border-antique-gold hover:text-ink-brown transition-colors font-label-sm text-label-sm uppercase tracking-wide flex items-center gap-2 whitespace-nowrap bg-surface" data-category="{{ $category->id }}">
@if($category->icon)
<span class="material-symbols-outlined text-[16px]">{{ $category->icon }}</span>
@endif
{{ $category->name }}
</button>
@endforeach
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-x-8 gap-y-12">
@foreach($products as $index => $product)
<div class="product-card group animate-on-scroll" data-category="{{ $product->category_id }}" style="transition-delay: {{ ($index % 4) * 100 }}ms;">
<div class="aspect-square mb-4 overflow-hidden relative bg-surface-variant">
<img alt="{{ $product->name }}" class="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105" data-alt="{{ $product->name }}" src="{{ $product->image ? Storage::url($product->image) : asset('assets/images/product-macaron.jpg') }}"/>
<div class="absolute inset-0 border border-outline/10 pointer-events-none m-2"></div>
</div>
<div class="text-center">
<h4 class="font-headline-md text-[20px] text-on-background mb-1">{{ $product->name }}</h4>
<p class="font-body-md text-body-md text-on-surface-variant/80 mb-2">{{ $product->description }}</p>
<p class="font-label-sm text-label-sm text-antique-gold">{{ number_format($product->price, 0) }} TMT</p>
</div>
</div>
@endforeach
</div>
</section>
<section class="py-24 px-margin-mobile md:px-margin-desktop max-w-container-max mx-auto" id="about">
<div class="grid md:grid-cols-2 gap-16 items-center">
<div class="relative aspect-[4/5] animate-on-scroll">
<img alt="About Us" class="w-full h-full object-cover grayscale opacity-90 sepia-[.2]" src="{{ $settings->about_image ? Storage::url($settings->about_image) : asset('assets/images/about-baker.jpg') }}"/>
<div class="absolute -bottom-8 -right-8 w-48 h-48 border border-antique-gold hidden md:block pointer-events-none"></div>
<div class="absolute -top-4 -left-4 w-24 h-24 border-t border-l border-ink-brown hidden md:block pointer-events-none"></div>
</div>
<div class="animate-on-scroll" style="transition-delay: 200ms;">
<p class="font-label-sm text-label-sm text-antique-gold uppercase tracking-widest mb-4">{{ $settings->about_label ?? 'Biziň mirasy' }}</p>
<h2 class="font-display-lg-mobile md:font-display-lg text-display-lg-mobile md:text-display-lg text-on-background mb-8 italic">{!! nl2br(e($settings->about_title ?? "Sabyr\nsungaty")) !!}</h2>
<div class="relative">
<div class="absolute -left-12 -top-12 opacity-10 pointer-events-none hidden md:block">
<svg fill="none" height="120" stroke="currentColor" stroke-width="0.5" viewbox="0 0 100 100" width="120">
<path d="M50 100 C 50 50, 0 50, 0 0 C 0 50, 50 50, 50 0 C 50 50, 100 50, 100 0 C 100 50, 50 50, 50 100"></path>
<circle cx="50" cy="50" r="10"></circle>
</svg>
</div>
<div class="font-body-md text-body-md text-on-surface-variant mb-8 leading-relaxed relative z-10">
{!! nl2br(e($settings->about_text ?? "Hoşal-da hakyky lýuksy wagtda görmek mümkin diýip hasaplaýarys. Peçimizden çykýan her kruassan üç gün dowam edýän jik-jik laminaasiýa prosesinden geçýär. Her tart gabygy dynýar, her krem sabyr bilen doldurylýar. Täzelikçi fransuz usullaryna esaslanýan, ýöne ýerli teýrwarlaryň ýyllygyndan ilham alýan patisseriamyz — öň biziňden öň gelen hünärmenlere hormatdyr.")) !!}
</div>
<img alt="Aşpeziň gol çeki" class="h-12 opacity-60 mix-blend-multiply" data-alt="Gol çekilen aşpeziň gol çeki" src="{{ asset('assets/images/chef-signature.png') }}"/>
</div>
</div>
</div>
</section>
<script>
document.addEventListener("DOMContentLoaded", () => {
const filterBtns = document.querySelectorAll('.filter-btn');
const productCards = document.querySelectorAll('.product-card');
const activeClasses = ['bg-ink-brown', 'text-surface-container-lowest'];
const inactiveClasses = ['border', 'border-outline/30', 'text-on-surface-variant', 'bg-surface'];
filterBtns.forEach(btn => {
btn.addEventListener('click', () => {
const category = btn.getAttribute('data-category');
// 1. Update button styles
filterBtns.forEach(b => {
b.classList.remove(...activeClasses);
b.classList.add(...inactiveClasses);
});
btn.classList.remove(...inactiveClasses);
btn.classList.add(...activeClasses);
// 2. Filter products
let visibleIndex = 0;
productCards.forEach(card => {
// Reset animation state
card.classList.remove('is-visible');
if (category === 'all' || card.getAttribute('data-category') === category) {
card.style.display = 'block';
// Recalculate transition delay dynamically based on visible items
card.style.transitionDelay = `${(visibleIndex % 4) * 100}ms`;
visibleIndex++;
// Small timeout to allow browser to register display:block before animating
setTimeout(() => {
card.classList.add('is-visible');
}, 50);
} else {
card.style.display = 'none';
// Reset delay so it doesn't affect future changes
card.style.transitionDelay = '0ms';
}
});
});
});
});
</script>
</x-layouts.app>