swell-node was relying too much on Node packages like crypto or events to be used with Cloudflare Pages or Vercel Edge Functions
134 lines
4.1 KiB
Svelte
134 lines
4.1 KiB
Svelte
<style lang="scss">
|
||
@import "../../style/layouts/poster";
|
||
</style>
|
||
|
||
<script lang="ts">
|
||
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
|
||
export let shopProduct: any
|
||
|
||
$: hasStock = shopProduct.stock_level > 0
|
||
|
||
|
||
/**
|
||
* Preview photos specs
|
||
*/
|
||
let lastPreviewPhoto: any = undefined
|
||
|
||
$: if (product && product.photos_preview.length) {
|
||
lastPreviewPhoto = product.photos_preview[product.photos_preview.length - 1].directus_files_id
|
||
}
|
||
|
||
// Images sizes
|
||
const photosPreview = [
|
||
{
|
||
sizes: {
|
||
small: { width: 275 },
|
||
medium: { width: 500 },
|
||
large: { width: 800 },
|
||
},
|
||
ratio: 0.75,
|
||
},
|
||
{
|
||
sizes: {
|
||
small: { width: 200 },
|
||
medium: { width: 300 },
|
||
large: { width: 400 },
|
||
},
|
||
ratio: 0.8,
|
||
},
|
||
{
|
||
sizes: {
|
||
small: { width: 200 },
|
||
medium: { width: 300 },
|
||
large: { width: 400 },
|
||
},
|
||
ratio: 1.28,
|
||
},
|
||
{
|
||
sizes: {
|
||
small: { width: 450 },
|
||
medium: { width: 700 },
|
||
large: { width: 1000 },
|
||
},
|
||
ratio: 0.68,
|
||
},
|
||
]
|
||
</script>
|
||
|
||
<section class="poster-layout grid" id="poster">
|
||
<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">
|
||
<dl>
|
||
<dt class="title-small">{capitalizeFirstLetter(product.type)}</dt>
|
||
<dd class="text-info">{shopProduct.name} – {shopProduct.price}€</dd>
|
||
</dl>
|
||
<Button
|
||
tag="button"
|
||
text={hasStock ? 'Add to cart' : 'Sold out'}
|
||
color="pinklight"
|
||
disabled={!hasStock}
|
||
on:click={() => addToCart(shopProduct)}
|
||
/>
|
||
</div>
|
||
|
||
<Carousel
|
||
class="shadow-box-dark"
|
||
slides={product.photos_product.map(({ directus_files_id }) => ({
|
||
id: directus_files_id.id,
|
||
alt: directus_files_id.title,
|
||
}))}
|
||
/>
|
||
</aside>
|
||
|
||
{#if product.photos_preview.length}
|
||
<div class="poster-layout__images grid container">
|
||
{#each product.photos_preview.slice(0, 3) as { directus_files_id}, index}
|
||
<Image
|
||
class="image image--{index + 1} photo shadow-box-light"
|
||
id={directus_files_id.id}
|
||
sizeKey="photo-list"
|
||
sizes={photosPreview[index].sizes}
|
||
ratio={photosPreview[index].ratio}
|
||
alt={directus_files_id.title}
|
||
/>
|
||
{/each}
|
||
</div>
|
||
{/if}
|
||
|
||
<div class="poster-layout__about grid">
|
||
<div class="text container">
|
||
{#if product.description}
|
||
<p class="headline text-large">{product.description}</p>
|
||
{/if}
|
||
{#if product.details}
|
||
<p class="details text-xsmall">{product.details}</p>
|
||
{/if}
|
||
</div>
|
||
</div>
|
||
|
||
{#if lastPreviewPhoto}
|
||
<Image
|
||
class="image image--4 photo shadow-box-light"
|
||
id={lastPreviewPhoto.id}
|
||
sizeKey="photo-grid"
|
||
sizes={photosPreview[photosPreview.length - 1].sizes}
|
||
ratio={photosPreview[photosPreview.length - 1].ratio}
|
||
alt={lastPreviewPhoto.title}
|
||
/>
|
||
{/if}
|
||
</section> |