173 lines
5.6 KiB
Svelte
173 lines
5.6 KiB
Svelte
<script lang="ts">
|
|
import { onMount } from 'svelte'
|
|
import { fade, fly } from 'svelte/transition'
|
|
import { quartOut } from 'svelte/easing'
|
|
import { cartOpen, cartId, cartData, cartAmount, cartIsUpdating } from '$utils/stores/shop'
|
|
// Components
|
|
import Button from '$components/atoms/Button.svelte'
|
|
import Icon from '$components/atoms/Icon.svelte'
|
|
import CartItem from '$components/molecules/CartItem.svelte'
|
|
import ShopLocationSwitcher from '$components/molecules/ShopLocationSwitcher.svelte'
|
|
|
|
|
|
onMount(async () => {
|
|
// Cart already exists
|
|
if ($cartId && $cartId !== 'null') {
|
|
// Fetch stored cart
|
|
const existantCart = await fetch('/api/swell', {
|
|
method: 'POST',
|
|
body: JSON.stringify({
|
|
action: 'fetchCart',
|
|
cartId: $cartId
|
|
})
|
|
})
|
|
if (existantCart.ok) {
|
|
const cart = await existantCart.json()
|
|
$cartId = cart.id
|
|
$cartData = cart
|
|
// console.log('Fetched existant cart:', $cartId, $cartData)
|
|
}
|
|
}
|
|
// Cart doesn't exists
|
|
else {
|
|
// Create a new cart and store it
|
|
const newCart = await fetch('/api/swell', {
|
|
method: 'POST',
|
|
body: JSON.stringify({
|
|
action: 'createCart'
|
|
})
|
|
})
|
|
if (newCart.ok) {
|
|
const cart = await newCart.json()
|
|
$cartId = cart.id
|
|
$cartData = cart
|
|
// console.log('Created new cart:', localStorage.getItem('cartId'))
|
|
}
|
|
}
|
|
})
|
|
|
|
|
|
// Closing the cart
|
|
const handleCloseCart = () => {
|
|
$cartOpen = false
|
|
}
|
|
|
|
// Item quantity changed
|
|
const changedQuantity = async ({ detail: { id, quantity } }) => {
|
|
// Cart is now updating
|
|
$cartIsUpdating = true
|
|
|
|
// Get updated cart
|
|
const updatedCart = await fetch('/api/swell', {
|
|
method: 'POST',
|
|
body: JSON.stringify({
|
|
action: 'updateCartItem',
|
|
cartId: $cartId,
|
|
productId: id,
|
|
quantity,
|
|
})
|
|
})
|
|
if (updatedCart.ok) {
|
|
const cart = await updatedCart.json()
|
|
$cartData = cart
|
|
// Cart is updated
|
|
$cartIsUpdating = false
|
|
}
|
|
}
|
|
|
|
// Item removed
|
|
const removedItem = async ({ detail: id }) => {
|
|
// Cart is now updating
|
|
$cartIsUpdating = true
|
|
|
|
// Remove item from cart
|
|
const updatedCart = await fetch('/api/swell', {
|
|
method: 'POST',
|
|
body: JSON.stringify({
|
|
action: 'removeCartItem',
|
|
cartId: $cartId,
|
|
productId: id,
|
|
})
|
|
})
|
|
if (updatedCart.ok) {
|
|
const cart = await updatedCart.json()
|
|
$cartData = cart
|
|
// Cart is updated
|
|
$cartIsUpdating = false
|
|
}
|
|
}
|
|
</script>
|
|
|
|
{#if $cartOpen}
|
|
<div class="cart-switcher"
|
|
in:fly={{ y: -24, duration: 1000, easing: quartOut }}
|
|
out:fly={{ y: -24, duration: 1000, easing: quartOut }}
|
|
>
|
|
<ShopLocationSwitcher isOver={true} />
|
|
</div>
|
|
|
|
<aside class="cart shadow-box-dark"
|
|
class:is-updating={$cartIsUpdating}
|
|
transition:fly={{ x: 48, duration: 600, easing: quartOut }}
|
|
>
|
|
<header class="cart__heading">
|
|
<h2>Cart</h2>
|
|
<button class="text-label" on:click={handleCloseCart}>Close</button>
|
|
</header>
|
|
|
|
<div class="cart__content">
|
|
{#if $cartAmount > 0}
|
|
{#each $cartData.items as item, index}
|
|
<CartItem {item} {index}
|
|
on:updatedQuantity={changedQuantity}
|
|
on:removed={removedItem}
|
|
/>
|
|
{/each}
|
|
{:else}
|
|
<div class="cart__empty shadow-small">
|
|
<div class="icon">
|
|
<Icon icon="bag" label="Shopping bag icon" />
|
|
</div>
|
|
<p>Your cart is empty</p>
|
|
</div>
|
|
{/if}
|
|
|
|
{#if !$cartData || $cartIsUpdating}
|
|
<div class="cart__update">
|
|
<p>Updating…</p>
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
|
|
<footer class="cart__total">
|
|
<div class="cart__total--sum">
|
|
<h3>Total</h3>
|
|
{#if $cartData}
|
|
<span>{$cartAmount} item{$cartAmount > 1 ? 's' : ''}</span>
|
|
<p>{$cartData.sub_total ? $cartData.sub_total : 0}€</p>
|
|
{:else}
|
|
<span>0 item</span>
|
|
<p>0€</p>
|
|
{/if}
|
|
</div>
|
|
<div class="cart__total--checkout">
|
|
<p>Shipping will be calculated from the delivery address during the checkout process</p>
|
|
{#if $cartData && $cartAmount > 0 && $cartData.checkout_url}
|
|
<div transition:fly={{ y: 8, duration: 600, easing: quartOut }}>
|
|
<Button
|
|
url={$cartData && $cartData.checkout_url}
|
|
text="Checkout"
|
|
color="pink"
|
|
size="small"
|
|
/>
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
</footer>
|
|
</aside>
|
|
|
|
<div class="cart-overlay"
|
|
transition:fade={{ duration: 600, easing: quartOut }}
|
|
on:click={handleCloseCart}
|
|
/>
|
|
{/if} |