Booking form

Move loader style to its own scss file to make it re-usable
This commit is contained in:
Michał 2024-05-20 12:15:32 +01:00
parent e0abea8cef
commit d2a637f8d6
8 changed files with 320 additions and 332 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -6,7 +6,7 @@
{#await announcement} {#await announcement}
<div class="announcement-banner-loading" /> <div class="loading-box" />
{:then announcement} {:then announcement}
<div class="announcement-banner"> <div class="announcement-banner">
<img src={announcement.image} alt=""> <img src={announcement.image} alt="">
@ -20,55 +20,15 @@
$padding: 1px; $padding: 1px;
.announcement-banner-loading { .loading-box {
height: 400px; height: 400px;
position: relative;
border-radius: $border-radius-large;
background: linear-gradient(
to right,
rgba($color-dark, 0) 8%,
rgba($color-dark, 0.3) 38%,
rgba($color-dark, 0) 54%
) no-repeat;
background-size: 1500px 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: darken($color-background, 10%);
background-image: url("/assets/Noise.png");
opacity: 0.9;
}
} }
@media only screen and (max-width: 670px) { @media only screen and (max-width: 670px) {
.announcement-banner-loading { .loading-box {
margin: -$spacing-small; margin: -$spacing-small;
margin-bottom: 0; margin-bottom: 0;
height: 250px; height: 250px;
} }
} }
@keyframes loading{
0%{
background-position: -750px 0
}
100%{
background-position: 750px 0
}
}
</style> </style>

View file

@ -18,31 +18,10 @@
<div class="spacer" /> <div class="spacer" />
<ImageWithText image={Dab} toRight={true}>
<div class="padding">
<h2>The hard times</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. At deserunt est quos dicta ipsa! Soluta laudantium dolore temporibus nisi aspernatur expedita vel, unde natus a nulla rerum officiis optio neque.</p>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. At deserunt est quos dicta ipsa! Soluta laudantium dolore temporibus nisi aspernatur expedita vel, unde natus a nulla rerum officiis optio neque.</p>
</div>
</ImageWithText>
<div class="spacer" />
<ImageWithText image={Hog}>
<div class="padding">
<h2>Whats next</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. At deserunt est quos dicta ipsa! Soluta laudantium dolore temporibus nisi aspernatur expedita vel, unde natus a nulla rerum officiis optio neque.</p>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. At deserunt est quos dicta ipsa! Soluta laudantium dolore temporibus nisi aspernatur expedita vel, unde natus a nulla rerum officiis optio neque.</p>
</div>
</ImageWithText>
<div class="spacer" />
<ImageWithText image={Beetle} toRight={true}> <ImageWithText image={Beetle} toRight={true}>
<div class="padding"> <div class="padding">
<h2>Our Chef</h2> <h2>Our Chef</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. At deserunt est quos dicta ipsa! Soluta laudantium dolore temporibus nisi aspernatur expedita vel, unde natus a nulla rerum officiis optio neque.</p> <p>He sucks at his job</p>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. At deserunt est quos dicta ipsa! Soluta laudantium dolore temporibus nisi aspernatur expedita vel, unde natus a nulla rerum officiis optio neque.</p>
</div> </div>
</ImageWithText> </ImageWithText>

View file

