[wip] Rework Shop
- Change strategy for content fetching - Add a route per page instead of using __layout for all - Change the behaviors of the posters section (add a carousel on small screens) - Change Poster buttons styling and make interactions only for desktop
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
|
||||
onMount(async () => {
|
||||
// Disable when changing filters on /photos and shop?
|
||||
if (!$page.query.get('country') && !$page.path.includes('/shop/poster')) {
|
||||
if (!$page.query.get('country') && !$page.path.includes('/shop')) {
|
||||
await tick()
|
||||
setTimeout(() => {
|
||||
// Scroll back to top between page transitions
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
import { addToCart } from '$utils/functions/shop'
|
||||
import { capitalizeFirstLetter } from '$utils/functions'
|
||||
// Components
|
||||
import SplitText from '$components/SplitText.svelte'
|
||||
import Button from '$components/atoms/Button.svelte'
|
||||
import Image from '$components/atoms/Image.svelte'
|
||||
import ScrollingTitle from '$components/atoms/ScrollingTitle.svelte'
|
||||
import Carousel from '$components/organisms/Carousel.svelte'
|
||||
|
||||
export let product: any
|
||||
@@ -60,9 +62,11 @@
|
||||
</script>
|
||||
|
||||
<section class="poster-layout grid" id="poster">
|
||||
<h2 class="title-huge">
|
||||
{product.location.name}
|
||||
</h2>
|
||||
<div class="poster-layout__title">
|
||||
<ScrollingTitle tag="h2" label={product.location.name}>
|
||||
<SplitText mode="chars" text={product.location.name} />
|
||||
</ScrollingTitle>
|
||||
</div>
|
||||
|
||||
<aside class="poster-layout__buy">
|
||||
<div class="poster-layout__info">
|
||||
|
||||
@@ -33,11 +33,11 @@
|
||||
text="View"
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
text="Add to cart"
|
||||
color="pinklight"
|
||||
tag="button"
|
||||
size="xsmall"
|
||||
on:click={() => addToCart($cartId, product)}
|
||||
text="Add to cart"
|
||||
color="pink"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,10 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores'
|
||||
import { goto } from '$app/navigation'
|
||||
import { shopLocations } from '$utils/stores/shop'
|
||||
import { getContext } from 'svelte'
|
||||
|
||||
export let isOver: boolean = false
|
||||
|
||||
const { shopLocations } = getContext('shop')
|
||||
|
||||
const classes = [
|
||||
'shop-locationswitcher',
|
||||
isOver && 'is-over',
|
||||
@@ -26,7 +28,7 @@
|
||||
<use xlink:href="#icon-map-pin" />
|
||||
</svg>
|
||||
<select on:change={quickLocationChange}>
|
||||
{#each $shopLocations as { name, slug }}
|
||||
{#each shopLocations as { name, slug }}
|
||||
<option value={slug} selected={slug === $page.params.name}>{name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
|
||||
115
src/components/organisms/PostersGrid.svelte
Normal file
115
src/components/organisms/PostersGrid.svelte
Normal file
@@ -0,0 +1,115 @@
|
||||
<script lang="ts">
|
||||
import { getContext, onMount } from 'svelte'
|
||||
import EmblaCarousel, { EmblaCarouselType } from 'embla-carousel'
|
||||
// Components
|
||||
import Poster from '$components/molecules/Poster.svelte'
|
||||
import EmailForm from '$components/molecules/EmailForm.svelte'
|
||||
import { debounce } from '$utils/functions'
|
||||
|
||||
export let posters: any = []
|
||||
|
||||
let innerWidth: number
|
||||
let carouselEl: HTMLElement
|
||||
let carousel: EmblaCarouselType
|
||||
let currentSlide = 0
|
||||
let carouselDots = []
|
||||
|
||||
const { shopProducts } = getContext('shop')
|
||||
|
||||
|
||||
/** Navigate to specific slide */
|
||||
const goToSlide = (index: number = 0) => {
|
||||
carousel.scrollTo(index)
|
||||
}
|
||||
|
||||
/** Init Carousel */
|
||||
const initCarousel = () => {
|
||||
if (innerWidth < 992) {
|
||||
if (!carousel) {
|
||||
carousel = EmblaCarousel(carouselEl, {
|
||||
slidesToScroll: innerWidth < 550 ? 1 : 2,
|
||||
})
|
||||
|
||||
// On init
|
||||
carousel.on('init', () => {
|
||||
// Define amounts of dots
|
||||
carouselDots = carousel.scrollSnapList()
|
||||
})
|
||||
// On slide change
|
||||
carousel.on('select', () => {
|
||||
// Define current slide
|
||||
currentSlide = carousel.selectedScrollSnap()
|
||||
})
|
||||
// On resize
|
||||
carousel.on('resize', () => {
|
||||
// Redefine options
|
||||
carousel.reInit({
|
||||
slidesToScroll: innerWidth < 550 ? 1 : 2
|
||||
})
|
||||
// Define amounts of dots
|
||||
carouselDots = carousel.scrollSnapList()
|
||||
// Define current slide
|
||||
currentSlide = carousel.selectedScrollSnap()
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (carousel) {
|
||||
carousel.destroy()
|
||||
carousel = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Destroy carousel for larger screens */
|
||||
const handleResize = debounce(initCarousel, 200)
|
||||
|
||||
|
||||
onMount(() => {
|
||||
initCarousel()
|
||||
|
||||
// Destroy
|
||||
return () => {
|
||||
if (carousel) {
|
||||
carousel.destroy()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<svelte:window
|
||||
bind:innerWidth
|
||||
on:resize={handleResize}
|
||||
/>
|
||||
|
||||
{#if posters}
|
||||
<section class="shop-page__posters grid">
|
||||
<h3>View all of our available posters</h3>
|
||||
|
||||
<div class="set" bind:this={carouselEl}>
|
||||
<div class="set__content">
|
||||
{#each posters as { location, photos_product }}
|
||||
<Poster
|
||||
location={location}
|
||||
image={photos_product.length && photos_product[1].directus_files_id}
|
||||
product={shopProducts.find(item => item.slug.includes(location.slug))}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
{#if carousel}
|
||||
<ul class="set__dots">
|
||||
{#each carouselDots as _, index}
|
||||
<li class:is-active={index === currentSlide}>
|
||||
<button on:click={() => goToSlide(index)} aria-label="Go to slide #{index + 1}" />
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="subscribe">
|
||||
<label class="subscribe__text" for="SUB_EMAIL">Subscribe to be notified when new posters become available</label>
|
||||
<EmailForm />
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
Reference in New Issue
Block a user