Files
planetposen-frontend/src/routes/shop/[id]/+page.svelte
Kevin b2a15be12e Feat: Refactor jsonld & method to update document title and description (#4)
* Generates JSON ld structured metadata from a product & appends to head

* Updated IProduct & IVariation interface

* Added IProductResponse & IProductsResponse interfaces

* Fixed sitemap urls having to many protocols

* Implemented jsonld for product w/ variations

* Aligned Product responses between backend & frontend

* PageMeta for updating head meta values: title & description

Use on any page where we want to display a unique meta page title &
description

* Set document language to norwegian

* Linting
2022-11-30 00:39:04 +01:00

118 lines
2.8 KiB
Svelte

<script lang="ts">
import ProductTile from '../ProductTile.svelte';
import ProductVariationSelect from '$lib/components/ProductVariationSelect.svelte';
import QuantitySelect from '$lib/components/QuantitySelect.svelte';
import SizesSection from './SizesSection.svelte';
import Button from '$lib/components/Button.svelte';
import type { PageData } from './$types';
import type { IProduct, IVariation } from '$lib/interfaces/IProduct';
export let data: PageData;
const product = data.product as IProduct;
import { addProductToCart } from '$lib/websocketCart';
function setSelectedVariation(event: CustomEvent) {
selectedVariation = event.detail;
}
function addProductClicked() {
cooldownInputs = true;
addProductToCart(product.product_no, selectedVariation.sku_id, quantity);
setTimeout(() => reset(), 2300);
}
function reset() {
quantity = 1;
cooldownInputs = false;
}
function defaultVariation() {
return product.variations?.find((variation) => variation.default_price);
}
let cooldownInputs = false;
let quantity = 1;
let selectedVariation: IVariation | undefined = defaultVariation();
$: addProductButtonText = cooldownInputs
? `${quantity} produkt${quantity > 1 ? 'er' : ''} lagt til`
: `Legg til ${quantity} i handlekurven`;
onMount(() => document.head.appendChild(generateProductJsonLd(product)))
</script>
<div class="product-container">
<ProductTile product="{product}" large="{true}" />
<div class="details">
<h2 class="name">{product.name}</h2>
<p class="subtext">{product.subtext}</p>
<p class="subtext">{product.description}</p>
<p class="price">NOK {selectedVariation?.price} (Ink. Moms)</p>
<ProductVariationSelect
variations="{product.variations}"
on:selected="{setSelectedVariation}"
/>
<QuantitySelect bind:value="{quantity}" disabled="{cooldownInputs}" />
<div class="button">
<Button
on:click="{() => addProductClicked()}"
text="{addProductButtonText}"
active="{cooldownInputs}"
/>
</div>
</div>
</div>
<SizesSection />
{#if data?.jsonld}
{@html data.jsonld}
{/if}
<style lang="scss" module="scoped">
@import '../../../styles/media-queries.scss';
.product-container {
display: grid;
max-width: 1200px;
margin: 2rem auto 4rem;
grid-template-columns: 1fr;
@include tablet {
margin: 8rem auto 2rem;
grid-template-columns: 1fr 1fr;
}
> * {
margin: 1rem;
}
.details {
.name {
font-size: 2rem;
}
.price {
margin-top: 3rem;
font-size: 1.5rem;
}
p {
font-size: 1.2rem;
}
.button {
margin-top: 3rem;
}
@include desktop {
margin-left: 4rem;
}
}
}
</style>