Skip to content
64 changes: 64 additions & 0 deletions src/components/Cart.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<script>
export let products;
export let summary = false;
export let header = true;
export let footer = true;
export let caption = "";

import { onMount } from 'svelte/';
import { store } from './store.js';

onMount(() => {
// `persist` returns an unsubscribe callback
store.persist();
});

</script>

<style>

</style>

{#if products.length > 0}
<table>
{#if caption}<caption>Shopping cart</caption>{/if}
{#if header}
<thead>
<tr>
<th scope="col">Product</th>
<th scope="col">Unit price</th>
<th scope="col">Units</th>
<th scope="col">Total</th>
</tr>
</thead>
{/if}
<tbody>
{#each products as product}
{#each product.variations as variation}
{#if !summary || $store[`${variation.slug}/${product.slug}`]}
<tr>
<th scope="row">{variation.description} {product.name}</th>
<td></td>
<td>
<button on:click={store.decrement(`${variation.slug}/${product.slug}`)}>-</button>
{$store[`${variation.slug}/${product.slug}`]}
<button on:click={store.increment(`${variation.slug}/${product.slug}`)}>+</button>
</td>
<td></td>
</tr>
{/if}
{/each}
{/each}
</tbody>
{#if footer}
<tfoot>
<tr>
<th scope="row">Grand total</th>
<td></td>
<td></td>
<td></td>
</tr>
</tfoot>
{/if}
</table>
{/if}
13 changes: 6 additions & 7 deletions src/components/Tile.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<script>
import Cart from './Cart.svelte';

export let id;
export let name;
export let description;
export let image;
export let available;
export let product;

let {name, description, image, available} = product;

// Could be a nice piece of code to move to a filter
const ASSETS_BASE = /^https:\/\/res.cloudinary.com\/jflower\/image\/upload\//;
Expand Down Expand Up @@ -58,9 +59,7 @@ aside:target {
<h2 class="font-display text-center text-2xl">{name}</h2>
<p class="max-w-prose">{description}</p>
{#if available}
<a href="https://wa.me/31611134040?text={wamsg}" target="_blank" class="w-1/2 max-w-xs self-center mt-2" rel="external nofollow noopener noreferrer">
<button class="w-full border-2 border-white font-display text-white focus:bg-yellow-50 active:bg-yellow-50 hover:bg-yellow-50 focus:border-yellow-600 active:border-yellow-600 hover:border-yellow-600 focus:text-yellow-600 active:text-yellow-600 hover:text-yellow-600 py-2 px-3 rounded-md">Add to cart</button>
</a>
<Cart hydrate-client={{products: [product]}} />
{/if}
</div>
</aside>
Expand Down
55 changes: 55 additions & 0 deletions src/components/store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { writable } from 'svelte/store';

// I'm not currently honouring anything but "THEIRS"
const MERGE_STRATEGY = "THEIRS";
const STORE_IDENTIFIER = "jflower-shopping-cart";

const { subscribe, set, update } = writable({});

let unsubscribe, isPersistent = false;

function add( n, product) {
update((store) => {
if (product in store) {
store[product] += n;
} else {
store[product] = n;
}
return store;
});
}

function remove( n, product ) {
update((store) => {
if (product in store && store[product] < n) {
store[product] = 0;
} else if (product in store) {
store[product] -= n;
} else {
store[product] = 0;
}
return store;
});
}

function increment( product ) { add( 1, product ); }
function decrement( product ) { remove( 1, product ); }

function trash( product ) {
update((store) => {
store[product] = 0;
return store;
});
}

function persist( identifier=STORE_IDENTIFIER, storage=localStorage, stategy=MERGE_STRATEGY ) {
if (isPersistent) return console.warn("J Flower Cake: Store is already persistent");
const store = storage.getItem(identifier);
if (store) {
update((_) => JSON.parse(store));
}
unsubscribe = subscribe((store) => storage.setItem(identifier, JSON.stringify(store)));
return isPersistent = true && unsubscribe;
}

export const store = { subscribe, add, remove, increment, decrement, trash, persist };
5 changes: 4 additions & 1 deletion src/routes/home/Home.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script>
import Tile from '../../components/Tile.svelte';
import Cart from '../../components/Cart.svelte';

export let data;
</script>
Expand All @@ -25,6 +26,8 @@ section {

<section class="grid justify-center">
{#each data.products as product, id}
<Tile {id} {...product} />
<Tile {id} {product} />
{/each}
</section>

<Cart hydrate-client={{products: data.products}} />