Improve Carts reliability

Nicer empty cart page
Check on page load if cart is valid
This commit is contained in:
Michał Gdula 2024-05-03 12:31:12 +01:00
parent 67c8794427
commit 764aaa48ea
5 changed files with 117 additions and 31 deletions

View file

@ -30,6 +30,9 @@
display: flex; display: flex;
flex-direction: row; flex-direction: row;
// Move background out of way of the image
background-position: 135px -43px;
overflow: hidden; overflow: hidden;
ul { ul {
@ -49,8 +52,8 @@
.basket-item-image { .basket-item-image {
margin: $spacing-small; margin: $spacing-small;
width: 140px; width: 120px;
height: 140px; height: 120px;
border-radius: $border-radius-normal; border-radius: $border-radius-normal;

View file

@ -1,13 +1,21 @@
import { get, writable } from "svelte/store"; import { get, writable } from "svelte/store";
import type { CartItem } from './types'; import type { Item, CartItem } from './types';
import { getItemByUUID } from "./test-api"; import { getItemByUUID, postVerifyCart } from "./test-api";
// Load content from localstorage // Load content from localstorage
let local = []; let local: CartItem[] = [];
try { try {
local = JSON.parse(localStorage.getItem("basket")) || [] let verified = await postVerifyCart(
JSON.parse(localStorage.getItem("basket")) || []
);
if (verified instanceof Error) {
throw new Error("Bruh");
}
local = <CartItem[]>verified;
} catch { } catch {
console.error("Failed to load cart") console.error("Failed to load cart")
} }
@ -27,13 +35,23 @@ function createCartStore() {
}); });
if (!found) { if (!found) {
let cartData: Item;
try {
let data: Item | Error = await getItemByUUID(uuid);
if (data instanceof Error) {
return;
}
cartData = <Item>data;
} finally {
const newItem: CartItem = { const newItem: CartItem = {
uuid: uuid, uuid: uuid,
amount: amount, amount: amount,
data: await getItemByUUID(uuid), data: cartData,
}; };
cart.update((cart: CartItem[]) => [...cart, newItem]); cart.update((cart: CartItem[]) => [...cart, newItem]);
} }
}
// Remove items that have an amount of 0 or lower // Remove items that have an amount of 0 or lower
cart.update((cart) => cart.filter((item) => item.amount > 0)) cart.update((cart) => cart.filter((item) => item.amount > 0))

View file

@ -1,10 +1,10 @@
import type { Item } from './types'; import type {CartItem, Item} from './types';
import TestData from './test-data'; import TestData from './test-data';
let cache = { let cache = {
announcement_banner: null, announcement_banner: undefined,
popular_today: null, popular_today: undefined,
}; };
@ -15,28 +15,30 @@ async function fakeDelay(timeout: number = 1000) {
} }
export async function getAnnouncements() { export async function getAnnouncements(): Promise<{image: string}> {
if (cache.announcement_banner) { if (cache.announcement_banner) {
return cache.announcement_banner; return cache.announcement_banner;
} }
const data = { const data = {
image: "/BannerExampleImage.jpg", image: "/BannerExampleImage.jpg",
}; };
cache.announcement_banner = data; cache.announcement_banner = data;
await fakeDelay(200) await fakeDelay(200)
return data; return data;
} }
export async function getPopularToday() { export async function getPopularToday(): Promise<Item[]> {
if (cache.popular_today) { if (cache.popular_today) {
return cache.popular_today; return cache.popular_today;
} }
const data: Item[] = TestData;
const data = TestData;
cache.popular_today = data; cache.popular_today = data;
await fakeDelay(200) await fakeDelay(200)
return data; return data;
} }
@ -61,8 +63,8 @@ export async function getMenuItems() {
} }
export async function getItemsByUUID(items: string[]) { export async function getItemsByUUID(items: string[]): Promise<Item[] | Error> {
let data = []; let data: Item[] = [];
TestData.forEach((itemInDatabase: Item) => { TestData.forEach((itemInDatabase: Item) => {
items.forEach((itemInRequest) => { items.forEach((itemInRequest) => {
@ -82,9 +84,12 @@ export async function getItemsByUUID(items: string[]) {
} }
export async function getItemByUUID(uuid: string) { export async function getItemByUUID(uuid: string): Promise<Item | Error> {
let data = await getItemsByUUID([uuid]); let data: Item[] | Error = await getItemsByUUID([uuid]);
if (data instanceof Error) {
throw new Error("Resource could not be found");
}
if (data.length != 1) { if (data.length != 1) {
throw new Error("Resource could not be found"); throw new Error("Resource could not be found");
} }
@ -93,7 +98,7 @@ export async function getItemByUUID(uuid: string) {
} }
export async function postContactEmail(name: string, email: string, message: string) { export async function postContactEmail(name: string, email: string, message: string): Promise<string | Error> {
await fakeDelay(200) await fakeDelay(200)
if (!name) { if (!name) {
@ -110,3 +115,36 @@ export async function postContactEmail(name: string, email: string, message: str
return "Check your email to confirm the message!"; return "Check your email to confirm the message!";
} }
export async function postVerifyCart(currentCartData: CartItem[]): Promise<CartItem[] | Error> {
if (currentCartData.length <= 0) {
return [];
}
let itemUUIDs: string[] = currentCartData.map((item) => item.uuid);
let verifiedItems: Item[] | Error = await getItemsByUUID(itemUUIDs);
if (verifiedItems instanceof Error) {
return new Error("Could not collect new cart information");
}
let newCartData: CartItem[] = [];
currentCartData.forEach((currentItem) => {
let data: Item;
verifiedItems.forEach((verifiedItem) => {
if (verifiedItem.uuid === currentItem.uuid) {
data = verifiedItem;
}
})
if (data) {
newCartData.push({
uuid: currentItem.uuid,
amount: currentItem.amount,
data: data,
});
}
});
return newCartData;
}

View file

@ -49,7 +49,7 @@ const TestData: Item[] = [
name: "GwaGwa", name: "GwaGwa",
price: 69, price: 69,
labels: [Labels.nut], labels: [Labels.nut],
// image: "/dab.jpg", image: "/dab.jpg",
}, },
{ {
uuid: "hogmelon", uuid: "hogmelon",

View file

@ -12,19 +12,23 @@
$: totalPrice = $Cart.map((item) => item.amount * item.data.price).reduce((a, b) => a + b, 0); $: totalPrice = $Cart.map((item) => item.amount * item.data.price).reduce((a, b) => a + b, 0);
</script> </script>
<h1>Cart</h1>
<button id="checkout-button">Checkout</button>
<h2>Order total: £{totalPrice}</h2>
{#if items.length > 0} {#if items.length > 0}
<h1>Cart</h1>
<button id="checkout-button">Checkout</button>
<h2>Order total: £{totalPrice}</h2>
{#each items as item} {#each items as item}
<div class="basket-item"> <div class="basket-item">
<BasketItem item={item}/> <BasketItem item={item}/>
</div> </div>
{/each} {/each}
{:else} {:else}
<p>Empty.....</p> <div id="emptyCart">
<h1>Empty Cart!</h1>
<p>Go add some items from the menu...</p>
</div>
{/if} {/if}
<div class="spacer" /> <div class="spacer" />
@ -72,4 +76,27 @@
outline: 0 solid transparent outline: 0 solid transparent
} }
} }
#emptyCart {
margin-left: auto;
margin-right: auto;
padding: $spacing-large;
max-width: $sizing-default-width;
display: flex;
flex-direction: column;
> h1 {
display: flex;
justify-content: center;
align-items: center;
font-size: $font-size-very-fucking-big;
text-align: center;
}
> p {
text-align: center;
}
}
</style> </style>