175 lines
5.1 KiB
TypeScript
175 lines
5.1 KiB
TypeScript
"use client"
|
|
import { usePathname } from "next/navigation"
|
|
import { useEffect, useMemo, useRef } from "react"
|
|
|
|
import { useEnterDetailsStore } from "@/stores/enter-details"
|
|
import { selectRoom } from "@/stores/enter-details/helpers"
|
|
|
|
import { useSessionId } from "@/hooks/useSessionId"
|
|
import { createSDKPageObject, trackPageView } from "@/utils/tracking"
|
|
|
|
import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
|
|
import {
|
|
type Ancillary,
|
|
TrackingChannelEnum,
|
|
type TrackingSDKHotelInfo,
|
|
type TrackingSDKPageData,
|
|
type TrackingSDKUserData,
|
|
} from "@/types/components/tracking"
|
|
import type { Packages } from "@/types/requests/packages"
|
|
import type { RoomConfiguration } from "@/types/trpc/routers/hotel/roomAvailability"
|
|
import type { Lang } from "@/constants/languages"
|
|
|
|
type Props = {
|
|
initialHotelsTrackingData: TrackingSDKHotelInfo
|
|
userTrackingData: TrackingSDKUserData
|
|
lang: Lang
|
|
selectedRoom: RoomConfiguration
|
|
cancellationRule: string
|
|
}
|
|
|
|
export default function EnterDetailsTracking(props: Props) {
|
|
const {
|
|
initialHotelsTrackingData,
|
|
userTrackingData,
|
|
lang,
|
|
selectedRoom,
|
|
cancellationRule,
|
|
} = props
|
|
|
|
const { bedType, breakfast, roomPrice, roomRate, roomFeatures } =
|
|
useEnterDetailsStore(selectRoom)
|
|
|
|
const totalPrice = useEnterDetailsStore((state) => state.totalPrice)
|
|
|
|
const pathName = usePathname()
|
|
const sessionId = useSessionId()
|
|
|
|
const previousPathname = useRef<string | null>(null)
|
|
|
|
const getSpecialRoomType = (packages: Packages | null) => {
|
|
if (!packages) {
|
|
return ""
|
|
}
|
|
|
|
const specialRoom = packages.find((p) =>
|
|
[
|
|
RoomPackageCodeEnum.PET_ROOM,
|
|
RoomPackageCodeEnum.ALLERGY_ROOM,
|
|
RoomPackageCodeEnum.ACCESSIBILITY_ROOM,
|
|
].includes(p.code)
|
|
)
|
|
|
|
switch (specialRoom?.code) {
|
|
case RoomPackageCodeEnum.PET_ROOM:
|
|
return "pet-friendly"
|
|
case RoomPackageCodeEnum.ALLERGY_ROOM:
|
|
return "allergy room"
|
|
case RoomPackageCodeEnum.ACCESSIBILITY_ROOM:
|
|
return "accessibility room"
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
const getAnalyticsRateCode = (rateCodeName: string | undefined) => {
|
|
switch (rateCodeName) {
|
|
case "FLEXEU":
|
|
return "flex"
|
|
case "CHANGEEU":
|
|
return "change"
|
|
case "SAVEEU":
|
|
return "save"
|
|
default:
|
|
return rateCodeName
|
|
}
|
|
}
|
|
|
|
const pageObject = useMemo(() => {
|
|
const stepByPathname = pathName.split("/").pop()!
|
|
const pageTrackingData: TrackingSDKPageData = {
|
|
pageId: stepByPathname,
|
|
domainLanguage: lang,
|
|
channel: TrackingChannelEnum["hotelreservation"],
|
|
pageName: `hotelreservation|${stepByPathname}`,
|
|
siteSections: `hotelreservation|${stepByPathname}`,
|
|
pageType: stepByPathname,
|
|
siteVersion: "new-web",
|
|
}
|
|
|
|
const trackingData = {
|
|
...pageTrackingData,
|
|
pathName,
|
|
sessionId,
|
|
pageLoadTime: 0, // Yes, this is instant
|
|
}
|
|
const pageObject = createSDKPageObject(trackingData)
|
|
|
|
return pageObject
|
|
}, [lang, sessionId, pathName])
|
|
|
|
const hotelDetailsData = useMemo(() => {
|
|
const isMember = true
|
|
const rate = isMember ? roomRate.memberRate : roomRate.publicRate
|
|
|
|
const breakfastAncillary = breakfast && {
|
|
hotelid: initialHotelsTrackingData.hotelID,
|
|
productName: "BreakfastAdult",
|
|
productCategory: "", // TODO: Add category
|
|
productId: breakfast.code,
|
|
productPrice: +breakfast.localPrice.price,
|
|
productUnits: initialHotelsTrackingData.noOfAdults,
|
|
productPoints: 0,
|
|
productType: "food",
|
|
}
|
|
|
|
const data: TrackingSDKHotelInfo = {
|
|
...initialHotelsTrackingData,
|
|
rateCode: rate?.rateCode,
|
|
rateCodeType: roomRate.publicRate.rateType,
|
|
rateCodeName: "", //TODO: this should be ratedefinition.title and should be fixed when tracking is implemented for multiroom.
|
|
rateCodeCancellationRule: cancellationRule,
|
|
revenueCurrencyCode: totalPrice.local?.currency,
|
|
breakfastOption: breakfast ? "breakfast buffet" : "no breakfast",
|
|
totalPrice: totalPrice.local?.price,
|
|
specialRoomType: getSpecialRoomType(roomFeatures),
|
|
roomTypeName: selectedRoom.roomType,
|
|
bedType: bedType?.description,
|
|
roomTypeCode: bedType?.roomTypeCode,
|
|
roomPrice: roomPrice.perStay.local.price,
|
|
discount: roomRate.memberRate
|
|
? roomRate.publicRate.localPrice.pricePerStay -
|
|
roomRate.memberRate.localPrice.pricePerStay
|
|
: 0,
|
|
analyticsrateCode: getAnalyticsRateCode(roomRate.publicRate.rateCode),
|
|
ancillaries: breakfastAncillary ? [breakfastAncillary] : [],
|
|
}
|
|
|
|
return data
|
|
}, [
|
|
bedType,
|
|
breakfast,
|
|
totalPrice,
|
|
roomPrice,
|
|
roomRate,
|
|
roomFeatures,
|
|
initialHotelsTrackingData,
|
|
cancellationRule,
|
|
selectedRoom.roomType,
|
|
])
|
|
|
|
useEffect(() => {
|
|
if (previousPathname.current !== pathName) {
|
|
trackPageView({
|
|
event: "pageView",
|
|
pageInfo: pageObject,
|
|
userInfo: userTrackingData,
|
|
hotelInfo: hotelDetailsData,
|
|
})
|
|
}
|
|
previousPathname.current = pathName // Update for next render
|
|
}, [userTrackingData, pageObject, hotelDetailsData, pathName])
|
|
|
|
return null
|
|
}
|