From d5bc2b3c57496eaaa1f9949d7793dfc8b4815d1d Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Fri, 24 Jan 2025 09:31:28 +0100 Subject: [PATCH] feat(SW-717) Multiple requests if adult differ between rooms --- .../(standard)/select-rate/page.tsx | 6 +- .../hotelreservation/(standard)/utils.ts | 6 +- .../SelectHotelMapContainer.tsx | 6 +- .../HotelReservation/SelectHotel/index.tsx | 6 +- .../SelectRate/HotelInfoCard/NoRoomsAlert.tsx | 55 +++++++++++++----- .../SelectRate/Rooms/RoomsContainer.tsx | 58 ++++++++++++------- .../selectRate/hotelInfoCard.ts | 1 + .../selectRate/roomsContainer.ts | 1 + .../hotelReservation/selectRate/selectRate.ts | 2 +- 9 files changed, 93 insertions(+), 48 deletions(-) diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx index ccda67e21..90a96095b 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx @@ -61,7 +61,7 @@ export default async function SelectRatePage({ searchTerm: selectHotelParams.city ?? hotel?.name, arrivalDate: format(arrivalDate, "yyyy-MM-dd"), departureDate: format(departureDate, "yyyy-MM-dd"), - noOfAdults: adultsInRoom, + noOfAdults: adultsInRoom[0], // TODO: Handle multiple rooms noOfChildren: childrenInRoom?.length, ageOfChildren: childrenInRoom?.map((c) => c.age).join(","), childBedPreference: childrenInRoom @@ -86,7 +86,7 @@ export default async function SelectRatePage({ lang={params.lang} fromDate={fromDate.toDate()} toDate={toDate.toDate()} - adultCount={adultsInRoom} + adultArray={adultsInRoom} childArray={childrenInRoom} /> @@ -99,7 +99,7 @@ export default async function SelectRatePage({ lang={params.lang} fromDate={fromDate.toDate()} toDate={toDate.toDate()} - adultCount={adultsInRoom} + adultArray={adultsInRoom} childArray={childrenInRoom} /> diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/utils.ts b/app/[lang]/(live)/(public)/hotelreservation/(standard)/utils.ts index d4763b53d..29dc4d5e1 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/utils.ts +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/utils.ts @@ -23,7 +23,7 @@ interface HotelSearchDetails { city: Location | null hotel: HotelLocation | null selectHotelParams: SelectHotelParams & { city: string | undefined } - adultsInRoom: number + adultsInRoom: number[] childrenInRoomString?: string childrenInRoom?: Child[] } @@ -79,7 +79,7 @@ export async function getHotelSearchDetails< if (!city && !hotel) return notFound() if (isAlternativeHotels && (!city || !hotel)) return notFound() - let adultsInRoom = 1 + let adultsInRoom: number[] = [] let childrenInRoomString: HotelSearchDetails["childrenInRoomString"] = undefined let childrenInRoom: HotelSearchDetails["childrenInRoom"] = undefined @@ -87,7 +87,7 @@ export async function getHotelSearchDetails< const { rooms } = selectHotelParams if (rooms && rooms.length > 0) { - adultsInRoom = rooms[0].adults // TODO: Handle multiple rooms + adultsInRoom = rooms.map((room) => room.adults?.[0] ?? 0) childrenInRoomString = rooms[0].childrenInRoom ? generateChildrenString(rooms[0].childrenInRoom) : undefined // TODO: Handle multiple rooms diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainer.tsx b/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainer.tsx index d4379e22b..ebe743617 100644 --- a/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainer.tsx +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainer.tsx @@ -69,7 +69,7 @@ export async function SelectHotelMapContainer({ fetchAlternativeHotels(isAlternativeFor.id, { roomStayStartDate: selectHotelParams.fromDate, roomStayEndDate: selectHotelParams.toDate, - adults: adultsInRoom, + adults: adultsInRoom[0], children: childrenInRoomString, }) ) @@ -78,7 +78,7 @@ export async function SelectHotelMapContainer({ cityId: city.id, roomStayStartDate: selectHotelParams.fromDate, roomStayEndDate: selectHotelParams.toDate, - adults: adultsInRoom, + adults: adultsInRoom[0], children: childrenInRoomString, }) ) @@ -118,7 +118,7 @@ export async function SelectHotelMapContainer({ : (selectHotelParams.city as string), arrivalDate: format(arrivalDate, "yyyy-MM-dd"), departureDate: format(departureDate, "yyyy-MM-dd"), - noOfAdults: adultsInRoom, + noOfAdults: adultsInRoom[0], // TODO: Handle multiple rooms noOfChildren: childrenInRoom?.length, ageOfChildren: childrenInRoom?.map((c) => c.age).join(","), childBedPreference: childrenInRoom diff --git a/components/HotelReservation/SelectHotel/index.tsx b/components/HotelReservation/SelectHotel/index.tsx index e8fbbcaef..983a91017 100644 --- a/components/HotelReservation/SelectHotel/index.tsx +++ b/components/HotelReservation/SelectHotel/index.tsx @@ -83,7 +83,7 @@ export default async function SelectHotel({ fetchAlternativeHotels(isAlternativeFor.id, { roomStayStartDate: selectHotelParams.fromDate, roomStayEndDate: selectHotelParams.toDate, - adults: adultsInRoom, + adults: adultsInRoom[0], children: childrenInRoomString, }) ) @@ -92,7 +92,7 @@ export default async function SelectHotel({ cityId: city.id, roomStayStartDate: selectHotelParams.fromDate, roomStayEndDate: selectHotelParams.toDate, - adults: adultsInRoom, + adults: adultsInRoom[0], children: childrenInRoomString, }) ) @@ -167,7 +167,7 @@ export default async function SelectHotel({ : (selectHotelParams.city as string), arrivalDate: format(arrivalDate, "yyyy-MM-dd"), departureDate: format(departureDate, "yyyy-MM-dd"), - noOfAdults: adultsInRoom, + noOfAdults: adultsInRoom[0], // TODO: Handle multiple rooms, noOfChildren: childrenInRoom?.length, ageOfChildren: childrenInRoom?.map((c) => c.age).join(","), childBedPreference: childrenInRoom diff --git a/components/HotelReservation/SelectRate/HotelInfoCard/NoRoomsAlert.tsx b/components/HotelReservation/SelectRate/HotelInfoCard/NoRoomsAlert.tsx index 2badd5fce..d3edeb373 100644 --- a/components/HotelReservation/SelectRate/HotelInfoCard/NoRoomsAlert.tsx +++ b/components/HotelReservation/SelectRate/HotelInfoCard/NoRoomsAlert.tsx @@ -16,7 +16,7 @@ import type { Lang } from "@/constants/languages" type Props = { hotelId: number lang: Lang - adultCount: number + adultArray: number[] childArray?: Child[] fromDate: Date toDate: Date @@ -27,24 +27,53 @@ export async function NoRoomsAlert({ fromDate, toDate, childArray, - adultCount, + adultArray, lang, }: Props) { - const [availability, availabilityError] = await safeTry( - getRoomsAvailability({ - hotelId: hotelId, - roomStayStartDate: dt(fromDate).format("YYYY-MM-DD"), - roomStayEndDate: dt(toDate).format("YYYY-MM-DD"), - adults: adultCount, - children: childArray ? generateChildrenString(childArray) : undefined, // TODO: Handle multiple rooms, - }) - ) + const fromDateString = dt(fromDate).format("YYYY-MM-DD") + const toDateString = dt(toDate).format("YYYY-MM-DD") - if (!availability || availabilityError) { + const uniqueAdultCounts = [...new Set(adultArray)] + const roomsAvailabilityPromises = uniqueAdultCounts.map((adultCount) => { + return safeTry( + getRoomsAvailability({ + hotelId: hotelId, + roomStayStartDate: fromDateString, + roomStayEndDate: toDateString, + adults: adultCount, + children: + childArray && childArray.length > 0 + ? generateChildrenString(childArray) + : undefined, + }) + ) + }) + + const roomsAvailabilityResults = await Promise.all(roomsAvailabilityPromises) + + const roomsAvailability = roomsAvailabilityResults.reduce< + (typeof roomsAvailabilityResults)[0][0] + >((acc, [result, error]) => { + if (error) { + console.error("[RoomsContainer] unable to fetch room availability") + return acc + } + if (!acc) return result + if (!result) return acc + return { + ...result, + roomConfigurations: [ + ...acc.roomConfigurations, + ...result.roomConfigurations, + ], + } + }, null) + + if (!roomsAvailability) { return null } - const noRoomsAvailable = availability.roomConfigurations.reduce( + const noRoomsAvailable = roomsAvailability.roomConfigurations.reduce( (acc, room) => { return acc && room.status === "NotAvailable" }, diff --git a/components/HotelReservation/SelectRate/Rooms/RoomsContainer.tsx b/components/HotelReservation/SelectRate/Rooms/RoomsContainer.tsx index 723541b6a..23e426b65 100644 --- a/components/HotelReservation/SelectRate/Rooms/RoomsContainer.tsx +++ b/components/HotelReservation/SelectRate/Rooms/RoomsContainer.tsx @@ -16,7 +16,7 @@ import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectR import type { RoomsContainerProps } from "@/types/components/hotelReservation/selectRate/roomsContainer" export async function RoomsContainer({ - adultCount, + adultArray, childArray, fromDate, hotelId, @@ -42,7 +42,7 @@ export async function RoomsContainer({ hotelId: hotelId.toString(), startDate: fromDateString, endDate: toDateString, - adults: adultCount, + adults: adultArray[0], children: childArray ? childArray.length : undefined, packageCodes: [ RoomPackageCodeEnum.ACCESSIBILITY_ROOM, @@ -52,35 +52,49 @@ export async function RoomsContainer({ }) ) - const roomsAvailabilityPromise = safeTry( - getRoomsAvailability({ - hotelId: hotelId, - roomStayStartDate: fromDateString, - roomStayEndDate: toDateString, - adults: adultCount, - children: - childArray && childArray.length > 0 - ? generateChildrenString(childArray) - : undefined, - }) - ) + const uniqueAdultCounts = [...new Set(adultArray)] + const roomsAvailabilityPromises = uniqueAdultCounts.map((adultCount) => { + return safeTry( + getRoomsAvailability({ + hotelId: hotelId, + roomStayStartDate: fromDateString, + roomStayEndDate: toDateString, + adults: adultCount, + children: + childArray && childArray.length > 0 + ? generateChildrenString(childArray) + : undefined, + }) + ) + }) const [hotelData, hotelDataError] = await hotelDataPromise const [packages, packagesError] = await packagesPromise - const [roomsAvailability, roomsAvailabilityError] = - await roomsAvailabilityPromise + const roomsAvailabilityResults = await Promise.all(roomsAvailabilityPromises) + + const roomsAvailability = roomsAvailabilityResults.reduce< + (typeof roomsAvailabilityResults)[0][0] + >((acc, [result, error]) => { + if (error) { + console.error("[RoomsContainer] unable to fetch room availability") + return acc + } + if (!acc) return result + if (!result) return acc + return { + ...result, + roomConfigurations: [ + ...acc.roomConfigurations, + ...result.roomConfigurations, + ], + } + }, null) if (packagesError) { // TODO: Log packages error console.error("[RoomsContainer] unable to fetch packages") } - if (roomsAvailabilityError) { - // TODO: show proper error component - console.error("[RoomsContainer] unable to fetch room availability") - return null - } - if (!roomsAvailability) { // HotelInfoCard has the logic for displaying when there are no rooms available return null diff --git a/types/components/hotelReservation/selectRate/hotelInfoCard.ts b/types/components/hotelReservation/selectRate/hotelInfoCard.ts index 8fc9a8c2d..78250822a 100644 --- a/types/components/hotelReservation/selectRate/hotelInfoCard.ts +++ b/types/components/hotelReservation/selectRate/hotelInfoCard.ts @@ -3,6 +3,7 @@ import type { Child } from "./selectRate" export interface HotelInfoCardProps { adultCount: number + adultArray: number[] childArray?: Child[] fromDate: Date hotelId: number diff --git a/types/components/hotelReservation/selectRate/roomsContainer.ts b/types/components/hotelReservation/selectRate/roomsContainer.ts index 74f52aa2d..a972bcd0c 100644 --- a/types/components/hotelReservation/selectRate/roomsContainer.ts +++ b/types/components/hotelReservation/selectRate/roomsContainer.ts @@ -3,6 +3,7 @@ import type { Child } from "./selectRate" export interface RoomsContainerProps { adultCount: number + adultArray: number[] childArray?: Child[] fromDate: Date hotelId: number diff --git a/types/components/hotelReservation/selectRate/selectRate.ts b/types/components/hotelReservation/selectRate/selectRate.ts index 8ca10f6b1..679e0b1db 100644 --- a/types/components/hotelReservation/selectRate/selectRate.ts +++ b/types/components/hotelReservation/selectRate/selectRate.ts @@ -11,7 +11,7 @@ export interface Child { } export interface Room { - adults: number + adults: number[] roomTypeCode: string rateCode: string counterRateCode: string