@ -1,26 +1,9 @@
<script lang="ts"> <script lang="ts">
import { link, push, querystring } from 'svelte-spa-router'; import {SealWarning, CaretDown, ArrowRight} from "phosphor-svelte";
import { SealWarning, CaretDown, ArrowRight, ArrowLeft } from "phosphor-svelte";
import { expandOnTyping } from "../lib/utils"; import { expandOnTyping } from "../lib/utils";
import Calendar from "../components/Calendar.svelte"; import Calendar from "../components/Calendar.svelte";
let progress = 1;
querystring.subscribe((params) => {
const url = new URLSearchParams(params);
const parsed = parseInt(url.get("progress"));
progress = 1;
if (url.has("progress") && !isNaN(parsed)) {
progress = parsed;
}
if ([1, 2, 3].indexOf(progress) === -1) {
progress = 1;
push("/booking?progress=1");
}
})
const specialRequestsMax = 300; const specialRequestsMax = 300;
const today = new Date(); const today = new Date();
@ -29,6 +12,7 @@
let telephone = ""; let telephone = "";
let date: Date; let date: Date;
let timeSlot = "slot1"; let timeSlot = "slot1";
let tableSlot = "table1";
let specialRequests = ""; let specialRequests = "";
let nameValid = true; let nameValid = true;
@ -41,27 +25,18 @@
function validateEmail() { emailValid = email.length > 1} function validateEmail() { emailValid = email.length > 1}
function validateTelephone() { telephoneValid = telephone.length == 11} function validateTelephone() { telephoneValid = telephone.length == 11}
function validateDate() { dateValid = date > today;} function validateDate() { dateValid = date > today;}
function validateSpecialRequests() { specialRequestsValid = specialRequests.length < 301 } function validateSpecialRequests() { specialRequestsValid = specialRequests.length <= 300 }
function onSubmit(event) {} function onSubmit(event) {}
</script> </script>
<h1>Table booking</h1> <h1>Table booking</h1>
<div id="booking-progress"> <div id="booking">
<a href="/booking?progress={progress - 1}" use:link><ArrowLeft /></a> <div id="form">
<div <h2>Date and Time</h2>
class="progress" <p>When do you wanna come see us?</p>
class:progress-1={progress === 1} <div class="spacer half" />
class:progress-2={progress === 2}
class:progress-3={progress === 3}
/>
<a href="/booking?progress={progress + 1}" use:link><ArrowRight /></a>
</div>
<div class="spacer" />
{#if progress === 1}
<div class="form-element"> <div class="form-element">
<p class="form-label">Booking Date</p> <p class="form-label">Booking Date</p>
<Calendar <Calendar
@ -105,7 +80,44 @@
</div> </div>
</div> </div>
{/if} {/if}
{:else if progress === 2}
<div class="spacer" />
<hr>
<div class="spacer" />
<h2>Seating</h2>
<p>Where would you like to be seating?</p>
<div class="spacer half" />
<div class="seating-image">
<img src="/assets/SeatingTemporary.png" alt="Birds-eye view of the available seating at the restaurant" />
</div>
<div class="spacer half" />
<div class="form-element">
<label class="form-label" for="table-slot">Seat Choice</label>
<div class="select-container">
<select
bind:value={tableSlot}
class="form-input"
id="table-slot"
name="table-slot"
>
<option value="table1">Table 1</option>
<option value="table2">Table 2</option>
<option value="table3">Table 3</option>
</select>
<div class="select-arrow">
<CaretDown />
</div>
</div>
</div>
<div class="spacer" />
<hr>
<div class="spacer" />
<h2>Special requests</h2>
<p>Wanna make sure we're accessible to your disabilities? Let us know where what todo!</p>
<div class="spacer half" />
<div class="form-element"> <div class="form-element">
<label class="form-label" for="message">Message</label> <label class="form-label" for="message">Message</label>
<textarea <textarea
@ -123,7 +135,14 @@
({specialRequests.length}/{specialRequestsMax}) ({specialRequests.length}/{specialRequestsMax})
</span> </span>
</div> </div>
{:else if progress === 3}
<div class="spacer" />
<hr>
<div class="spacer" />
<h2>Who are you</h2>
<p>Just so we can keep you updated on your reservation</p>
<div class="spacer half" />
<div class="form-element"> <div class="form-element">
<label class="form-label" for="name">Full Name</label> <label class="form-label" for="name">Full Name</label>
<input <input
@ -181,85 +200,39 @@
{/if} {/if}
</span> </span>
</div> </div>
{/if} </div>
<div class="spacer" />
<div id="booking-confirmation">
<div class="container">
<div class="header">
<h2>Booking Confirmation</h2>
</div>
<hr>
<div class="section">
<p>
I want to stay at table {tableSlot || "Table 1"}, on {date || "a pleasant day"}, {timeSlot || "during the day"}.
<br><br>
I request "{specialRequests || "a nice stay"}".
<br><br>
If I need to be contacted, my name is {name || "Unknown"},
email {email || "Missing"} or alternatively call me on {telephone || "nothing"}.
</p>
</div>
</div>
<div class="spacer half" />
<div class="container">
<div class="section">
<p>By pressing "Book Table" you agree to our terms of service</p>
<div class="spacer half" />
<button id="book-button" form="form">Book&nbsp;Table&nbsp;<ArrowRight /></button>
</div>
</div>
</div>
</div>
<style lang="scss"> <style lang="scss">
@import "../styles/vars"; @import "../styles/vars";
#booking-progress {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
> a {
padding: 0 $spacing-small;
width: 35px;
height: 35px;
display: flex;
justify-content: center;
align-items: center;
font-size: $font-size-p;
border: 0 solid transparent;
border-radius: $border-radius-circle;
background-color: $color-light;
color: $color-on-light;
&:hover {
background-color: $color-dark;
color: $color-on-dark;
}
&:focus-visible {
background-color: $color-dark;
color: $color-on-dark;
outline: 0 solid transparent;
}
}
.progress {
margin: 0 $spacing-normal;
width: 100%;
height: 5px;
position: relative;
border-radius: $border-radius-circle;
background-color: $color-light;
overflow: hidden;
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 0;
height: 100%;
background-color: $color-dark;
transition: width 0.5s cubic-bezier(.19,1,.22,1);
}
&.progress-1::after {
width: 33%;
}
&.progress-2::after {
width: 66%;
}
&.progress-3::after {
width: 100%;
}
}
}
#name, #email { #name, #email {
width: 300px; width: 300px;
max-width: calc(100vw - calc(2 * $spacing-normal)); max-width: calc(100vw - calc(2 * $spacing-normal));
@ -306,4 +279,77 @@
} }
} }
} }
.container {
overflow: hidden;
}
.seating-image {
max-width: 550px;
border-radius: $border-radius-large;
overflow: hidden;
> img {
width: 100%;
height: auto;
display: block;
}
}
#book-button {
padding: 0 $spacing-normal;
width: 100%;
height: 35px;
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
font-size: $font-size-p;
text-decoration: none;
border-radius: $border-radius-large;
border: 0 solid transparent;
background-color: $color-primary;
color: $color-on-primary;
&:hover {
background-color: $color-dark;
color: $color-on-dark;
}
}
#booking {
display: flex;
flex-direction: row;
justify-content: normal;
align-items: flex-start;
}
#form {
width: 100%;
position: relative;
}
#booking-confirmation {
min-width: calc(400px - $spacing-normal);
width: 100%;
max-width: calc(400px - $spacing-normal);
position: sticky;
top: calc($sizing-navigation-height + $spacing-normal);
}
@media only screen and (max-width: 900px) {
#booking {
flex-direction: column;
}
#booking-confirmation {
max-width: unset;
position: unset;
}
}
</style> </style>

