Files
housesof/src/components/organisms/Cart.svelte
Félix Péault 73c9e80a21 Use SVG icons from global symbols
Allow to change color and avoid code duplication
2021-11-10 22:57:50 +01:00

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}