feat: add multiroom tracking to booking flow
This commit is contained in:
@@ -1,40 +1,26 @@
|
||||
import { differenceInCalendarDays, format, isWeekend } from "date-fns"
|
||||
import { notFound } from "next/navigation"
|
||||
|
||||
import { env } from "@/env/server"
|
||||
import { getCityCoordinates } from "@/lib/trpc/memoizedRequests"
|
||||
|
||||
import {
|
||||
fetchAlternativeHotels,
|
||||
fetchAvailableHotels,
|
||||
fetchBookingCodeAvailableHotels,
|
||||
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 { getIntl } from "@/i18n"
|
||||
import { getLang } from "@/i18n/serverContext"
|
||||
import { getHotelSearchDetails } from "@/utils/hotelSearchDetails"
|
||||
import { safeTry } from "@/utils/safeTry"
|
||||
|
||||
import { getHotelPins } from "../../HotelCardDialogListing/utils"
|
||||
import { getFiltersFromHotels, getHotels } from "../helpers"
|
||||
import { getTracking } from "./tracking"
|
||||
import SelectHotelMap from "."
|
||||
|
||||
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
|
||||
import type { HotelData } 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 intl = await getIntl()
|
||||
const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
|
||||
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
|
||||
const getHotelSearchDetailsPromise = safeTry(
|
||||
@@ -50,106 +36,58 @@ export async function SelectHotelMapContainer({
|
||||
|
||||
const [searchDetails] = await getHotelSearchDetailsPromise
|
||||
|
||||
if (!searchDetails) return notFound()
|
||||
if (!searchDetails) {
|
||||
return notFound()
|
||||
}
|
||||
|
||||
const {
|
||||
city,
|
||||
selectHotelParams,
|
||||
adultsInRoom,
|
||||
childrenInRoom,
|
||||
childrenInRoomString,
|
||||
hotel: isAlternativeFor,
|
||||
bookingCode,
|
||||
childrenInRoom,
|
||||
city,
|
||||
hotel: isAlternativeFor,
|
||||
noOfRooms,
|
||||
redemption,
|
||||
selectHotelParams,
|
||||
} = searchDetails
|
||||
|
||||
if (!city) return notFound()
|
||||
if (!city) {
|
||||
return notFound()
|
||||
}
|
||||
|
||||
const fetchAvailableHotelsPromise = isAlternativeFor
|
||||
? safeTry(
|
||||
fetchAlternativeHotels(isAlternativeFor.id, {
|
||||
roomStayStartDate: selectHotelParams.fromDate,
|
||||
roomStayEndDate: selectHotelParams.toDate,
|
||||
adults: adultsInRoom[0],
|
||||
children: childrenInRoomString,
|
||||
bookingCode,
|
||||
redemption,
|
||||
})
|
||||
)
|
||||
: bookingCode
|
||||
? safeTry(
|
||||
fetchBookingCodeAvailableHotels({
|
||||
cityId: city.id,
|
||||
roomStayStartDate: selectHotelParams.fromDate,
|
||||
roomStayEndDate: selectHotelParams.toDate,
|
||||
adults: adultsInRoom[0],
|
||||
children: childrenInRoomString,
|
||||
bookingCode,
|
||||
})
|
||||
)
|
||||
: safeTry(
|
||||
fetchAvailableHotels({
|
||||
cityId: city.id,
|
||||
roomStayStartDate: selectHotelParams.fromDate,
|
||||
roomStayEndDate: selectHotelParams.toDate,
|
||||
adults: adultsInRoom[0],
|
||||
children: childrenInRoomString,
|
||||
redemption,
|
||||
})
|
||||
)
|
||||
const hotels = await getHotels(
|
||||
selectHotelParams,
|
||||
isAlternativeFor,
|
||||
bookingCode,
|
||||
city,
|
||||
!!redemption
|
||||
)
|
||||
|
||||
const [hotels] = await fetchAvailableHotelsPromise
|
||||
|
||||
const validHotels = (hotels?.filter(Boolean) as HotelData[]) || []
|
||||
|
||||
const currencyValue = redemption
|
||||
? intl.formatMessage({ id: "Points" })
|
||||
: undefined
|
||||
const hotelPins = getHotelPins(validHotels, currencyValue)
|
||||
const filterList = getFiltersFromHotels(validHotels)
|
||||
const hotelPins = getHotelPins(hotels)
|
||||
const filterList = getFiltersFromHotels(hotels)
|
||||
const cityCoordinates = await getCityCoordinates({
|
||||
city: city.name,
|
||||
hotel: { address: hotels?.[0]?.hotelData?.address.streetAddress },
|
||||
hotel: { address: hotels?.[0]?.hotel?.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[0], // TODO: Handle multiple rooms
|
||||
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,
|
||||
}
|
||||
const { hotelsTrackingData, pageTrackingData } = getTracking(
|
||||
lang,
|
||||
!!isAlternativeFor,
|
||||
!!isAlternativeHotels,
|
||||
arrivalDate,
|
||||
departureDate,
|
||||
adultsInRoom,
|
||||
childrenInRoom,
|
||||
hotels.length,
|
||||
selectHotelParams.hotelId,
|
||||
noOfRooms,
|
||||
hotels?.[0]?.hotel.address.country,
|
||||
hotels?.[0]?.hotel.address.city,
|
||||
selectHotelParams.city
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -157,7 +95,7 @@ export async function SelectHotelMapContainer({
|
||||
apiKey={googleMapsApiKey}
|
||||
hotelPins={hotelPins}
|
||||
mapId={googleMapId}
|
||||
hotels={validHotels}
|
||||
hotels={hotels}
|
||||
filterList={filterList}
|
||||
cityCoordinates={cityCoordinates}
|
||||
bookingCode={bookingCode ?? ""}
|
||||
|
||||
@@ -26,10 +26,10 @@ import { getVisibleHotels } from "./utils"
|
||||
|
||||
import styles from "./selectHotelMapContent.module.css"
|
||||
|
||||
import type { HotelData } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
|
||||
import type { SelectHotelMapProps } from "@/types/components/hotelReservation/selectHotel/map"
|
||||
import { BookingCodeFilterEnum } from "@/types/enums/bookingCodeFilter"
|
||||
import { RateTypeEnum } from "@/types/enums/rateType"
|
||||
import type { HotelResponse } from "@/components/HotelReservation/SelectHotel/helpers"
|
||||
|
||||
const SKELETON_LOAD_DELAY = 750
|
||||
|
||||
@@ -46,7 +46,7 @@ export default function SelectHotelContent({
|
||||
const map = useMap()
|
||||
|
||||
const isAboveMobile = useMediaQuery("(min-width: 768px)")
|
||||
const [visibleHotels, setVisibleHotels] = useState<HotelData[]>([])
|
||||
const [visibleHotels, setVisibleHotels] = useState<HotelResponse[]>([])
|
||||
const [showSkeleton, setShowSkeleton] = useState<boolean>(true)
|
||||
const listingContainerRef = useRef<HTMLDivElement | null>(null)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { HotelData } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
|
||||
import type { HotelPin } from "@/types/components/hotelReservation/selectHotel/map"
|
||||
import type { HotelResponse } from "@/components/HotelReservation/SelectHotel/helpers"
|
||||
|
||||
export function getVisibleHotelPins(
|
||||
map: google.maps.Map | null,
|
||||
@@ -17,13 +17,13 @@ export function getVisibleHotelPins(
|
||||
}
|
||||
|
||||
export function getVisibleHotels(
|
||||
hotels: HotelData[],
|
||||
hotels: HotelResponse[],
|
||||
filteredHotelPins: HotelPin[],
|
||||
map: google.maps.Map | null
|
||||
) {
|
||||
const visibleHotelPins = getVisibleHotelPins(map, filteredHotelPins)
|
||||
const visibleHotels = hotels.filter((hotel) =>
|
||||
visibleHotelPins.some((pin) => pin.operaId === hotel.hotelData.operaId)
|
||||
visibleHotelPins.some((pin) => pin.operaId === hotel.hotel.operaId)
|
||||
)
|
||||
return visibleHotels
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import { differenceInCalendarDays, format, isWeekend } from "date-fns"
|
||||
|
||||
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
|
||||
import {
|
||||
TrackingChannelEnum,
|
||||
type TrackingSDKHotelInfo,
|
||||
type TrackingSDKPageData,
|
||||
} from "@/types/components/tracking"
|
||||
import type { Lang } from "@/constants/languages"
|
||||
import type { ChildrenInRoom } from "@/utils/hotelSearchDetails"
|
||||
|
||||
export function getTracking(
|
||||
lang: Lang,
|
||||
isAlternativeFor: boolean,
|
||||
isAlternativeHotels: boolean,
|
||||
arrivalDate: Date,
|
||||
departureDate: Date,
|
||||
adultsInRoom: number[],
|
||||
childrenInRoom: ChildrenInRoom,
|
||||
hotelsResult: number,
|
||||
hotelId: string,
|
||||
noOfRooms: number,
|
||||
country: string | undefined,
|
||||
hotelCity: string | undefined,
|
||||
paramCity: string | undefined
|
||||
) {
|
||||
const pageTrackingData: TrackingSDKPageData = {
|
||||
channel: TrackingChannelEnum["hotelreservation"],
|
||||
domainLanguage: lang,
|
||||
pageId: isAlternativeFor ? "alternative-hotels" : "select-hotel",
|
||||
pageName: isAlternativeHotels
|
||||
? "hotelreservation|alternative-hotels|mapview"
|
||||
: "hotelreservation|select-hotel|mapview",
|
||||
pageType: "bookinghotelsmapviewpage",
|
||||
siteSections: isAlternativeHotels
|
||||
? "hotelreservation|altervative-hotels|mapview"
|
||||
: "hotelreservation|select-hotel|mapview",
|
||||
siteVersion: "new-web",
|
||||
}
|
||||
|
||||
const hotelsTrackingData: TrackingSDKHotelInfo = {
|
||||
ageOfChildren: childrenInRoom
|
||||
?.map((c) => c?.map((k) => k.age).join(",") ?? "-")
|
||||
.join("|"),
|
||||
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
|
||||
availableResults: hotelsResult,
|
||||
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
|
||||
childBedPreference: childrenInRoom
|
||||
?.map((c) => c?.map((k) => ChildBedMapEnum[k.bed]).join(",") ?? "-")
|
||||
.join("|"),
|
||||
country,
|
||||
departureDate: format(departureDate, "yyyy-MM-dd"),
|
||||
duration: differenceInCalendarDays(departureDate, arrivalDate),
|
||||
leadTime: differenceInCalendarDays(arrivalDate, new Date()),
|
||||
noOfAdults: adultsInRoom.join(","),
|
||||
noOfChildren: childrenInRoom?.map((kids) => kids?.length ?? 0).join(","),
|
||||
noOfRooms,
|
||||
region: hotelCity,
|
||||
searchTerm: isAlternativeFor ? hotelId : (paramCity as string),
|
||||
searchType: "destination",
|
||||
}
|
||||
|
||||
return {
|
||||
hotelsTrackingData,
|
||||
pageTrackingData,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user