It's been tricky but got there finally! Hello `:global` - Avoid using one global CSS file containing everything - Import the component SCSS file in a script tag from the component file to allow style scoping and including it only when used
135 lines
4.0 KiB
Svelte
135 lines
4.0 KiB
Svelte
<style lang="scss">
|
||
@import "../../style/layouts/poster";
|
||
</style>
|
||
|
||
<script lang="ts">
|
||
import { cartId } from '$utils/stores/shop'
|
||
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>{capitalizeFirstLetter(product.type)}</dt>
|
||
<dd>{shopProduct.name} – {shopProduct.price}€</dd>
|
||
</dl>
|
||
<Button
|
||
tag="button"
|
||
text={hasStock ? 'Add to cart' : 'Sold out'}
|
||
color="pinklight"
|
||
disabled={!hasStock}
|
||
on:click={() => addToCart($cartId, 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>{product.description}</p>
|
||
{/if}
|
||
{#if product.details}
|
||
<p class="details">{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> |