From 2afab6a33d1df1405d407c8eb988561161594b4b Mon Sep 17 00:00:00 2001 From: Hrishikesh Vaipurkar Date: Thu, 25 Jul 2024 16:04:35 +0200 Subject: [PATCH] feat: SW-65 Working on booking widget wrapper component --- actions/updateBookingWidget.ts | 56 +++++++++++++++++ .../BookingWidget/bookingWidget.module.css | 20 ++++++ components/BookingWidget/index.tsx | 62 +++++++++++++++++++ components/BookingWidget/schema.ts | 25 ++++++++ components/Current/Header/index.tsx | 7 +++ types/components/bookingWidget/index.ts | 5 ++ 6 files changed, 175 insertions(+) create mode 100644 actions/updateBookingWidget.ts create mode 100644 components/BookingWidget/bookingWidget.module.css create mode 100644 components/BookingWidget/index.tsx create mode 100644 components/BookingWidget/schema.ts create mode 100644 types/components/bookingWidget/index.ts diff --git a/actions/updateBookingWidget.ts b/actions/updateBookingWidget.ts new file mode 100644 index 000000000..f69df22d6 --- /dev/null +++ b/actions/updateBookingWidget.ts @@ -0,0 +1,56 @@ +"use server" +import { ZodError } from "zod" + +import { bookingWidgetSchema } from "@/components/BookingWidget/schema" + +import { type State, Status } from "@/types/components/myPages/myProfile/edit" + +export async function updateBookingWidget(_prevState: State, values: FormData) { + try { + const data: Record = Object.fromEntries(values.entries()) + + /** + * ToDo: Update the data parsing + */ + console.info(`Raw Data BW`) + console.log(data) + const parsedData = bookingWidgetSchema.safeParse(data) + if (parsedData.success) { + console.info(`Success`) + console.log(parsedData.data) + return { + message: "All good!", + status: Status.success, + } + } else { + console.error("Error parsing BW data") + console.error(parsedData.error) + return { + message: "Invalid data, parse failed!", + status: Status.error, + } + } + } catch (error) { + if (error instanceof ZodError) { + console.error(`ZodError handling profile edit`) + console.error(error) + + return { + errors: error.issues.map((issue) => ({ + message: `Server validation: ${issue.message}`, + path: issue.path.join("."), + })), + message: "Invalid form data", + status: Status.error, + } + } + + console.error(`EditProfile Server Action Error`) + console.error(error) + + return { + message: "Something went wrong. Please try again.", + status: Status.error, + } + } +} diff --git a/components/BookingWidget/bookingWidget.module.css b/components/BookingWidget/bookingWidget.module.css new file mode 100644 index 000000000..91c266932 --- /dev/null +++ b/components/BookingWidget/bookingWidget.module.css @@ -0,0 +1,20 @@ +.container { + display: none; + gap: var(--Spacing-x3); +} + +.form { + display: grid; + gap: var(--Spacing-x5); +} + +@media screen and (min-width: 1367px) { + .container { + display: grid; + padding: 0 var(--Spacing-x5); + } + .form { + grid-template-columns: auto auto auto auto auto auto; + align-items: center; + } +} diff --git a/components/BookingWidget/index.tsx b/components/BookingWidget/index.tsx new file mode 100644 index 000000000..6f1654f69 --- /dev/null +++ b/components/BookingWidget/index.tsx @@ -0,0 +1,62 @@ +"use client" +import { zodResolver } from "@hookform/resolvers/zod" +import { useFormState as useReactFormState } from "react-dom" +import { FormProvider, useForm } from "react-hook-form" + +import { updateBookingWidget } from "@/actions/updateBookingWidget" + +import { SearchWidget } from "../SearchWidget" +import Button from "../TempDesignSystem/Button" +import { type BookingWidgetSchema, bookingWidgetSchema } from "./schema" + +import styles from "./bookingWidget.module.css" + +import { State } from "@/types/components/myPages/myProfile/edit" + +export function BookingWidget() { + const [state, formAction] = useReactFormState( + updateBookingWidget, + null + ) + const methods = useForm({ + defaultValues: { + search: { + stayType: "", + stayValue: "", + }, + nights: { + fromDate: new Date(), + toDate: new Date(new Date().setDate(+1)), + }, + bookingCode: { + value: "", + }, + redemption: false, + voucher: false, + rooms: [ + { + Adults: 1, + Child: 0, + }, + ], + }, + mode: "all", + resolver: zodResolver(bookingWidgetSchema), + reValidateMode: "onChange", + }) + + return ( +
+
+ +
Search
+
Nights
+
Rooms
+
Bonus code
+
Bonus cheque or reward nights
+ +
+
+
+ ) +} diff --git a/components/BookingWidget/schema.ts b/components/BookingWidget/schema.ts new file mode 100644 index 000000000..5ce7f2d2a --- /dev/null +++ b/components/BookingWidget/schema.ts @@ -0,0 +1,25 @@ +import { z } from "zod" + +export const bookingWidgetSchema = z.object({ + search: z.object({ + stayType: z.string(), + stayValue: z.string(), + }), + nights: z.object({ + fromDate: z.date().default(new Date()), + toDate: z.date().default(new Date(new Date().setDate(+1))), + }), + bookingCode: z.object({ + value: z.string(), + }), + redemption: z.boolean().default(false), + voucher: z.boolean().default(false), + rooms: z.array( + z.object({ + Adults: z.number().default(1), + Child: z.number().default(0), + }) + ), +}) + +export type BookingWidgetSchema = z.infer diff --git a/components/Current/Header/index.tsx b/components/Current/Header/index.tsx index dd74dd4cb..0681d8354 100644 --- a/components/Current/Header/index.tsx +++ b/components/Current/Header/index.tsx @@ -4,6 +4,7 @@ import { serverClient } from "@/lib/trpc/server" import { auth } from "@/auth" +import { BookingWidget } from "../../BookingWidget" import { MainMenu } from "./MainMenu" import OfflineBanner from "./OfflineBanner" import TopMenu from "./TopMenu" @@ -25,6 +26,11 @@ export default async function Header({ const user = await serverClient().user.name() + /** + * ToDo: Create logic to get this info from ContentStack based on page + * */ + const hideBookingWidget = false + if (!data) { return null } @@ -58,6 +64,7 @@ export default async function Header({ user={user} lang={lang} /> + {hideBookingWidget ? null : } ) } diff --git a/types/components/bookingWidget/index.ts b/types/components/bookingWidget/index.ts new file mode 100644 index 000000000..457a9a1af --- /dev/null +++ b/types/components/bookingWidget/index.ts @@ -0,0 +1,5 @@ +import { BookingWidgetSchema } from "@/components/BookingWidget/schema" + +export type bwFormProps = { + data: BookingWidgetSchema +}