mirror of
https://github.com/Fluffy-Bean/TastyBites.git
synced 2025-05-20 10:24:53 +00:00
Improve Carts reliability
Nicer empty cart page Check on page load if cart is valid
This commit is contained in:
parent
67c8794427
commit
764aaa48ea
5 changed files with 117 additions and 31 deletions
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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,12 +35,22 @@ function createCartStore() {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
const newItem: CartItem = {
|
let cartData: Item;
|
||||||
uuid: uuid,
|
|
||||||
amount: amount,
|
try {
|
||||||
data: await getItemByUUID(uuid),
|
let data: Item | Error = await getItemByUUID(uuid);
|
||||||
};
|
if (data instanceof Error) {
|
||||||
cart.update((cart: CartItem[]) => [...cart, newItem]);
|
return;
|
||||||
|
}
|
||||||
|
cartData = <Item>data;
|
||||||
|
} finally {
|
||||||
|
const newItem: CartItem = {
|
||||||
|
uuid: uuid,
|
||||||
|
amount: amount,
|
||||||
|
data: cartData,
|
||||||
|
};
|
||||||
|
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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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>
|
Loading…
Add table
Add a link
Reference in a new issue