feat(SW-240): refactor booking widget

This commit is contained in:
Fredrik Thorsson
2024-08-14 18:46:07 +02:00
parent 5a0d1c6d7b
commit 00a5465485
8 changed files with 209 additions and 181 deletions

View File

@@ -1,63 +1,8 @@
.container {
border-top: 1px solid var(--Base-Border-Subtle);
box-shadow: 0px 16px 24px 0px #00000014;
}
.form {
display: flex;
justify-content: space-between;
max-width: 1432px;
padding: var(--Spacing-x2) var(--Spacing-x5);
}
.input {
display: flex;
gap: var(--Spacing-x2);
width: 100%;
max-width: 1250px;
}
.button {
width: 118px;
justify-content: center;
}
.bodyFontSize {
font-size: var(--typography-Caption-Bold-Desktop-fontSize);
}
.border {
border-right: 1px solid var(--Base-Surface-Subtle-Normal);
}
.where {
width: 100%;
max-width: 280px;
height: 100%;
max-height: 46px;
}
.when,
.rooms {
width: 100%;
max-width: 240px;
}
.vouchers {
width: 100%;
max-width: 200px;
}
.options {
display: flex;
flex-direction: column;
width: 100%;
max-width: 158px;
}
/**
* Update the styles after mobile UX is ready
*/
@media screen and (max-width: 1367px) {
.container {
display: none;

View File

@@ -1,131 +1,11 @@
"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { FormProvider, useForm } from "react-hook-form"
import { useIntl } from "react-intl"
import { dt } from "@/lib/dt"
import Button from "../TempDesignSystem/Button"
import Body from "../TempDesignSystem/Text/Body"
import { bookingWidgetSchema } from "./schema"
import Form from "../Forms/BookingWidget"
import styles from "./bookingWidget.module.css"
import { type BookingWidgetSchema } from "@/types/components/bookingWidget"
export function BookingWidget() {
const intl = useIntl()
const methods = useForm<BookingWidgetSchema>({
defaultValues: {
search: {
stayType: "",
stayValue: "",
},
nights: {
// UTC is required to handle requests from far away timezones https://scandichotels.atlassian.net/browse/SWAP-6375 & PET-507
// This is specifically to handle timezones falling in different dates.
fromDate: dt().utc().format("DD/MM/YYYY"),
toDate: dt().utc().add(1, "day").format("DD/MM/YYYY"),
},
bookingCode: "",
redemption: false,
voucher: false,
rooms: [
{
adults: 1,
childs: [],
},
],
},
mode: "all",
resolver: zodResolver(bookingWidgetSchema),
reValidateMode: "onChange",
})
function onSubmit(data: BookingWidgetSchema) {
console.log(data)
// Parse data and route accordignly to Select hotel or select room-rate page
console.log("to be routing")
}
return (
<div id="booking-widget" className={styles.container}>
<form onSubmit={methods.handleSubmit(onSubmit)} className={styles.form}>
<FormProvider {...methods}>
<div className={styles.input}>
<div className={`${styles.where} ${styles.border}`}>
<Body
color="red"
textTransform="bold"
className={styles.bodyFontSize}
>
{intl.formatMessage({ id: "Where to" })}
</Body>
</div>
<div className={`${styles.when} ${styles.border}`}>
<Body
color="red"
textTransform="bold"
className={styles.bodyFontSize}
>
{intl.formatMessage({ id: "When" })}
</Body>
</div>
<div className={`${styles.rooms} ${styles.border}`}>
<Body
color="red"
textTransform="bold"
className={styles.bodyFontSize}
>
{intl.formatMessage({ id: "Rooms & Guests" })}
</Body>
</div>
<div className={`${styles.vouchers} ${styles.border}`}>
<Body
color="textMediumContrast"
textTransform="bold"
className={styles.bodyFontSize}
>
{intl.formatMessage({ id: "Booking codes and vouchers" })}
</Body>
</div>
<div className={styles.options}>
<div>
<Body
color="textMediumContrast"
className={styles.bodyFontSize}
>
{intl.formatMessage({ id: "Use bonus cheque" })}
</Body>
</div>
<div>
<Body
color="textMediumContrast"
className={styles.bodyFontSize}
>
{intl.formatMessage({ id: "Book reward night" })}
</Body>
</div>
</div>
</div>
<Button
type="submit"
size="small"
theme="base"
intent="primary"
className={styles.button}
>
<Body
color="white"
textTransform="bold"
className={styles.bodyFontSize}
>
{intl.formatMessage({ id: "Find hotels" })}
</Body>
</Button>
</FormProvider>
</form>
</div>
<section className={styles.container}>
<Form />
</section>
)
}

View File

@@ -0,0 +1,45 @@
.input {
display: flex;
gap: var(--Spacing-x2);
width: 100%;
max-width: 1250px;
}
.button {
width: 118px;
justify-content: center;
}
.bodyFontSize {
font-size: var(--typography-Caption-Bold-Desktop-fontSize);
}
.border {
border-right: 1px solid var(--Base-Surface-Subtle-Normal);
}
.where {
display: flex;
gap: var(--Spacing-x-quarter);
flex-direction: column;
width: 100%;
max-width: 280px;
}
.when,
.rooms {
width: 100%;
max-width: 240px;
}
.vouchers {
width: 100%;
max-width: 200px;
}
.options {
display: flex;
flex-direction: column;
width: 100%;
max-width: 158px;
}

View File

@@ -0,0 +1,90 @@
"use client"
import { useIntl } from "react-intl"
import Button from "@/components/TempDesignSystem/Button"
import Body from "@/components/TempDesignSystem/Text/Body"
import styles from "./formContent.module.css"
export default function FormContent() {
const intl = useIntl()
const where = intl.formatMessage({ id: "Where to" })
const when = intl.formatMessage({ id: "When" })
const rooms = intl.formatMessage({ id: "Rooms & Guests" })
const vouchers = intl.formatMessage({ id: "Booking codes and vouchers" })
const bonus = intl.formatMessage({ id: "Use bonus cheque" })
const reward = intl.formatMessage({ id: "Book reward night" })
const search = intl.formatMessage({ id: "Find hotels" })
return (
<>
<div className={styles.input}>
<div className={`${styles.where} ${styles.border}`}>
<Body
color="red"
textTransform="bold"
className={styles.bodyFontSize}
>
{where}
</Body>
</div>
<div className={`${styles.when} ${styles.border}`}>
<Body
color="red"
textTransform="bold"
className={styles.bodyFontSize}
>
{when}
</Body>
</div>
<div className={`${styles.rooms} ${styles.border}`}>
<Body
color="red"
textTransform="bold"
className={styles.bodyFontSize}
>
{rooms}
</Body>
</div>
<div className={`${styles.vouchers} ${styles.border}`}>
<Body
color="textMediumContrast"
textTransform="bold"
className={styles.bodyFontSize}
>
{vouchers}
</Body>
</div>
<div className={styles.options}>
<div>
<Body color="textMediumContrast" className={styles.bodyFontSize}>
{bonus}
</Body>
</div>
<div>
<Body color="textMediumContrast" className={styles.bodyFontSize}>
{reward}
</Body>
</div>
</div>
</div>
<Button
type="submit"
size="small"
theme="base"
intent="primary"
className={styles.button}
>
<Body
color="white"
textTransform="bold"
className={styles.bodyFontSize}
>
{search}
</Body>
</Button>
</>
)
}

View File

@@ -0,0 +1,7 @@
.form {
display: flex;
justify-content: space-between;
width: 100%;
max-width: 1432px;
padding: var(--Spacing-x2) var(--Spacing-x5);
}

View File

@@ -0,0 +1,61 @@
"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { FormProvider, useForm } from "react-hook-form"
import { dt } from "@/lib/dt"
import FormContent from "./FormContent"
import { bookingWidgetSchema } from "./schema"
import styles from "./form.module.css"
import { BookingWidgetSchema } from "@/types/components/bookingWidget"
const formId = "booking-widget"
export default function Form() {
const methods = useForm<BookingWidgetSchema>({
defaultValues: {
search: {
stayType: "",
stayValue: "",
},
nights: {
// UTC is required to handle requests from far away timezones https://scandichotels.atlassian.net/browse/SWAP-6375 & PET-507
// This is specifically to handle timezones falling in different dates.
fromDate: dt().utc().format("DD/MM/YYYY"),
toDate: dt().utc().add(1, "day").format("DD/MM/YYYY"),
},
bookingCode: "",
redemption: false,
voucher: false,
rooms: [
{
adults: 1,
childs: [],
},
],
},
mode: "all",
resolver: zodResolver(bookingWidgetSchema),
reValidateMode: "onChange",
})
function onSubmit(data: BookingWidgetSchema) {
console.log(data)
// Parse data and route accordignly to Select hotel or select room-rate page
console.log("to be routing")
}
return (
<form
onSubmit={methods.handleSubmit(onSubmit)}
className={styles.form}
id={formId}
>
<FormProvider {...methods}>
<FormContent />
</FormProvider>
</form>
)
}

View File

@@ -1,5 +1,5 @@
import { z } from "zod"
import { bookingWidgetSchema } from "@/components/BookingWidget/schema"
import { bookingWidgetSchema } from "@/components/Forms/BookingWidget/schema"
export type BookingWidgetSchema = z.output<typeof bookingWidgetSchema>