Rework Shop pages and switch to page endpoints

- Create ShopHeader component to reuse on pages
- Use page endpoints to query data from API and Swell
- Remove use of `stuff`
This commit is contained in:
2022-06-07 16:58:57 +02:00
parent 152961996d
commit 3bd7061cd2
6 changed files with 264 additions and 322 deletions

View File

@@ -0,0 +1,133 @@
<script lang="ts">
import { getContext, onMount } from 'svelte'
import anime from 'animejs'
import type { AnimeTimelineInstance } from 'animejs'
import { cartOpen } from '$utils/stores/shop'
// Components
import Image from '$components/atoms/Image.svelte'
import ButtonCart from '$components/atoms/ButtonCart.svelte'
import ShopLocationSwitcher from '$components/molecules/ShopLocationSwitcher.svelte'
export let product: any = undefined
const { shop, shopLocations } = getContext('shop')
let navObserver: IntersectionObserver
let introEl: HTMLElement
let scrolledPastIntro = false
onMount(() => {
// Reveal the nav past the Intro
navObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
scrolledPastIntro = !entry.isIntersecting
})
}, {
threshold: 0,
rootMargin: '0px 0px 0px'
})
navObserver.observe(introEl)
/**
* Animations
*/
// Setup animations
const timeline: AnimeTimelineInstance = anime.timeline({
duration: 1600,
easing: 'easeOutQuart',
autoplay: false,
})
// Hero image
timeline.add({
targets: '.shop-page__background',
scale: [1.06, 1],
opacity: [0, 1],
duration: 2400,
}, 400)
// Hero title
timeline.add({
targets: '.shop-page__intro h1',
translateY: [32, 0],
opacity: [0, 1],
}, 500)
// Intro top elements
timeline.add({
targets: '.shop-page__intro .top > *',
translateY: [-100, 0],
delay: anime.stagger(250),
}, 400)
// Intro navbar
timeline.add({
targets: '.shop-page__nav .container > *',
translateY: [100, 0],
delay: anime.stagger(250),
}, 700)
// Transition in
requestAnimationFrame(timeline.play)
// Destroy
return () => {
navObserver && navObserver.unobserve(introEl)
}
})
</script>
<section class="shop-page__intro" bind:this={introEl}>
<div class="top container">
<a href="/" class="back" sveltekit:noscroll>
<svg width="5" height="8" viewBox="0 0 5 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 1 1 4l3 3" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<span>Back to Houses Of</span>
</a>
</div>
<h1>Shop</h1>
<nav class="shop-page__nav">
<div class="container">
<p class="text-label">Choose a city</p>
<nav>
<ul>
{#each shopLocations as { name, slug }}
<li class:is-active={product && slug === product.location.slug}>
<a href="/shop/poster-{slug}" sveltekit:prefetch sveltekit:noscroll>
{name}
</a>
</li>
{/each}
</ul>
</nav>
<ButtonCart />
</div>
</nav>
<Image
class="shop-page__background"
id={shop.page_heroimage.id}
alt="photo"
sizeKey="hero"
sizes={{
large: { width: 1800, height: 1200 },
medium: { width: 1200, height: 800 },
small: { width: 700, height: 700 },
}}
/>
</section>
<nav class="shop-location"
class:is-visible={scrolledPastIntro}
class:is-overlaid={$cartOpen}
>
<ShopLocationSwitcher />
<ButtonCart />
</nav>