mirror of
https://github.com/Fluffy-Bean/TastyBites.git
synced 2024-12-28 02:16:07 +00:00
Improve Item page
Add 500 page and dedicated 404 page Add fake cache to tester API Adjust some styles for better readability and usability
This commit is contained in:
parent
40c19335cf
commit
383f22bdf8
|
@ -14,20 +14,19 @@
|
|||
cart: {path: '/cart', className: 'active'},
|
||||
}
|
||||
|
||||
let windowScrollY = 0;
|
||||
let windowWidth = 0;
|
||||
let scrollY = 0;
|
||||
let width = 0;
|
||||
|
||||
let oldLocation = undefined;
|
||||
let fullWidth = false;
|
||||
let showNavBar = false;
|
||||
|
||||
$: scrolled = windowScrollY > 0
|
||||
$: mobile = windowWidth < 700
|
||||
|
||||
function routeLoading(event) {
|
||||
if (event.detail.location === oldLocation) {
|
||||
console.log("Fake!");
|
||||
return; // not an actual change
|
||||
}
|
||||
|
||||
showNavBar = event.detail.userData.showNavBar;
|
||||
fullWidth = event.detail.userData.fullWidth;
|
||||
oldLocation = event.detail.location;
|
||||
|
@ -38,15 +37,18 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<svelte:window bind:scrollY={windowScrollY} bind:innerWidth={windowWidth} />
|
||||
<svelte:window
|
||||
bind:scrollY={scrollY}
|
||||
bind:innerWidth={width}
|
||||
/>
|
||||
<svelte:head>
|
||||
<link rel="stylesheet" href="https://api.fontshare.com/v2/css?f[]=erode@300,301,400,401,500,501,600,601,700,701,1,2&display=swap">
|
||||
</svelte:head>
|
||||
|
||||
|
||||
{#if showNavBar }
|
||||
<nav class:scrolled={scrolled} class:mobile={mobile}>
|
||||
{#if !mobile}
|
||||
<nav class:scrolled={scrollY > 0} class:mobile={width < 700}>
|
||||
{#if !(width < 700)}
|
||||
<ul style="justify-content: flex-end">
|
||||
<li use:active={links.home}><a href="/" use:link>Home</a></li>
|
||||
<li use:active={links.menu}><a href="/menu" use:link>Menu</a></li>
|
||||
|
|
|
@ -6,9 +6,7 @@
|
|||
|
||||
|
||||
{#await announcement}
|
||||
<div class="announcement-banner-loading">
|
||||
<div />
|
||||
</div>
|
||||
<div class="announcement-banner-loading" />
|
||||
{:then announcement}
|
||||
<div class="announcement-banner">
|
||||
<img src={announcement.image} alt="">
|
||||
|
@ -35,12 +33,15 @@
|
|||
|
||||
overflow: hidden;
|
||||
|
||||
> div {
|
||||
&::after {
|
||||
content: '';
|
||||
|
||||
position: absolute;
|
||||
top: $padding;
|
||||
right: $padding;
|
||||
bottom: $padding;
|
||||
left: $padding;
|
||||
|
||||
border-radius: calc($border-radius-large - $padding);
|
||||
background-color: rgba($color-background, 0.9);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
align-items: center;
|
||||
|
||||
p {
|
||||
font-size: $font-size-h5;
|
||||
font-size: $font-size-h6;
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,23 +4,19 @@
|
|||
|
||||
import LoadingImage from '/MenuItemLoadingAlt.svg';
|
||||
|
||||
export let id;
|
||||
export let name;
|
||||
export let price;
|
||||
export let image;
|
||||
export let labels = []
|
||||
export let item = {};
|
||||
</script>
|
||||
|
||||
<div class="menu-item">
|
||||
{#if !image}
|
||||
{#if !item.image}
|
||||
<img src={LoadingImage} alt="" class="menu-item-image">
|
||||
{:else}
|
||||
<img src={image} alt="" class="menu-item-image">
|
||||
<img src={item.image} alt="" class="menu-item-image">
|
||||
{/if}
|
||||
|
||||
<div class="menu-item-header">
|
||||
<ul>
|
||||
{#each labels as label}
|
||||
{#each item.labels as label}
|
||||
{#if label === "vegan"}
|
||||
<li class="vegan"><Leaf weight="fill" /></li>
|
||||
{/if}
|
||||
|
@ -38,12 +34,14 @@
|
|||
{/if}
|
||||
{/each}
|
||||
</ul>
|
||||
<a href="/item/{id}" use:link>View <ArrowUpRight /></a>
|
||||
<a href="/item/{item.uuid}" use:link>
|
||||
View <ArrowUpRight />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<ul class="menu-item-detail">
|
||||
<li>{name}</li>
|
||||
<li>£{price}</li>
|
||||
<li>{item.name}</li>
|
||||
<li>£{item.price}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -7,13 +7,7 @@
|
|||
<ul>
|
||||
{#each items as item}
|
||||
<li>
|
||||
<MenuItem
|
||||
id={item.name}
|
||||
name={item.name}
|
||||
price={item.price}
|
||||
image={item.image}
|
||||
labels={item.labels}
|
||||
/>
|
||||
<MenuItem item={item} />
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
@ -31,4 +25,4 @@
|
|||
li {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
@ -1,19 +1,32 @@
|
|||
import Items from '%/lib/test-data.js';
|
||||
|
||||
let cache = {};
|
||||
|
||||
|
||||
async function fakeDelay(timeout = 1000) {
|
||||
await new Promise(resolve => setTimeout(resolve, timeout));
|
||||
}
|
||||
|
||||
export async function getAnnouncements() {
|
||||
if (cache.announcement_banner !== undefined) {
|
||||
return cache.announcement_banner;
|
||||
}
|
||||
|
||||
const data = {
|
||||
image: "/BannerExampleImage.jpg",
|
||||
};
|
||||
await fakeDelay(2000)
|
||||
cache.announcement_banner = data;
|
||||
await fakeDelay(5000)
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function getPopularToday() {
|
||||
if (cache.popular_today !== undefined) {
|
||||
return cache.popular_today;
|
||||
}
|
||||
|
||||
const data = Items;
|
||||
cache.popular_today = data;
|
||||
await fakeDelay(2000)
|
||||
return data;
|
||||
}
|
||||
|
@ -33,6 +46,24 @@ export async function getMenuItems() {
|
|||
items: Items,
|
||||
},
|
||||
];
|
||||
await fakeDelay(2000)
|
||||
await fakeDelay(20)
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function getItemByUUID(uuid) {
|
||||
let data;
|
||||
|
||||
Items.forEach((item) => {
|
||||
if (item.uuid === uuid) {
|
||||
data = item;
|
||||
}
|
||||
})
|
||||
|
||||
await fakeDelay(1000)
|
||||
|
||||
if (!data) {
|
||||
throw new Error("Resource could not be found");
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
|
@ -7,6 +7,7 @@ const Items = [
|
|||
name: "Bar of Soap",
|
||||
price: 69.99,
|
||||
labels: ["vegan", "spicy"],
|
||||
detail: "Example",
|
||||
},
|
||||
// sock: {
|
||||
{
|
||||
|
@ -14,6 +15,7 @@ const Items = [
|
|||
name: "Sock",
|
||||
price: 21,
|
||||
labels: ["vegan", "fish", "nut", "spicy"],
|
||||
detail: "Example",
|
||||
},
|
||||
// brick: {
|
||||
{
|
||||
|
@ -21,6 +23,7 @@ const Items = [
|
|||
name: "Brick",
|
||||
price: 0,
|
||||
labels: ["spicy"],
|
||||
detail: "Example",
|
||||
},
|
||||
// toast: {
|
||||
{
|
||||
|
@ -28,6 +31,7 @@ const Items = [
|
|||
name: "Toast",
|
||||
price: 4382749832743,
|
||||
labels: ["gluten"],
|
||||
detail: "Example",
|
||||
},
|
||||
// water: {
|
||||
{
|
||||
|
@ -35,6 +39,7 @@ const Items = [
|
|||
name: "water",
|
||||
price: 1,
|
||||
labels: ["fish"],
|
||||
detail: "Example",
|
||||
},
|
||||
// mouldy_bread: {
|
||||
{
|
||||
|
@ -42,6 +47,7 @@ const Items = [
|
|||
name: "half eaten mouldy bread",
|
||||
price: -99,
|
||||
labels: ["nut"],
|
||||
detail: "Example",
|
||||
},
|
||||
// gwagwa: {
|
||||
{
|
||||
|
@ -58,6 +64,7 @@ const Items = [
|
|||
price: "1111",
|
||||
labels: ["fish"],
|
||||
image: "/wathog.jpg",
|
||||
detail: "Example",
|
||||
},
|
||||
// bluhog: {
|
||||
{
|
||||
|
@ -66,6 +73,7 @@ const Items = [
|
|||
price: "ARUGH",
|
||||
labels: ["nut", "gluten", "spicy"],
|
||||
image: "/sonichog.jpg",
|
||||
detail: "Example",
|
||||
},
|
||||
];
|
||||
|
||||
|
|
32
front/src/pages/Page500.svelte
Normal file
32
front/src/pages/Page500.svelte
Normal file
|
@ -0,0 +1,32 @@
|
|||
<script>
|
||||
import { SmileySad } from "phosphor-svelte";
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<h1>Server Fucking Died! <SmileySad weight="fill" /></h1>
|
||||
<p>Error 500</p>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import "%/styles/vars";
|
||||
|
||||
div {
|
||||
padding: $spacing-large;
|
||||
|
||||
height: 100%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
h1 {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
font-size: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
p {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
|
@ -119,6 +119,7 @@
|
|||
min-width: 250px;
|
||||
max-width: calc(100vw - calc(2 * $spacing-normal));
|
||||
resize: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
button {
|
||||
|
|
|
@ -1,95 +1,161 @@
|
|||
<script>
|
||||
import { replace } from "svelte-spa-router";
|
||||
|
||||
import MenuList from "%/components/MenuList.svelte";
|
||||
import LoadingBar from "%/components/LoadingBar.svelte";
|
||||
import { getPopularToday, getItemByUUID } from "%/lib/test-api.js";
|
||||
import LoadingImage from "/MenuItemLoading.svg";
|
||||
import Items from '%/lib/test-data.js';
|
||||
|
||||
let items = Items;
|
||||
export let params;
|
||||
|
||||
export let params = {};
|
||||
$: item = getItemByUUID(params.uuid)
|
||||
// ToDo: Fix this, keeps fucking breaking
|
||||
// NOT WORKING FUCK
|
||||
// .catch((error) => {
|
||||
// console.error(error);
|
||||
// if (error === "404") {
|
||||
// replace("/ForOhFor");
|
||||
// }
|
||||
// replace("/ServerError");
|
||||
// });
|
||||
let popularToday = getPopularToday();
|
||||
</script>
|
||||
|
||||
<div class="main">
|
||||
<div class="images">
|
||||
<div>
|
||||
<img src={LoadingImage} alt="">
|
||||
{#await item}
|
||||
<div id="images">
|
||||
<div>
|
||||
<img src={LoadingImage} alt="">
|
||||
</div>
|
||||
<ul>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="info">
|
||||
<h2>{params.name}</h2>
|
||||
</div>
|
||||
|
||||
<div id="info">
|
||||
<div class="loading title" />
|
||||
<div class="loading price" />
|
||||
|
||||
<div class="loading description" />
|
||||
</div>
|
||||
{:then item}
|
||||
<div id="images">
|
||||
<div>
|
||||
<img src={item.image} alt="">
|
||||
</div>
|
||||
<ul>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
<li><img src={LoadingImage} alt=""></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="info">
|
||||
<h2>{item.name}</h2>
|
||||
<p>£{item.price}</p>
|
||||
|
||||
<div class="container">
|
||||
<p>{item.detail}</p>
|
||||
</div>
|
||||
</div>
|
||||
{:catch error}
|
||||
<p>Server fucking died...</p>
|
||||
<p>{error}</p>
|
||||
{/await}
|
||||
</div>
|
||||
|
||||
<div class="spacer"></div>
|
||||
|
||||
<div class="other">
|
||||
<h2>Popular</h2>
|
||||
<MenuList items={items} />
|
||||
<div id="popular">
|
||||
{#await popularToday}
|
||||
<LoadingBar />
|
||||
{:then items}
|
||||
<MenuList {items} />
|
||||
{:catch error}
|
||||
<p>{error}</p>
|
||||
{/await}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import "%/styles/vars";
|
||||
|
||||
h2 {
|
||||
margin-bottom: $spacing-small;
|
||||
}
|
||||
.spacer {
|
||||
height: $spacing-large;
|
||||
}
|
||||
$padding: 1px;
|
||||
|
||||
.main {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
#images {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> div {
|
||||
margin-bottom: $spacing-small;
|
||||
|
||||
width: 650px;
|
||||
height: 500px;
|
||||
|
||||
.images {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
> div {
|
||||
margin-bottom: $spacing-small;
|
||||
overflow: hidden;
|
||||
|
||||
width: 650px;
|
||||
height: 500px;
|
||||
> img {
|
||||
max-width: 650px;
|
||||
max-height: 500px;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: $border-radius-normal;
|
||||
}
|
||||
}
|
||||
|
||||
//border-radius: $border-radius-large;
|
||||
//background-color: $color-light;
|
||||
> ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
> li {
|
||||
list-style: none;
|
||||
|
||||
> img {
|
||||
max-width: 650px;
|
||||
max-height: 500px;
|
||||
|
||||
margin-right: $spacing-small;
|
||||
width: 100px;
|
||||
border-radius: $border-radius-normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
#info {
|
||||
width: 100%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
|
||||
> li {
|
||||
list-style: none;
|
||||
|
||||
> img {
|
||||
margin-right: $spacing-small;
|
||||
width: 100px;
|
||||
border-radius: $border-radius-normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
> h2 {
|
||||
font-size: $font-size-h1;
|
||||
padding-bottom: $spacing-small;
|
||||
}
|
||||
> p {
|
||||
font-size: $font-size-h2;
|
||||
padding-bottom: $spacing-normal;
|
||||
}
|
||||
.container {
|
||||
padding: $spacing-normal;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,4 +163,65 @@
|
|||
margin: 0 auto;
|
||||
max-width: $sizing-default-width;
|
||||
}
|
||||
|
||||
#popular {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.loading {
|
||||
position: relative;
|
||||
|
||||
border-radius: $border-radius-large;
|
||||
|
||||
background: linear-gradient(to right, $color-background 8%, rgba($color-dark, 0.3) 38%, $color-background 54%);
|
||||
background-size: 1000px 100%;
|
||||
animation: loading 1s infinite linear;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
|
||||
position: absolute;
|
||||
top: $padding;
|
||||
right: $padding;
|
||||
bottom: $padding;
|
||||
left: $padding;
|
||||
|
||||
border-radius: calc($border-radius-large - $padding);
|
||||
background-color: rgba($color-background, 0.9);
|
||||
}
|
||||
|
||||
&.title {
|
||||
margin-bottom: $spacing-small;
|
||||
height: calc($font-size-h1 + 10px);
|
||||
width: 150px;
|
||||
}
|
||||
&.price {
|
||||
margin-bottom: $spacing-normal;
|
||||
height: calc($font-size-h2 + 10px);
|
||||
width: 60px;
|
||||
}
|
||||
&.description {
|
||||
height: 400px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 670px) {
|
||||
.announcement-banner-loading {
|
||||
margin: -$spacing-small;
|
||||
margin-bottom: 0;
|
||||
height: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading{
|
||||
0%{
|
||||
background-position: -500px 0
|
||||
}
|
||||
100%{
|
||||
background-position: 500px 0
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,8 @@
|
|||
import { wrap } from "svelte-spa-router/wrap";
|
||||
|
||||
import PageLoading from "%/pages/PageLoading.svelte";
|
||||
import Page404 from "%/pages/Page404.svelte";
|
||||
import Page500 from "%/pages/Page500.svelte";
|
||||
|
||||
const routes = {
|
||||
"/": wrap({
|
||||
|
@ -15,7 +17,7 @@ const routes = {
|
|||
conditions: [],
|
||||
userData: { showNavBar: true, fullWidth: true, },
|
||||
}),
|
||||
"/item/:name": wrap({
|
||||
"/item/:uuid": wrap({
|
||||
asyncComponent: () => import("%/pages/PageItem.svelte"),
|
||||
loadingComponent: PageLoading,
|
||||
conditions: [],
|
||||
|
@ -39,11 +41,21 @@ const routes = {
|
|||
conditions: [],
|
||||
userData: { showNavBar: true, fullWidth: false, },
|
||||
}),
|
||||
'*': wrap({
|
||||
"/ForOhFor": wrap({
|
||||
component: Page404,
|
||||
conditions: [],
|
||||
userData: { showNavBar: true, fullWidth: false, },
|
||||
})
|
||||
}),
|
||||
"/ServerError": wrap({
|
||||
component: Page500,
|
||||
conditions: [],
|
||||
userData: { showNavBar: true, fullWidth: false, },
|
||||
}),
|
||||
"*": wrap({
|
||||
component: Page404,
|
||||
conditions: [],
|
||||
userData: { showNavBar: true, fullWidth: false, },
|
||||
}),
|
||||
}
|
||||
|
||||
export default routes;
|
||||
|
|
Loading…
Reference in a new issue