Files
web/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainer.tsx
2025-01-30 13:51:47 +01:00

155 lines
5.0 KiB
TypeScript

import { differenceInCalendarDays, format, isWeekend } from "date-fns"
import { notFound } from "next/navigation"
import { Suspense } from "react"
import { env } from "@/env/server"
import { getCityCoordinates } from "@/lib/trpc/memoizedRequests"
import {
fetchAlternativeHotels,
fetchAvailableHotels,
getFiltersFromHotels,
} from "@/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils"
import { getHotelSearchDetails } from "@/app/[lang]/(live)/(public)/hotelreservation/(standard)/utils"
import TrackingSDK from "@/components/TrackingSDK"
import { getLang } from "@/i18n/serverContext"
import { safeTry } from "@/utils/safeTry"
import { getHotelPins } from "../../HotelCardDialogListing/utils"
import SelectHotelMap from "."
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
import type {
HotelData,
NullableHotelData,
} from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
import type { SelectHotelMapContainerProps } from "@/types/components/hotelReservation/selectHotel/map"
import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams"
import {
TrackingChannelEnum,
type TrackingSDKHotelInfo,
type TrackingSDKPageData,
} from "@/types/components/tracking"
export async function SelectHotelMapContainer({
searchParams,
isAlternativeHotels,
}: SelectHotelMapContainerProps) {
const lang = getLang()
const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
const getHotelSearchDetailsPromise = safeTry(
getHotelSearchDetails(
{
searchParams: searchParams as SelectHotelSearchParams & {
[key: string]: string
},
},
isAlternativeHotels
)
)
const [searchDetails] = await getHotelSearchDetailsPromise
if (!searchDetails) return notFound()
const {
city,
selectHotelParams,
adultsInRoom,
childrenInRoom,
childrenInRoomString,
hotel: isAlternativeFor,
} = searchDetails
if (!city) return notFound()
const fetchAvailableHotelsPromise = isAlternativeFor
? safeTry(
fetchAlternativeHotels(isAlternativeFor.id, {
roomStayStartDate: selectHotelParams.fromDate,
roomStayEndDate: selectHotelParams.toDate,
adults: adultsInRoom,
children: childrenInRoomString,
})
)
: safeTry(
fetchAvailableHotels({
cityId: city.id,
roomStayStartDate: selectHotelParams.fromDate,
roomStayEndDate: selectHotelParams.toDate,
adults: adultsInRoom,
children: childrenInRoomString,
})
)
const [hotels] = await fetchAvailableHotelsPromise
const validHotels = (hotels?.filter(Boolean) as HotelData[]) || []
const hotelPins = getHotelPins(validHotels)
const filterList = getFiltersFromHotels(validHotels)
const cityCoordinates = await getCityCoordinates({
city: city.name,
hotel: { address: hotels?.[0]?.hotelData?.address.streetAddress },
})
const arrivalDate = new Date(selectHotelParams.fromDate)
const departureDate = new Date(selectHotelParams.toDate)
const pageTrackingData: TrackingSDKPageData = {
pageId: isAlternativeFor ? "alternative-hotels" : "select-hotel",
domainLanguage: lang,
channel: TrackingChannelEnum["hotelreservation"],
pageName: isAlternativeHotels
? "hotelreservation|alternative-hotels|mapview"
: "hotelreservation|select-hotel|mapview",
siteSections: isAlternativeHotels
? "hotelreservation|altervative-hotels|mapview"
: "hotelreservation|select-hotel|mapview",
pageType: "bookinghotelsmapviewpage",
siteVersion: "new-web",
}
const hotelsTrackingData: TrackingSDKHotelInfo = {
availableResults: validHotels.length,
searchTerm: isAlternativeFor
? selectHotelParams.hotelId
: (selectHotelParams.city as string),
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
departureDate: format(departureDate, "yyyy-MM-dd"),
noOfAdults: adultsInRoom,
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: "destination",
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
country: validHotels?.[0]?.hotelData.address.country,
region: validHotels?.[0]?.hotelData.address.city,
}
return (
<>
<SelectHotelMap
apiKey={googleMapsApiKey}
hotelPins={hotelPins}
mapId={googleMapId}
hotels={validHotels}
filterList={filterList}
cityCoordinates={cityCoordinates}
/>
<Suspense fallback={null}>
<TrackingSDK
pageData={pageTrackingData}
hotelInfo={hotelsTrackingData}
/>
</Suspense>
</>
)
}