View file

@ -434,7 +434,8 @@
} }
.table { .table {
//border-radius: $border-radius-normal; margin: 0 $spacing-normal;
border-radius: $border-radius-normal;
border: 1px solid rgba($color-dark, 0.2); border: 1px solid rgba($color-dark, 0.2);
background-color: $color-light; background-color: $color-light;

View file

@ -54,23 +54,23 @@
{#await item} {#await item}
<div id="images"> <div id="images">
<div class="img-main"> <div class="img-main">
<div class="loading image" /> <div class="loading-box image" />
</div> </div>
<ul class="img-alts"> <ul class="img-alts">
<li><div class="loading image-small" /></li> <li><div class="loading-box image-small" /></li>
<li><div class="loading image-small" /></li> <li><div class="loading-box image-small" /></li>
<li><div class="loading image-small" /></li> <li><div class="loading-box image-small" /></li>
<li><div class="loading image-small" /></li> <li><div class="loading-box image-small" /></li>
<li><div class="loading image-small" /></li> <li><div class="loading-box image-small" /></li>
</ul> </ul>
</div> </div>
<div class="spacer half" /> <div class="spacer half" />
<div id="info"> <div id="info">
<div class="loading title" /> <div class="loading-box title" />
<div class="loading price" /> <div class="loading-box price" />
<div class="loading description" /> <div class="loading-box description" />
</div> </div>
{:then item} {:then item}
<div id="images"> <div id="images">
@ -174,8 +174,6 @@
<style lang="scss"> <style lang="scss">
@import "../styles/vars"; @import "../styles/vars";
$padding: 1px;
.notice { .notice {
margin-right: auto; margin-right: auto;
margin-bottom: $spacing-large; margin-bottom: $spacing-large;
@ -257,7 +255,7 @@
background-color: rgba($color-dark, 0.1); background-color: rgba($color-dark, 0.1);
} }
> .loading.image { > .loading-box.image {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
@ -278,7 +276,7 @@
> li { > li {
list-style: none; list-style: none;
> .loading.image-small { > .loading-box.image-small {
margin-right: $spacing-small; margin-right: $spacing-small;
width: 100px; width: 100px;
height: 100px; height: 100px;
@ -504,38 +502,7 @@
} }
} }
.loading { .loading-box {
position: relative;
border-radius: $border-radius-large;
background: linear-gradient(
to right,
rgba($color-dark, 0) 8%,
rgba($color-dark, 0.3) 38%,
rgba($color-dark, 0) 54%
) no-repeat;
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: darken($color-background, 10%);
background-image: url("/assets/Noise.png");
opacity: 0.9;
}
&.title { &.title {
margin-bottom: $spacing-small; margin-bottom: $spacing-small;
height: calc($font-size-h1 + 10px); height: calc($font-size-h1 + 10px);
@ -551,13 +518,4 @@
width: 100%; width: 100%;
} }
} }
@keyframes loading{
0%{
background-position: -600px 0
}
100%{
background-position: 600px 0
}
}
</style> </style>

View file

@ -0,0 +1,43 @@
$loading-box-padding: 1px;
.loading-box {
position: relative;
border-radius: $border-radius-large;
background: linear-gradient(
to right,
rgba($color-dark, 0) 8%,
rgba($color-dark, 0.3) 38%,
rgba($color-dark, 0) 54%
) no-repeat;
background-size: 1500px 100%;
animation: loading-box-glow 1s infinite linear;
overflow: hidden;
&::after {
content: '';
position: absolute;
top: $loading-box-padding;
right: $loading-box-padding;
bottom: $loading-box-padding;
left: $loading-box-padding;
border-radius: calc($border-radius-large - $loading-box-padding);
background-color: darken($color-background, 10%);
background-image: url("/assets/Noise.png");
opacity: 0.9;
}
}
@keyframes loading-box-glow {
0%{
background-position: -750px 0
}
100%{
background-position: 750px 0
}
}

View file

@ -2,6 +2,7 @@
@import "reset"; @import "reset";
@import "loading_bar"; @import "loading_bar";
@import "loading_box";
@import "navigation_bar"; @import "navigation_bar";
@import "footer"; @import "footer";
@import "announcement_banner"; @import "announcement_banner";