Add checkout page

Give shadows to more elements
Fix broken cart
Add notice on checkout if item is no-longer available
Remove spacing on bottom of menu-item list with an added check
Add leg
This commit is contained in:
Michał 2024-05-16 14:45:16 +01:00
parent 261939b445
commit 9a683e9605
17 changed files with 147 additions and 40 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

View file

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { link } from 'svelte-spa-router'; import { link } from 'svelte-spa-router';
import { Plus, Minus, Trash, Acorn, Fish, GrainsSlash, Leaf, Pepper } from "phosphor-svelte"; import { Plus, Minus, Trash, Acorn, Fish, GrainsSlash, Leaf, Pepper, SealWarning } from "phosphor-svelte";
import { type CartItem, Labels } from "../lib/types"; import { type CartItem, Labels } from "../lib/types";
import Cart from "../lib/cart"; import Cart from "../lib/cart";
@ -24,6 +24,12 @@
</script> </script>
<div class="container"> <div class="container">
{#if !item.data.availability}
<div class="basket-item-notice">
<SealWarning weight="fill" />&nbsp;&nbsp;<span>Item is no-longer for sale</span>
</div>
{/if}
{#if item.data.images && item.data.images[0]} {#if item.data.images && item.data.images[0]}
<img src="{item.data.images[0]}" alt="Item" class="basket-item-image"> <img src="{item.data.images[0]}" alt="Item" class="basket-item-image">
{:else} {:else}
@ -63,6 +69,8 @@
@import "../styles/vars"; @import "../styles/vars";
.container { .container {
position: relative;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -71,6 +79,25 @@
overflow: hidden; overflow: hidden;
} }
.basket-item-notice {
width: 100%;
height: 30px;
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
font-size: $font-size-p;
background: $color-error;
color: $color-on-error;
box-shadow: 0 1px 0.5px rgba(#000, 0.3);
}
.basket-item-image { .basket-item-image {
margin: $spacing-small; margin: $spacing-small;

View file

@ -26,6 +26,8 @@
max-height: 350px; max-height: 350px;
border-radius: $border-radius-large; border-radius: $border-radius-large;
box-shadow: 0 1px 0.5px rgba(#000, 0.3);
} }
> .container { > .container {

View file

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { onMount } from "svelte"; import { onMount } from "svelte";
import { link } from 'svelte-spa-router'; import { link } from 'svelte-spa-router';
import { Acorn, Fish, Leaf, Pepper, ArrowUpRight, GrainsSlash } from 'phosphor-svelte'; import { Acorn, Fish, Leaf, Pepper, ArrowUpRight, GrainsSlash, SealWarning } from 'phosphor-svelte';
import { type Item, Labels} from "../lib/types"; import { type Item, Labels} from "../lib/types";
import LoadingImage from '/assets/MenuItemLoadingAlt.svg'; import LoadingImage from '/assets/MenuItemLoadingAlt.svg';
@ -23,6 +23,10 @@
<svelte:window on:resize={keepSquare}></svelte:window> <svelte:window on:resize={keepSquare}></svelte:window>
<div class="menu-item" bind:this={element}> <div class="menu-item" bind:this={element}>
{#if !item.availability}
<!-- <div class="menu-item-notice"><span>Item is no-longer for sale</span></div>-->
{/if}
{#if item.images && item.images[0]} {#if item.images && item.images[0]}
<img src={item.images[0]} alt="" class="menu-item-image"> <img src={item.images[0]} alt="" class="menu-item-image">
{:else} {:else}

View file

@ -45,8 +45,8 @@ function createCartStore() {
} }
cart.update((cart: CartRecord) => { cart.update((cart: CartRecord) => {
if (cart.uuid.amount <= 0) delete cart.uuid; if (cart[uuid].amount <= 0) delete cart[uuid]; // skipcq: JS-0320
if (cart.uuid.amount > 99) cart.uuid.amount = 99; if (cart[uuid].amount > 99) cart[uuid].amount = 99; // skipcq: JS-0320
return cart; return cart;
}); });
} }

View file

@ -6,9 +6,7 @@ const TestData: Item[] = [
availability: true, availability: true,
name: "Bar of Soap", name: "Bar of Soap",
price: 69.99, price: 69.99,
description: ` description: `Example`,
Example
`,
labels: [Labels.vegan, Labels.spicy], labels: [Labels.vegan, Labels.spicy],
}, },
{ {
@ -16,9 +14,7 @@ Example
availability: true, availability: true,
name: "Sock", name: "Sock",
price: 21, price: 21,
description: ` description: `Example`,
Example
`,
labels: [Labels.vegan, Labels.fish, Labels.nut, Labels.spicy], labels: [Labels.vegan, Labels.fish, Labels.nut, Labels.spicy],
}, },
{ {
@ -26,9 +22,7 @@ Example
availability: true, availability: true,
name: "Brick", name: "Brick",
price: 0, price: 0,
description: ` description: `Example`,
Example
`,
labels: [Labels.spicy], labels: [Labels.spicy],
}, },
{ {
@ -36,9 +30,7 @@ Example
availability: true, availability: true,
name: "Toast", name: "Toast",
price: 4382749832743, price: 4382749832743,
description: ` description: `Example`,
Example
`,
labels: [Labels.gluten], labels: [Labels.gluten],
}, },
{ {
@ -46,9 +38,7 @@ Example
availability: true, availability: true,
name: "water", name: "water",
price: 1, price: 1,
description: ` description: `Example`,
Example
`,
labels: [Labels.fish], labels: [Labels.fish],
}, },
{ {
@ -56,11 +46,24 @@ Example
availability: true, availability: true,
name: "half eaten mouldy bread", name: "half eaten mouldy bread",
price: -99, price: -99,
description: ` description: `Example`,
Example
`,
labels: [Labels.nut], labels: [Labels.nut],
}, },
{
uuid: "cup_cake_leg",
availability: false,
name: "Eated Cupcake",
price: 1.69,
description: `
aurgh
Contains:
- Single Pringle GwaGwa
- Cupcake with icing eated
`,
labels: [Labels.nut],
images: ["/item_images/cupcake.jpg", "/item_images/cupcake.jpg", "/item_images/cupcake.jpg"],
},
// { // {
// uuid: "gwagwa", // uuid: "gwagwa",
// availability: false, // availability: false,

View file

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { link } from 'svelte-spa-router'; import { link } from 'svelte-spa-router';
import { Basket } from "phosphor-svelte"; import {ArrowLeft, ArrowRight, Basket} from "phosphor-svelte";
import { type CartItem } from "../lib/types"; import { type CartItem } from "../lib/types";
import { getPopularToday } from "../lib/test-api"; import { getPopularToday } from "../lib/test-api";
@ -31,10 +31,10 @@
{#if totalItems} {#if totalItems}
<h1>Cart</h1> <h1>Cart</h1>
<button id="checkout-button">Checkout</button> <a id="checkout-button" href="/cart/checkout" use:link>Checkout&nbsp;<ArrowRight /></a>
<h2>Order total: £{totalPrice}</h2> <h2>Order total: £{totalPrice}</h2>
{#each items as [key, item]} {#each items as [_, item]}
<div class="basket-item"> <div class="basket-item">
<BasketItem item={item}/> <BasketItem item={item}/>
</div> </div>
@ -85,7 +85,9 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
text-shadow: 0 1px 0.5px rgba($color-dark, 0.3);; text-shadow: 0 1px 0.5px rgba($color-dark, 0.3);
text-decoration: none;
font-size: $font-size-p;
border: 0 solid transparent; border: 0 solid transparent;
border-radius: 9999px; border-radius: 9999px;

View file

@ -0,0 +1,40 @@
<script lang="ts">
import { link } from "svelte-spa-router";
import { ArrowLeft } from "phosphor-svelte";
</script>
<a href="/cart" use:link id="back-button"><ArrowLeft />&nbsp;Back</a>
<h1>Cart</h1>
<h2>Order total: £Balls</h2>
<style lang="scss">
@import "../styles/vars";
#back-button {
margin-top: 8px;
padding: 0 $spacing-small;
width: max-content;
height: 30px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
font-size: $font-size-p;
text-decoration: none;
border-radius: 9999px;
background-color: transparent;
color: $color-on-background;
&:hover {
background-color: $color-light;
color: $color-on-light;
}
}
</style>

View file

@ -101,6 +101,7 @@
#map { #map {
min-width: 550px; min-width: 550px;
border-radius: $border-radius-normal; border-radius: $border-radius-normal;
box-shadow: 0 1px 0.5px rgba(#000, 0.3);
} }
#contact { #contact {

View file

@ -184,6 +184,9 @@
max-width: $sizing-default-width; max-width: $sizing-default-width;
height: 45px; height: 45px;
position: sticky;
top: calc($spacing-small + $sizing-navigation-height);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -194,6 +197,8 @@
background: $color-dark; background: $color-dark;
color: $color-on-dark; color: $color-on-dark;
box-shadow: 0 1px 0.5px rgba(#000, 0.3);
&.error { &.error {
background: $color-error; background: $color-error;
color: $color-on-error; color: $color-on-error;

View file

@ -141,14 +141,16 @@
{#await items} {#await items}
<LoadingBar /> <LoadingBar />
{:then items} {:then items}
{#each items as section} {#each items as section, i}
<h2>{section.name}</h2> <h2>{section.name}</h2>
{#if section.items.length > 0} {#if section.items.length > 0}
<MenuList items={section.items} /> <MenuList items={section.items} />
{:else} {:else}
<p>No results</p> <p>No results</p>
{/if} {/if}
<div class="spacer" /> {#if i !== items.length -1}
<div class="spacer" />
{/if}
{/each} {/each}
{:catch error} {:catch error}
<p>{error}</p> <p>{error}</p>

View file

@ -41,9 +41,10 @@ const routes = {
userData: { showNavBar: true, fullWidth: false }, userData: { showNavBar: true, fullWidth: false },
}), }),
"/cart/checkout": wrap({ "/cart/checkout": wrap({
component: Page404, asyncComponent: () => import("./pages/Checkout.svelte"),
loadingComponent: PageLoading,
conditions: [], conditions: [],
userData: { showNavBar: false, fullWidth: true }, userData: { showNavBar: true, fullWidth: true },
}), }),
"/booking": wrap({ "/booking": wrap({
asyncComponent: () => import("./pages/Booking.svelte"), asyncComponent: () => import("./pages/Booking.svelte"),

View file

@ -1,10 +1,11 @@
.announcement-banner { .announcement-banner {
position: relative; position: relative;
border-radius: $border-radius-normal; border-radius: $border-radius-large;
background-color: $color-light; background-color: $color-light;
color: $color-on-light; color: $color-on-light;
box-shadow: 0 1px 0.5px rgba(#000, 0.3);
overflow: hidden; overflow: hidden;
img { img {
@ -13,7 +14,6 @@
display: block; display: block;
//aspect-ratio: 16 / 7;
object-fit: cover; object-fit: cover;
} }
} }
@ -26,7 +26,6 @@
img { img {
height: 250px; height: 250px;
//aspect-ratio: 16 / 9;
aspect-ratio: unset; aspect-ratio: unset;
} }
} }

View file

@ -117,15 +117,11 @@
font-weight: $font-weight-black; font-weight: $font-weight-black;
text-decoration: underline; text-decoration: underline;
color: $color-on-light; color: $color-on-light;
//background-color: $color-primary;
//color: $color-on-primary;
} }
} }
&.selected { &.selected {
> button { > button {
//background-color: $color-dark;
//color: $color-on-dark;
background-color: $color-primary; background-color: $color-primary;
color: $color-on-primary; color: $color-on-primary;
} }

View file

@ -7,6 +7,8 @@
background-color: $color-light; background-color: $color-light;
color: $color-on-light; color: $color-on-light;
box-shadow: 0 1px 0.5px rgba(#000, 0.3);
.header { .header {
padding: $spacing-normal; padding: $spacing-normal;
display: flex; display: flex;

View file

@ -3,12 +3,35 @@
position: relative; position: relative;
border-radius: $border-radius-large; border-radius: $border-radius-normal;
background-color: $color-dark; background-color: $color-dark;
box-shadow: 0 1px 0.5px rgba(#000, 0.3);
overflow: hidden; overflow: hidden;
} }
.menu-item-notice {
padding: $spacing-small;
width: 100%;
min-height: 40px;
position: absolute;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
font-size: $font-size-p;
text-align: center;
background: $color-error;
color: $color-on-error;
box-shadow: 0 1px 0.5px rgba(#000, 0.3);
z-index: 3;
}
.menu-item-image { .menu-item-image {
width: 100%; width: 100%;
height: 100%; height: 100%;

View file

@ -51,8 +51,8 @@ nav {
.nav-basket { .nav-basket {
padding: 0 $spacing-xsmall; padding: 0 $spacing-xsmall;
min-width: 17px; min-width: 18px;
min-height: 17px; min-height: 18px;
display: inline-block; display: inline-block;