Files
housesof/src/routes/shop/__layout.svelte
Félix Péault 5923afed3b Make Shop location switcher a component using a global store
Using two switchers (one in the shop nav and the other in the cart) makes possible to have the switcher over the Cart overlay (over intro)
2021-11-07 22:40:52 +01:00

240 lines
6.7 KiB
Svelte
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.
<script lang="ts">
import { onMount } from 'svelte'
import { shopLocations, cartOpen, cartNotifications } from '$utils/stores/shop'
// Components
import Metas from '$components/Metas.svelte'
import PosterLayout from '$components/layouts/PosterLayout.svelte'
import SiteTitle from '$components/atoms/SiteTitle.svelte'
import Image from '$components/atoms/Image.svelte'
import ButtonCart from '$components/atoms/ButtonCart.svelte'
import Poster from '$components/molecules/Poster.svelte'
import NotificationCart from '$components/molecules/NotificationCart.svelte'
import EmailForm from '$components/molecules/EmailForm.svelte'
import ShopLocationSwitcher from '$components/molecules/ShopLocationSwitcher.svelte';
import Cart from '$components/organisms/Cart.svelte'
export let shop: any
export let locations: any
export let posters: any
export let product: any
export let productShop: any
let introEl: HTMLElement
let navObserver: IntersectionObserver
let scrolledPastIntro = false
// Locations with an existing poster product
$shopLocations = locations.filter(({ slug }: any) => {
if (posters.find((poster: any) => poster.location.slug === slug)) {
return true
}
})
onMount(async () => {
// 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)
// Destroy
return () => {
navObserver && navObserver.unobserve(introEl)
}
})
</script>
<Metas
title="Shop Houses Of"
description=""
image=""
/>
{#key product}
<main class="shop-page">
<Cart />
<section class="shop-page__intro" bind:this={introEl}>
<a href="/" class="back">
Back to Houses Of
</a>
<span class="shop-title">Shop</span>
<SiteTitle
variant="inline"
/>
<header class="shop-page__header">
<div class="container">
<p class="text-label">Shop your city</p>
<nav>
<ul>
{#each $shopLocations as { name, slug }}
<li class:is-active={slug === product.location.slug}>
<a href="/shop/poster-{slug}">{name}</a>
</li>
{/each}
</ul>
</nav>
<ButtonCart />
</div>
</header>
<Image
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 />
<div class="shop-location__notifications">
{#each $cartNotifications as { id, title, name, image } (id)}
<NotificationCart
title={title}
name={name}
image={image}
/>
{/each}
</div>
</nav>
<section class="shop-page__about grid">
<p class="description text-normal">{shop.about}</p>
</section>
<PosterLayout
product={product}
productShop={productShop}
/>
<section class="shop-page__posters grid">
<h3>View all of our available posters</h3>
<div class="set">
{#each posters as { location, photos_product }}
<Poster
location={location}
image={photos_product.length && photos_product[1].directus_files_id}
/>
{/each}
</div>
<div class="subscribe">
<p>Subscribe to be notified when new posters become available</p>
<EmailForm />
</div>
</section>
</main>
{/key}
<slot />
<script context="module" lang="ts">
import { fetchAPI } from '$utils/api'
import { getRandomElement } from '$utils/functions'
export async function load ({ page, fetch, session, stuff }) {
// Init Swell
// swell.init(import.meta.env.VITE_SWELL_STORE_ID, import.meta.env.VITE_SWELL_API_TOKEN)
// Get content from API
const res = await fetchAPI(`
query {
shop {
about
page_heroimage { id }
}
location (
filter: { has_poster: { _eq: true }},
sort: "name"
) {
name
slug
}
posters: product {
name
type
description
details
location {
name
slug
}
product_id
photos_product {
directus_files_id {
id
title
}
}
photos_preview {
directus_files_id {
id
title
}
}
}
}
`)
const { data } = res
/**
* Define product
*/
const productAPI = (!page.params.type && !page.params.name)
// Get a random product
? data.posters[getRandomElement(data.posters)]
// Get the current product from slug
: data.posters.find(({ location }: any) => location.slug === page.params.name)
/**
* Get product data from Swell
*/
let productShopRes: any
const productShop = await fetch('/api/swell', {
method: 'POST',
body: JSON.stringify({
action: 'getProduct',
productId: productAPI.product_id,
})
})
if (productShop) {
productShopRes = await productShop.json()
}
return {
props: {
shop: data.shop,
locations: data.location,
posters: data.posters,
product: productAPI,
productShop: productShopRes,
}
}
}
</script>