Booking type

Clean up Checkout????
This commit is contained in:
Michał Gdula 2024-05-21 15:24:01 +01:00
parent 67d3433fa4
commit 4e4df9610f
3 changed files with 86 additions and 77 deletions

View file

@ -6,6 +6,21 @@ export enum Labels {
gluten = "GLUTEN", gluten = "GLUTEN",
} }
export enum TimeSlots {
slot0 = "8am to 10am",
slot1 = "10am to 12am",
slot2 = "12am to 2pm",
slot3 = "2pm to 4pm",
slot4 = "4pm to 6pm",
slot5 = "6pm to 8pm",
slot6 = "8pm to 10pm",
}
export enum Tables {
table1 = "Table 1",
table2 = "Table 2",
table3 = "Table 3",
}
export type Item = { export type Item = {
uuid: string; uuid: string;
availability?: boolean; availability?: boolean;
@ -23,6 +38,20 @@ export type CartItem = {
export type CartRecord = Record<string, CartItem>; export type CartRecord = Record<string, CartItem>;
export type Booking = {
date: {
date: Date;
slot: TimeSlots;
};
table: Tables;
message: string;
personal: {
name: string;
email: string;
phone?: number;
};
};
export type Checkout = { export type Checkout = {
personal: { personal: {
name: string; name: string;

View file

@ -1,39 +1,30 @@
<script lang="ts"> <script lang="ts">
import {SealWarning, CaretDown, ArrowRight} from "phosphor-svelte"; import { SealWarning, CaretDown, ArrowRight } from "phosphor-svelte";
import { type Booking, TimeSlots, Tables } from "../lib/types";
import { expandOnTyping } from "../lib/utils"; import { expandOnTyping } from "../lib/utils";
import Calendar from "../components/Calendar.svelte"; import Calendar from "../components/Calendar.svelte";
const timeSlots = {
slot0: "8am to 10am",
slot1: "10am to 12am",
slot2: "12am to 2pm",
slot3: "2pm to 4pm",
slot4: "4pm to 6pm",
slot5: "6pm to 8pm",
slot6: "8pm to 10pm",
}
const tables = {
table1: "Table 1",
table2: "Table 2",
table3: "Table 3",
}
const specialRequestsMax = 300; const specialRequestsMax = 300;
const today = new Date(); const today = new Date();
const BookingData: Booking = {
date: {
date: new Date(),
slot: TimeSlots.slot0,
},
table: Tables.table1,
message: "",
personal: {
name: "",
email: "",
},
};
let name = ""; $: nameValid = BookingData.personal.name.length > 1;
let email = ""; $: emailValid = BookingData.personal.email.length > 1;
let telephone = ""; $: telephoneValid = `${BookingData.personal.phone}`.length == 11;
let date: Date; $: dateValid = BookingData.date.date > today;
let timeSlot = "slot1"; $: specialRequestsValid = BookingData.message.length <= 300 ;
let tableSlot = "table1";
let specialRequests = "";
let nameValid = true;
let emailValid = true;
let telephoneValid = true;
let dateValid = true;
let specialRequestsValid = true;
function formatDate(date: Date) { function formatDate(date: Date) {
let formattedDate = new Intl.DateTimeFormat( let formattedDate = new Intl.DateTimeFormat(
@ -45,7 +36,6 @@
} }
).format(date); ).format(date);
// Add the ordinal suffix
let day = date.getDate(); let day = date.getDate();
let suffix = 'th'; let suffix = 'th';
if (day % 10 === 1 && day !== 11) { if (day % 10 === 1 && day !== 11) {
@ -58,12 +48,6 @@
return formattedDate.replace(`${day}`, day + suffix); return formattedDate.replace(`${day}`, day + suffix);
} }
function validateName() { nameValid = name.length > 1}
function validateEmail() { emailValid = email.length > 1}
function validateTelephone() { telephoneValid = telephone.length == 11}
function validateDate() { dateValid = date > today;}
function validateSpecialRequests() { specialRequestsValid = specialRequests.length <= 300 }
function onSubmit(event) {} function onSubmit(event) {}
</script> </script>
@ -77,8 +61,7 @@
<div class="form-element"> <div class="form-element">
<p class="form-label">Booking Date</p> <p class="form-label">Booking Date</p>
<Calendar <Calendar
bind:selectedDate={date} bind:selectedDate={BookingData.date.date}
on:selected={validateDate}
notBefore={today} notBefore={today}
/> />
<span class="form-notice error"> <span class="form-notice error">
@ -91,25 +74,25 @@
<div class="spacer half" /> <div class="spacer half" />
<!-- ToDo: Don't give a fake error for the weekend slots, just for testing || !dateValid --> <!-- ToDo: Don't give a fake error for the weekend slots, just for testing || !dateValid -->
{#if date && (date.getDay() === 6 || date.getDay() === 0)} {#if BookingData.date.date && (BookingData.date.date.getDay() === 6 || BookingData.date.date.getDay() === 0)}
<p class="form-message error"><SealWarning weight="fill" />&nbsp;Time slots not available for this date</p> <p class="form-message error"><SealWarning weight="fill" />&nbsp;Time slots not available for this date</p>
{:else} {:else}
<div class="form-element"> <div class="form-element">
<label class="form-label" for="time-slot">Time Slot</label> <label class="form-label" for="time-slot">Time Slot</label>
<div class="select-container"> <div class="select-container">
<select <select
bind:value={timeSlot} bind:value={BookingData.date.slot}
class="form-input" class="form-input"
id="time-slot" id="time-slot"
name="time-slot" name="time-slot"
> >
<option value="slot0">8am to 10am</option> <option value={TimeSlots.slot0}>8am to 10am</option>
<option value="slot1">10am to 12am</option> <option value={TimeSlots.slot1}>10am to 12am</option>
<option value="slot2" disabled>12am to 2pm</option> <option value={TimeSlots.slot2}>12am to 2pm</option>
<option value="slot3">2pm to 4pm</option> <option value={TimeSlots.slot3}>2pm to 4pm</option>
<option value="slot4">4pm to 6pm</option> <option value={TimeSlots.slot4}>4pm to 6pm</option>
<option value="slot5">6pm to 8pm</option> <option value={TimeSlots.slot5}>6pm to 8pm</option>
<option value="slot6">8pm to 10pm</option> <option value={TimeSlots.slot6}>8pm to 10pm</option>
</select> </select>
<div class="select-arrow"> <div class="select-arrow">
<CaretDown /> <CaretDown />
@ -133,14 +116,14 @@
<label class="form-label" for="table-slot">Seat Choice</label> <label class="form-label" for="table-slot">Seat Choice</label>
<div class="select-container"> <div class="select-container">
<select <select
bind:value={tableSlot} bind:value={BookingData.table}
class="form-input" class="form-input"
id="table-slot" id="table-slot"
name="table-slot" name="table-slot"
> >
<option value="table1">Table 1</option> <option value={Tables.table1}>Table 1</option>
<option value="table2">Table 2</option> <option value={Tables.table2}>Table 2</option>
<option value="table3">Table 3</option> <option value={Tables.table3}>Table 3</option>
</select> </select>
<div class="select-arrow"> <div class="select-arrow">
<CaretDown /> <CaretDown />
@ -158,9 +141,7 @@
<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
bind:value={specialRequests} bind:value={BookingData.message}
on:input={validateSpecialRequests}
on:blur={validateSpecialRequests}
use:expandOnTyping use:expandOnTyping
rows="1" rows="1"
cols="50" cols="50"
@ -169,7 +150,7 @@
class="form-input" class="form-input"
/> />
<span class="form-notice" class:error={!specialRequestsValid}> <span class="form-notice" class:error={!specialRequestsValid}>
({specialRequests.length}/{specialRequestsMax}) ({BookingData.message.length}/{specialRequestsMax})
</span> </span>
</div> </div>
@ -183,9 +164,7 @@
<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
bind:value={name} bind:value={BookingData.personal.name}
on:blur={validateName}
on:input={validateName}
type="text" type="text"
id="name" id="name"
name="name" name="name"
@ -203,9 +182,7 @@
<div class="form-element"> <div class="form-element">
<label class="form-label" for="email">Email</label> <label class="form-label" for="email">Email</label>
<input <input
bind:value={email} bind:value={BookingData.personal.email}
on:blur={validateEmail}
on:input={validateEmail}
type="text" type="text"
id="email" id="email"
name="email" name="email"
@ -223,9 +200,7 @@
<div class="form-element"> <div class="form-element">
<label class="form-label" for="telephone">Telephone</label> <label class="form-label" for="telephone">Telephone</label>
<input <input
bind:value={telephone} bind:value={BookingData.personal.phone}
on:blur={validateTelephone}
on:input={validateTelephone}
type="text" type="text"
id="telephone" id="telephone"
name="telephone" name="telephone"
@ -248,21 +223,21 @@
<div class="section"> <div class="section">
<p> <p>
On On
<span class="h">{date ? `the ${formatDate(date)}` : "an undecided date"}</span> <span class="h">{BookingData.date.date ? `the ${formatDate(BookingData.date.date)}` : "an undecided date"}</span>
at at
<span class="h">{timeSlot ? timeSlots[timeSlot] : "an undecided time"}</span>, <span class="h">{BookingData.date.slot ? BookingData.date.slot : "an undecided time"}</span>,
I want to be seated at I want to be seated at
<span class="h">{tableSlot ? tables[tableSlot] : "a table"}</span>. <span class="h">{BookingData.table ? BookingData.table : "a table"}</span>.
<br><br> <br><br>
I request I request
<span class="h">{specialRequests ? specialRequests : "nothing in particular"}</span>. <span class="h">{BookingData.message ? BookingData.message : "nothing in particular"}</span>.
<br><br> <br><br>
My name is My name is
<span class="h">{name ? name : "Unknown"}</span>, <span class="h">{BookingData.personal.name ? BookingData.personal.name : "Unknown"}</span>,
in the event I need to be contacted by email, you can do that at in the event I need to be contacted by email, you can do that at
<span class="h">{email ? email : "an empty email"}</span>, <span class="h">{BookingData.personal.email ? BookingData.personal.email : "an empty email"}</span>,
or alternatively call me on or alternatively call me on
<span class="h">{telephone ? telephone : "an empty phone number"}</span>. <span class="h">{BookingData.personal.phone ? BookingData.personal.phone : "an empty phone number"}</span>.
</p> </p>
</div> </div>
</div> </div>

View file

@ -13,8 +13,8 @@
name: "", name: "",
email: "", email: "",
}, },
message: "",
delivery: true, delivery: true,
message: "",
address: { address: {
line1: "", line1: "",
line2: "", line2: "",
@ -33,19 +33,24 @@
let unavailableItems: boolean; let unavailableItems: boolean;
Cart.subscribe(() => { Cart.subscribe(() => {
items = Cart.getEntries(); items = Cart.getEntries();
totalPrice = 1.50 + Cart.getTotalPrice(); if (CheckoutData.delivery) {
if (CheckoutData.delivery) totalPrice += 3.00 totalPrice = 3.00 + 1.50 + Cart.getTotalPrice();
unavailableItems = Cart.getEntries().some(([_, item]) => item.data.availability === false); } else {
totalPrice = 1.50 + Cart.getTotalPrice();
}
unavailableItems = Cart.getEntries().some(([_, item]) => {
item.data.availability === false
});
}); });
let leafletMap: Map; let leafletMap: Map;
onMount(() => { onMount(() => {
leafletMap = L.map('map').setView([50.82304922105467, -0.432780150496344], 13); leafletMap = L.map("map").setView([50.82304922105467, -0.432780150496344], 13);
L.tileLayer( L.tileLayer(
'https://tile.openstreetmap.org/{z}/{x}/{y}.png', "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
{ {
maxZoom: 20, maxZoom: 20,
attribution: "&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a>", attribution: "&copy; <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap</a>",
}, },
).addTo(leafletMap); ).addTo(leafletMap);
L.marker([50.82304922105467, -0.432780150496344]).addTo(leafletMap); L.marker([50.82304922105467, -0.432780150496344]).addTo(leafletMap);