🚧 Switch to monorepo with Turbo
This commit is contained in:
155
apps/website/src/components/organisms/Cart.svelte
Normal file
155
apps/website/src/components/organisms/Cart.svelte
Normal file
@@ -0,0 +1,155 @@
|
||||
<style lang="scss">
|
||||
@import "../../style/organisms/cart";
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { browser } from '$app/environment'
|
||||
import { onMount } from 'svelte'
|
||||
import { fade, fly } from 'svelte/transition'
|
||||
import { quartOut } from 'svelte/easing'
|
||||
import { smoothScroll } from '$utils/stores'
|
||||
import { cartOpen, cartData, cartAmount, cartIsUpdating } from '$utils/stores/shop'
|
||||
import { initSwell, getCart, updateCartItem, removeCartItem } from '$utils/functions/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'
|
||||
import { sendEvent } from '$utils/analytics';
|
||||
|
||||
|
||||
// Block scroll if cart is open
|
||||
$: if (browser && $smoothScroll) {
|
||||
if ($cartOpen) {
|
||||
$smoothScroll.stop()
|
||||
} else {
|
||||
$smoothScroll.start()
|
||||
}
|
||||
|
||||
document.documentElement.classList.toggle('block-scroll', $cartOpen)
|
||||
}
|
||||
|
||||
|
||||
// Closing the cart
|
||||
const handleCloseCart = () => {
|
||||
$cartOpen = false
|
||||
}
|
||||
|
||||
// Item quantity changed
|
||||
const changedQuantity = async ({ detail: { id, quantity } }) => {
|
||||
// Cart is now updating
|
||||
$cartIsUpdating = true
|
||||
|
||||
// Update cart item
|
||||
const updatedCart = await updateCartItem(id, quantity)
|
||||
if (updatedCart) {
|
||||
// Store new cart data
|
||||
$cartData = updatedCart
|
||||
// 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 removeCartItem(id)
|
||||
if (updatedCart) {
|
||||
// Store new cart data
|
||||
$cartData = updatedCart
|
||||
// Cart is updated
|
||||
$cartIsUpdating = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMount(async () => {
|
||||
// Init Swell
|
||||
initSwell()
|
||||
|
||||
// Fetch cart
|
||||
const cart = await getCart()
|
||||
if (cart) {
|
||||
// Store cart data
|
||||
$cartData = cart
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if $cartOpen}
|
||||
<div class="cart-switcher" transition: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}
|
||||
<CartItem {item}
|
||||
on:updatedQuantity={changedQuantity}
|
||||
on:removed={removedItem}
|
||||
/>
|
||||
{/each}
|
||||
{:else}
|
||||
<div class="cart__empty shadow-small" transition:fade={{ duration: 600 }}>
|
||||
<div class="icon">
|
||||
<Icon icon="bag" label="Shopping bag icon" />
|
||||
</div>
|
||||
<p>Your cart is empty</p>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if $cartIsUpdating}
|
||||
<div class="cart__update"
|
||||
in:fly={{ y: 8, duration: 600, easing: quartOut }}
|
||||
out:fly={{ y: -8, duration: 600, easing: quartOut }}
|
||||
>
|
||||
<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>Free shipping worldwide!</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"
|
||||
on:click={() => sendEvent('cartCheckout', { props: { amount: $cartAmount }})}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</footer>
|
||||
</aside>
|
||||
|
||||
<div class="cart-overlay"
|
||||
transition:fade={{ duration: 600, easing: quartOut }}
|
||||
on:click={handleCloseCart}
|
||||
/>
|
||||
{/if}
|
||||
Reference in New Issue
Block a user