refactor: url management in hotel reservation flow

This commit is contained in:
Christel Westerberg
2025-01-13 14:26:38 +01:00
parent 23ff0970e9
commit b2935114e3
48 changed files with 407 additions and 418 deletions

View File

@@ -1,7 +1,8 @@
.page {
background-color: var(--Base-Background-Primary-Normal);
min-height: 50dvh;
max-width: var(--max-width);
max-width: var(--max-width-page);
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;

View File

@@ -20,8 +20,13 @@ export default async function SelectHotelMapPage({
setLang(params.lang)
const searchDetails = await getHotelSearchDetails({ searchParams })
if (!searchDetails) return notFound()
const { city, adultsInRoom, childrenInRoom, childrenInRoomArray } =
searchDetails
const {
city,
adultsInRoom,
childrenInRoom,
childrenInRoomArray,
selectHotelParams,
} = searchDetails
if (!city) return notFound()
@@ -34,7 +39,7 @@ export default async function SelectHotelMapPage({
>
<SelectHotelMapContainer
city={city}
searchParams={searchParams}
selectHotelParams={selectHotelParams}
adultsInRoom={adultsInRoom}
childrenInRoom={childrenInRoom}
child={childrenInRoomArray}

View File

@@ -3,7 +3,6 @@ import { Suspense } from "react"
import SelectHotel from "@/components/HotelReservation/SelectHotel"
import { SelectHotelSkeleton } from "@/components/HotelReservation/SelectHotel/SelectHotelSkeleton"
import { getHotelReservationQueryParams } from "@/components/HotelReservation/SelectRate/RoomSelection/utils"
import { setLang } from "@/i18n/serverContext"
import { getHotelSearchDetails } from "../utils"
@@ -20,7 +19,7 @@ export default async function SelectHotelPage({
if (!searchDetails) return notFound()
const {
city,
urlSearchParams,
selectHotelParams,
adultsInRoom,
childrenInRoom,
childrenInRoomArray,
@@ -29,8 +28,7 @@ export default async function SelectHotelPage({
if (!city) return notFound()
const reservationParams = {
selectHotelParams: urlSearchParams,
searchParams,
selectHotelParams,
adultsInRoom,
childrenInRoom,
childrenInRoomArray,

View File

@@ -29,7 +29,8 @@ export default async function SelectRatePage({
setLang(params.lang)
const searchDetails = await getHotelSearchDetails({ searchParams })
if (!searchDetails) return notFound()
const { hotel, adultsInRoom, childrenInRoomArray } = searchDetails
const { hotel, adultsInRoom, childrenInRoomArray, selectHotelParams } =
searchDetails
if (!hotel) return notFound()
@@ -39,12 +40,12 @@ export default async function SelectRatePage({
})
const { fromDate, toDate } = getValidDates(
searchParams.fromDate,
searchParams.toDate
selectHotelParams.fromDate,
selectHotelParams.toDate
)
const arrivalDate = new Date(searchParams.fromDate)
const departureDate = new Date(searchParams.toDate)
const arrivalDate = fromDate.toDate()
const departureDate = toDate.toDate()
const pageTrackingData: TrackingSDKPageData = {
pageId: "select-rate",
@@ -57,7 +58,7 @@ export default async function SelectRatePage({
}
const hotelsTrackingData: TrackingSDKHotelInfo = {
searchTerm: searchParams.city ?? hotel?.name,
searchTerm: selectHotelParams.city ?? hotel?.name,
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
departureDate: format(departureDate, "yyyy-MM-dd"),
noOfAdults: adultsInRoom,

View File

@@ -21,21 +21,19 @@ import SectionAccordion from "@/components/HotelReservation/EnterDetails/Section
import SelectedRoom from "@/components/HotelReservation/EnterDetails/SelectedRoom"
import DesktopSummary from "@/components/HotelReservation/EnterDetails/Summary/Desktop"
import MobileSummary from "@/components/HotelReservation/EnterDetails/Summary/Mobile"
import {
generateChildrenString,
getQueryParamsForEnterDetails,
} from "@/components/HotelReservation/SelectRate/RoomSelection/utils"
import { generateChildrenString } from "@/components/HotelReservation/utils"
import TrackingSDK from "@/components/TrackingSDK"
import { getIntl } from "@/i18n"
import { setLang } from "@/i18n/serverContext"
import EnterDetailsProvider from "@/providers/EnterDetailsProvider"
import { convertSearchParamsToObj } from "@/utils/url"
import EnterDetailsTracking from "./enterDetailsTracking"
import styles from "./page.module.css"
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
import type { SelectRateSearchParams } from "@/types/components/hotelReservation/selectRate/selectRate"
import { type SelectRateSearchParams } from "@/types/components/hotelReservation/selectRate/selectRate"
import {
TrackingChannelEnum,
type TrackingSDKHotelInfo,
@@ -61,10 +59,10 @@ export default async function StepPage({
const selectRoomParams = new URLSearchParams(searchParams)
// Deleting step to avoid double searchparams after rewrite
selectRoomParams.delete("step")
const booking = getQueryParamsForEnterDetails(selectRoomParams)
const booking = convertSearchParamsToObj<SelectRateSearchParams>(searchParams)
const {
hotel: hotelId,
hotelId,
rooms: [
{ adults, children, roomTypeCode, rateCode, packages: packageCodes },
], // TODO: Handle multiple rooms
@@ -153,8 +151,8 @@ export default async function StepPage({
}
: undefined
const arrivalDate = new Date(searchParams.fromDate)
const departureDate = new Date(searchParams.toDate)
const arrivalDate = new Date(fromDate)
const departureDate = new Date(toDate)
const hotelAttributes = hotelData?.data.attributes
const initialPageTrackingData: TrackingSDKPageData = {

View File

@@ -2,10 +2,8 @@ import { notFound } from "next/navigation"
import { getLocations } from "@/lib/trpc/memoizedRequests"
import {
generateChildrenString,
getHotelReservationQueryParams,
} from "@/components/HotelReservation/SelectRate/RoomSelection/utils"
import { generateChildrenString } from "@/components/HotelReservation/utils"
import { convertSearchParamsToObj } from "@/utils/url"
import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams"
import type {
@@ -14,62 +12,59 @@ import type {
} from "@/types/components/hotelReservation/selectRate/selectRate"
import type { Location } from "@/types/trpc/routers/hotel/locations"
interface HotelSearchDetails {
interface HotelSearchDetails<T> {
city: Location | null
hotel: Location | null
urlSearchParams?: URLSearchParams
selectHotelParams: T
adultsInRoom: number
childrenInRoom?: string
childrenInRoomArray?: Child[]
}
export async function getHotelSearchDetails({
export async function getHotelSearchDetails<
T extends SelectHotelSearchParams | SelectRateSearchParams,
>({
searchParams,
}: {
searchParams:
| (SelectHotelSearchParams & {
[key: string]: string
})
| (SelectRateSearchParams & {
[key: string]: string
})
}): Promise<HotelSearchDetails | null> {
searchParams: T & {
[key: string]: string
}
}): Promise<HotelSearchDetails<T> | null> {
const selectHotelParams = convertSearchParamsToObj<T>(searchParams)
const locations = await getLocations()
if (!locations || "error" in locations) return null
const city = locations.data.find(
(location) =>
location.name.toLowerCase() === searchParams.city?.toLowerCase()
location.name.toLowerCase() === selectHotelParams.city?.toLowerCase()
)
const hotel = locations.data.find(
(location) =>
"operaId" in location && location.operaId == searchParams.hotel
"operaId" in location && location.operaId == selectHotelParams.hotelId
)
if (!city && !hotel) return notFound()
const urlSearchParams = new URLSearchParams(searchParams)
const searchParamsObject = getHotelReservationQueryParams(urlSearchParams)
let adultsInRoom = 1
let childrenInRoom: string | undefined = undefined
let childrenInRoomArray: Child[] | undefined = undefined
if (searchParamsObject.room && searchParamsObject.room.length > 0) {
adultsInRoom = searchParamsObject.room[0].adults // TODO: Handle multiple rooms
childrenInRoom = searchParamsObject.room[0].child
? generateChildrenString(searchParamsObject.room[0].child)
: undefined // TODO: Handle multiple rooms
childrenInRoomArray = searchParamsObject.room[0].child
? searchParamsObject.room[0].child
const { rooms } = selectHotelParams
if (rooms && rooms.length > 0) {
adultsInRoom = rooms[0].adults // TODO: Handle multiple rooms
childrenInRoom = rooms[0].children
? generateChildrenString(rooms[0].children)
: undefined // TODO: Handle multiple rooms
childrenInRoomArray = rooms[0].children ? rooms[0].children : undefined // TODO: Handle multiple rooms
}
return {
city: city ?? null,
hotel: hotel ?? null,
urlSearchParams,
selectHotelParams,
adultsInRoom,
childrenInRoom,
childrenInRoomArray,

View File

@@ -4,21 +4,20 @@ import { getHotelData, getHotelPage } from "@/lib/trpc/memoizedRequests"
import BookingWidget, { preload } from "@/components/BookingWidget"
import { getLang } from "@/i18n/serverContext"
import type { BookingWidgetSearchData } from "@/types/components/bookingWidget"
import type { ContentTypeParams, PageArgs } from "@/types/params"
import { PageContentTypeEnum } from "@/types/requests/contentType"
export default async function BookingWidgetPage({
params,
searchParams,
}: PageArgs<ContentTypeParams, URLSearchParams>) {
}: PageArgs<ContentTypeParams, BookingWidgetSearchData>) {
if (!env.ENABLE_BOOKING_WIDGET) {
return null
}
preload()
const urlParams = new URLSearchParams()
if (params.contentType === PageContentTypeEnum.hotelPage) {
const hotelPageData = await getHotelPage()
@@ -26,10 +25,14 @@ export default async function BookingWidgetPage({
hotelId: hotelPageData?.hotel_page_id || "",
language: getLang(),
})
urlParams.set("hotel", hotelData?.data?.id || "")
urlParams.set("city", hotelData?.data?.attributes?.cityName || "")
return <BookingWidget searchParams={urlParams} />
const hotelPageParams = {
hotel: hotelData?.data?.id || "",
city: hotelData?.data?.attributes?.cityName || "",
}
return <BookingWidget bookingWidgetSearchParams={hotelPageParams} />
}
return <BookingWidget searchParams={searchParams} />
return <BookingWidget bookingWidgetSearchParams={searchParams} />
}

View File

@@ -2,16 +2,17 @@ import { env } from "@/env/server"
import BookingWidget, { preload } from "@/components/BookingWidget"
import type { PageArgs } from "@/types/params"
import type { BookingWidgetSearchData } from "@/types/components/bookingWidget"
import type { LangParams, PageArgs } from "@/types/params"
export default async function BookingWidgetPage({
searchParams,
}: PageArgs<{}, URLSearchParams>) {
}: PageArgs<LangParams, BookingWidgetSearchData>) {
if (!env.ENABLE_BOOKING_WIDGET_HOTELRESERVATION_PATH) {
return null
}
preload()
return <BookingWidget searchParams={searchParams} />
return <BookingWidget bookingWidgetSearchParams={searchParams} />
}

View File

@@ -3,11 +3,12 @@ import { serverClient } from "@/lib/trpc/server"
import BookingWidget, { preload } from "@/components/BookingWidget"
import type { BookingWidgetSearchData } from "@/types/components/bookingWidget"
import type { PageArgs } from "@/types/params"
export default async function BookingWidgetPage({
searchParams,
}: PageArgs<{}, URLSearchParams>) {
}: PageArgs<{}, BookingWidgetSearchData>) {
if (!env.ENABLE_BOOKING_WIDGET) {
return null
}
@@ -22,5 +23,5 @@ export default async function BookingWidgetPage({
return null
}
return <BookingWidget searchParams={searchParams} />
return <BookingWidget bookingWidgetSearchParams={searchParams} />
}