import { differenceInCalendarDays, format, isWeekend } from "date-fns" import { notFound } from "next/navigation" import { Suspense } from "react" import { getBreakfastPackages, getHotel, getPackages, getProfileSafely, getSelectedRoomAvailability, getUserTracking, } from "@/lib/trpc/memoizedRequests" import BedType from "@/components/HotelReservation/EnterDetails/BedType" import Breakfast from "@/components/HotelReservation/EnterDetails/Breakfast" import Details from "@/components/HotelReservation/EnterDetails/Details" import HotelHeader from "@/components/HotelReservation/EnterDetails/Header" import HistoryStateManager from "@/components/HotelReservation/EnterDetails/HistoryStateManager" import Payment from "@/components/HotelReservation/EnterDetails/Payment" import SectionAccordion from "@/components/HotelReservation/EnterDetails/SectionAccordion" 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 } from "@/components/HotelReservation/utils" 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 TrackingSDKHotelInfo } from "@/types/components/tracking" import { StepEnum } from "@/types/enums/step" import type { LangParams, PageArgs } from "@/types/params" function isValidStep(step: string): step is StepEnum { return Object.values(StepEnum).includes(step as StepEnum) } export default async function StepPage({ params: { lang }, searchParams, }: PageArgs) { if (!isValidStep(searchParams.step)) { return notFound() } setLang(lang) const intl = await getIntl() const selectRoomParams = new URLSearchParams(searchParams) // Deleting step to avoid double searchparams after rewrite selectRoomParams.delete("step") const booking = convertSearchParamsToObj(searchParams) const { hotelId, rooms: [ { adults, childrenInRoom, roomTypeCode, rateCode, packages: packageCodes, }, ], // TODO: Handle multiple rooms fromDate, toDate, } = booking const childrenAsString = childrenInRoom && generateChildrenString(childrenInRoom) const breakfastInput = { adults, fromDate, hotelId, toDate } const selectedRoomAvailabilityInput = { adults, children: childrenAsString, hotelId, packageCodes, rateCode, roomStayStartDate: fromDate, roomStayEndDate: toDate, roomTypeCode, } void getProfileSafely() void getBreakfastPackages(breakfastInput) void getSelectedRoomAvailability(selectedRoomAvailabilityInput) if (packageCodes?.length) { void getPackages({ adults, children: childrenInRoom?.length, endDate: toDate, hotelId, packageCodes, startDate: fromDate, }) } const packages = packageCodes ? await getPackages({ adults, children: childrenInRoom?.length, endDate: toDate, hotelId, packageCodes, startDate: fromDate, }) : null const roomAvailability = await getSelectedRoomAvailability( selectedRoomAvailabilityInput ) const hotelData = await getHotel({ hotelId, isCardOnlyPayment: roomAvailability?.mustBeGuaranteed, language: lang, }) const breakfastPackages = await getBreakfastPackages(breakfastInput) const user = await getProfileSafely() const userTrackingData = await getUserTracking() if (!hotelData || !roomAvailability) { return notFound() } const { mustBeGuaranteed, breakfastIncluded } = roomAvailability const paymentGuarantee = intl.formatMessage({ id: "Payment Guarantee", }) const payment = intl.formatMessage({ id: "Payment", }) const guaranteeWithCard = intl.formatMessage({ id: "Guarantee booking with credit card", }) const selectPaymentMethod = intl.formatMessage({ id: "Select payment method", }) const roomPrice = { memberPrice: roomAvailability.memberRate?.localPrice.pricePerStay, publicPrice: roomAvailability.publicRate!.localPrice.pricePerStay, } const memberPrice = roomAvailability.memberRate ? { price: roomAvailability.memberRate.localPrice.pricePerStay, currency: roomAvailability.memberRate.localPrice.currency, } : undefined const arrivalDate = new Date(searchParams.fromdate) const departureDate = new Date(searchParams.todate) const hotelAttributes = hotelData?.hotel const initialHotelsTrackingData: TrackingSDKHotelInfo = { searchTerm: searchParams.city, arrivalDate: format(arrivalDate, "yyyy-MM-dd"), departureDate: format(departureDate, "yyyy-MM-dd"), noOfAdults: adults, noOfChildren: childrenInRoom?.length, ageOfChildren: childrenInRoom?.map((c) => c.age).join(","), childBedPreference: childrenInRoom ?.map((c) => ChildBedMapEnum[c.bed]) .join("|"), noOfRooms: 1, // // TODO: Handle multiple rooms duration: differenceInCalendarDays(departureDate, arrivalDate), leadTime: differenceInCalendarDays(arrivalDate, new Date()), searchType: "hotel", bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday", country: hotelAttributes?.address.country, hotelID: hotelAttributes?.operaId, region: hotelAttributes?.address.city, } const summary = { cancellationText: roomAvailability.cancellationText, isMember: !!user, rateDetails: roomAvailability.rateDetails, roomType: roomAvailability.selectedRoom.roomType, breakfastIncluded, } const showBreakfastStep = Boolean( breakfastPackages?.length && !breakfastIncluded ) return (
{/* TODO: How to handle no beds found? */} {roomAvailability.bedTypes ? ( ) : null} {showBreakfastStep ? ( ) : null}
) }