Merged in feat/enter-details-tracking (pull request #1185)

Feat/enter details tracking

* feat: fixed bug in enter details tracking

* Sidepeek events, lowestroomPrice and analyticsRateCode

* Cleanup and fixed bug

* Fixed analyticsratecode

* Merge master

* merge master

* Removed console logs

* Added ancillaries tracking to enter details

* Added ancillary on confirmation page

* Removed console log

* Merge branch 'master' into feat/enter-details-tracking

* Refactor searchparams

* Hard code values for breakfast ancillary


Approved-by: Joakim Jäderberg
This commit is contained in:
Linus Flood
2025-01-17 07:42:44 +00:00
parent 33f0696c47
commit 69b69af03c
15 changed files with 187 additions and 79 deletions

View File

@@ -75,7 +75,6 @@ export default async function SelectRatePage({
country: hotelData?.data?.attributes.address.country,
hotelID: hotel?.id,
region: hotelData?.data?.attributes.address.city,
//lowestRoomPrice:
}
const hotelId = +hotel.id

View File

@@ -9,6 +9,7 @@ import { createSDKPageObject, pushToDataLayer } from "@/utils/tracking"
import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
import {
type Ancillary,
TrackingChannelEnum,
type TrackingSDKHotelInfo,
type TrackingSDKPageData,
@@ -35,21 +36,11 @@ export default function EnterDetailsTracking(props: Props) {
cancellationRule,
} = props
const {
currentStep,
bedType,
breakfast,
totalPrice,
roomPrice,
roomRate,
packages,
} = useEnterDetailsStore((state) => state)
const { bedType, breakfast, totalPrice, roomPrice, roomRate, packages } =
useEnterDetailsStore((state) => state)
const pathName = usePathname()
const sessionId = useSessionId()
// We need this check to differentiate hard vs soft navigations
// This is not because of StrictMode
const hasRunInitial = useRef<boolean>(false)
const previousPathname = useRef<string | null>(null)
const getSpecialRoomType = (packages: Packages | null) => {
@@ -77,34 +68,61 @@ export default function EnterDetailsTracking(props: Props) {
}
}
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: currentStep,
pageId: stepByPathname,
domainLanguage: lang,
channel: TrackingChannelEnum["hotelreservation"],
pageName: `hotelreservation|${currentStep}`,
siteSections: `hotelreservation|${currentStep}`,
pageType: currentStep,
pageName: `hotelreservation|${stepByPathname}`,
siteSections: `hotelreservation|${stepByPathname}`,
pageType: stepByPathname,
siteVersion: "new-web",
}
const trackingData = {
...pageTrackingData,
sessionId,
pathName,
sessionId,
pageLoadTime: 0, // Yes, this is instant
}
const pageObject = createSDKPageObject(trackingData)
return pageObject
}, [currentStep, lang, pathName, sessionId])
}, [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: rate?.rateType,
rateCodeType: roomRate.publicRate.rateType,
rateCodeName: rate?.rateCode,
rateCodeCancellationRule: cancellationRule,
revenueCurrencyCode: totalPrice.local?.currency,
@@ -119,39 +137,32 @@ export default function EnterDetailsTracking(props: Props) {
? roomRate.publicRate.localPrice.pricePerStay -
roomRate.memberRate.localPrice.pricePerStay
: 0,
analyticsrateCode: getAnalyticsRateCode(roomRate.publicRate.rateCode),
ancillaries: breakfastAncillary ? [breakfastAncillary] : [],
}
return data
}, [
roomRate.memberRate,
roomRate.publicRate,
bedType,
breakfast,
totalPrice,
roomPrice,
roomRate,
packages,
initialHotelsTrackingData,
cancellationRule,
totalPrice.local?.currency,
totalPrice.local?.price,
breakfast,
packages,
selectedRoom.roomType,
bedType?.description,
bedType?.roomTypeCode,
roomPrice.perStay.local.price,
])
useEffect(() => {
if (!hasRunInitial.current) {
hasRunInitial.current = true
previousPathname.current = pathName // Set initial path to compare later
return
if (previousPathname.current !== pathName) {
pushToDataLayer({
event: "pageView",
pageInfo: pageObject,
userInfo: userTrackingData,
hotelInfo: hotelDetailsData,
})
}
//if (previousPathname.current !== pathName) {
pushToDataLayer({
event: "pageView",
pageInfo: pageObject,
userInfo: userTrackingData,
//hotelInfo: hotelDetailsData,
})
//}
previousPathname.current = pathName // Update for next render
}, [userTrackingData, pageObject, hotelDetailsData, pathName])

View File

@@ -162,16 +162,6 @@ export default async function StepPage({
const departureDate = new Date(toDate)
const hotelAttributes = hotelData?.data.attributes
const initialPageTrackingData: TrackingSDKPageData = {
pageId: searchParams.step,
domainLanguage: lang,
channel: TrackingChannelEnum["hotelreservation"],
pageName: `hotelreservation|${searchParams.step}`,
siteSections: `hotelreservation|${searchParams.step}`,
pageType: searchParams.step,
siteVersion: "new-web",
}
const initialHotelsTrackingData: TrackingSDKHotelInfo = {
searchTerm: searchParams.city,
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
@@ -297,12 +287,6 @@ export default async function StepPage({
cancellationRule={roomAvailability.cancellationText}
lang={lang}
/>
<Suspense fallback={null}>
<TrackingSDK
pageData={initialPageTrackingData}
hotelInfo={initialHotelsTrackingData}
/>
</Suspense>
</EnterDetailsProvider>
)
}

View File

@@ -16,6 +16,7 @@ import {
type TrackingSDKPageData,
type TrackingSDKPaymentInfo,
} from "@/types/components/tracking"
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
export default async function BookingConfirmation({
confirmationNumber,
@@ -27,6 +28,21 @@ export default async function BookingConfirmation({
const arrivalDate = new Date(booking.checkInDate)
const departureDate = new Date(booking.checkOutDate)
const breakfastPkgSelected = booking.packages.find(
(pkg) => pkg.code === BreakfastPackageEnum.REGULAR_BREAKFAST
)
const breakfastAncillary = breakfastPkgSelected && {
hotelid: hotel.operaId,
productName: "BreakfastAdult",
productCategory: "", // TODO: Add category
productId: breakfastPkgSelected.code ?? "",
productPrice: +breakfastPkgSelected.unitPrice,
productUnits: booking.adults,
productPoints: 0,
productType: "food",
}
const initialPageTrackingData: TrackingSDKPageData = {
pageId: "booking-confirmation",
domainLanguage: lang,
@@ -70,6 +86,7 @@ export default async function BookingConfirmation({
roomTypeCode: booking.roomTypeCode ?? undefined,
roomPrice: booking.roomPrice,
bnr: booking.confirmationNumber ?? undefined,
ancillaries: breakfastAncillary ? [breakfastAncillary] : [],
}
const paymentInfo: TrackingSDKPaymentInfo = {

View File

@@ -1,8 +1,11 @@
"use client"
import { useSearchParams } from "next/navigation"
import { useCallback, useEffect, useMemo, useState } from "react"
import { useIntl } from "react-intl"
import { trackLowestRoomPrice } from "@/utils/tracking"
import RoomFilter from "../RoomFilter"
import RoomSelection from "../RoomSelection"
import { filterDuplicateRoomTypesByLowestPrice } from "./utils"
@@ -28,6 +31,12 @@ export default function Rooms({
hotelType,
isUserLoggedIn,
}: SelectRateProps) {
const searchParams = useSearchParams()
const hotelId = searchParams.get("hotel")
const arrivalDate = searchParams.get("fromDate")
const departureDate = searchParams.get("toDate")
const intl = useIntl()
const visibleRooms: RoomConfiguration[] = useMemo(() => {
@@ -177,6 +186,32 @@ export default function Rooms({
setSelectedRate(undefined)
}, [rateSummary, selectedRate])
useEffect(() => {
const pricesWithCurrencies = rooms.roomConfigurations.flatMap((room) =>
room.products.map((product) => ({
price: product.productType.public.localPrice.pricePerNight,
currency: product.productType.public.localPrice.currency,
}))
)
const cheapestPrice = pricesWithCurrencies.reduce(
(minPrice, { price }) => Math.min(minPrice, price),
Infinity
)
const currency = pricesWithCurrencies.find(
({ price }) => price === cheapestPrice
)?.currency
trackLowestRoomPrice({
hotelId,
arrivalDate,
departureDate,
lowestPrice: cheapestPrice,
currency: currency,
})
}, [arrivalDate, departureDate, hotelId, rooms.roomConfigurations])
return (
<div className={styles.content}>
<RoomFilter

View File

@@ -27,8 +27,8 @@ export default async function TrackingSDK({
<RouterTransition
pageData={pageData}
userData={userTrackingData}
// hotelInfo={hotelInfo}
//paymentInfo={paymentInfo}
hotelInfo={hotelInfo}
paymentInfo={paymentInfo}
/>
)
}

View File

@@ -62,6 +62,8 @@
"Booking confirmation": "Booking bekræftelse",
"Booking number": "Bookingnummer",
"Breakfast": "Morgenmad",
"Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}": "Morgenmad ({totalAdults, plural, one {# voksen} other {# voksne}}) x {totalBreakfasts}",
"Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}": "Morgenmad ({totalChildren, plural, one {# barn} other {# børn}}) x {totalBreakfasts}",
"Breakfast buffet": "Morgenbuffet",
"Breakfast charge": "Morgenmadsgebyr",
"Breakfast deal can be purchased at the hotel.": "Morgenmad kan købes på hotellet.",
@@ -70,8 +72,6 @@
"Breakfast is included.": "Morgenmad er inkluderet.",
"Breakfast restaurant": "Breakfast restaurant",
"Breakfast selection in next step.": "Valg af morgenmad i næste trin.",
"Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}": "Morgenmad ({totalAdults, plural, one {# voksen} other {# voksne}}) x {totalBreakfasts}",
"Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}": "Morgenmad ({totalChildren, plural, one {# barn} other {# børn}}) x {totalBreakfasts}",
"Bus terminal": "Busstation",
"Business": "Forretning",
"By accepting the <termsAndConditionsLink>Terms and Conditions for Scandic Friends</termsAndConditionsLink> I understand that my personal data will be processed in accordance with <privacyPolicy>Scandic's Privacy Policy</privacyPolicy>.": "Ved at acceptere <termsAndConditionsLink>vilkårene og betingelserne for Scandic Friends</termsAndConditionsLink>, forstår jeg, at mine personlige oplysninger vil blive behandlet i overensstemmelse med <privacyPolicy>Scandics privatlivspolitik</privacyPolicy>.",

View File

@@ -62,6 +62,8 @@
"Booking confirmation": "Buchungsbestätigung",
"Booking number": "Buchungsnummer",
"Breakfast": "Frühstück",
"Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}": "Frühstück ({totalAdults, plural, one {# erwachsene} other {# erwachsene}}) x {totalBreakfasts}",
"Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}": "Frühstück ({totalChildren, plural, one {# kind} other {# kinder}}) x {totalBreakfasts}",
"Breakfast buffet": "Frühstücksbuffet",
"Breakfast charge": "Frühstücksgebühr",
"Breakfast deal can be purchased at the hotel.": "Frühstücksangebot kann im Hotel gekauft werden.",
@@ -70,8 +72,6 @@
"Breakfast is included.": "Frühstück ist inbegriffen.",
"Breakfast restaurant": "Breakfast restaurant",
"Breakfast selection in next step.": "Frühstücksauswahl in nächsten Schritt.",
"Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}": "Frühstück ({totalAdults, plural, one {# erwachsene} other {# erwachsene}}) x {totalBreakfasts}",
"Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}": "Frühstück ({totalChildren, plural, one {# kind} other {# kinder}}) x {totalBreakfasts}",
"Business": "Geschäft",
"By accepting the <termsAndConditionsLink>Terms and Conditions for Scandic Friends</termsAndConditionsLink> I understand that my personal data will be processed in accordance with <privacyPolicy>Scandic's Privacy Policy</privacyPolicy>.": "Mit der Annahme der <termsAndConditionsLink>Allgemeinen Geschäftsbedingungen für Scandic Friends</termsAndConditionsLink> erkläre ich mich damit einverstanden, dass meine persönlichen Daten in Übereinstimmung mit der <privacyPolicy>Datenschutzrichtlinie von Scandic verarbeitet werden</privacyPolicy>.",
"By paying with any of the payment methods available, I accept the terms for this booking and the general <termsAndConditionsLink>Terms & Conditions</termsAndConditionsLink>, and understand that Scandic will process my personal data for this booking in accordance with <privacyPolicyLink>Scandic's Privacy policy</privacyPolicyLink>. I also accept that Scandic require a valid credit card during my visit in case anything is left unpaid.": "Mit der Zahlung über eine der verfügbaren Zahlungsmethoden akzeptiere ich die Buchungsbedingungen und die allgemeinen <termsAndConditionsLink>Geschäftsbedingungen</termsAndConditionsLink> und verstehe, dass Scandic meine personenbezogenen Daten im Zusammenhang mit dieser Buchung gemäß der <privacyPolicyLink>Scandic Datenschutzrichtlinie</privacyPolicyLink> verarbeitet. Ich akzeptiere, dass Scandic während meines Aufenthalts eine gültige Kreditkarte für eventuelle Rückerstattungen benötigt.",

View File

@@ -65,6 +65,8 @@
"Booking confirmation": "Booking confirmation",
"Booking number": "Booking number",
"Breakfast": "Breakfast",
"Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}": "Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}",
"Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}": "Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}",
"Breakfast buffet": "Breakfast buffet",
"Breakfast charge": "Breakfast charge",
"Breakfast deal can be purchased at the hotel.": "Breakfast deal can be purchased at the hotel.",
@@ -73,8 +75,6 @@
"Breakfast is included.": "Breakfast is included.",
"Breakfast restaurant": "Breakfast restaurant",
"Breakfast selection in next step.": "Breakfast selection in next step.",
"Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}": "Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}",
"Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}": "Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}",
"Bus terminal": "Bus terminal",
"Business": "Business",
"By accepting the <termsAndConditionsLink>Terms and Conditions for Scandic Friends</termsAndConditionsLink> I understand that my personal data will be processed in accordance with <privacyPolicy>Scandic's Privacy Policy</privacyPolicy>.": "By accepting the <termsAndConditionsLink>Terms and Conditions for Scandic Friends</termsAndConditionsLink> I understand that my personal data will be processed in accordance with <privacyPolicy>Scandic's Privacy Policy</privacyPolicy>.",

View File

@@ -62,16 +62,16 @@
"Booking confirmation": "Varausvahvistus",
"Booking number": "Varausnumero",
"Breakfast": "Aamiainen",
"Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}": "Aamiainen ({totalAdults, plural, one {# aikuinen} other {# aikuiset}}) x {totalBreakfasts}",
"Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}": "Aamiainen ({totalChildren, plural, one {# lapsi} other {# lasta}}) x {totalBreakfasts}",
"Breakfast buffet": "Aamiaisbuffet",
"Breakfast charge": "Aamiaismaksu",
"Breakfast deal can be purchased at the hotel.": "Aamiaisdeali voidaan ostaa hotellissa.",
"Breakfast excluded": "Aamiainen ei sisälly",
"Breakfast included": "Aamiainen sisältyy",
"Breakfast is included.": "Aamiainen sisältyy.",
"Breakfast restaurant": "Breakfast restaurant",
"Breakfast selection in next step.": "Aamiaisvalinta seuraavassa vaiheessa.",
"Breakfast charge": "Aamiaismaksu",
"Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}": "Aamiainen ({totalAdults, plural, one {# aikuinen} other {# aikuiset}}) x {totalBreakfasts}",
"Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}": "Aamiainen ({totalChildren, plural, one {# lapsi} other {# lasta}}) x {totalBreakfasts}",
"Bus terminal": "Bussiasema",
"Business": "Business",
"By accepting the <termsAndConditionsLink>Terms and Conditions for Scandic Friends</termsAndConditionsLink> I understand that my personal data will be processed in accordance with <privacyPolicy>Scandic's Privacy Policy</privacyPolicy>.": "Kyllä, <termsAndConditionsLink>hyväksyn Scandic Friends -jäsenyyttä</termsAndConditionsLink> koskevat ehdot ja ymmärrän, että Scandic käsittelee henkilötietojani <privacyPolicy>Scandicin Tietosuojaselosteen mukaisesti</privacyPolicy>.",

View File

@@ -62,16 +62,16 @@
"Booking confirmation": "Bestillingsbekreftelse",
"Booking number": "Bestillingsnummer",
"Breakfast": "Frokost",
"Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}": "Frokost ({totalAdults, plural, one {# voksen} other {# voksne}}) x {totalBreakfasts}",
"Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}": "Frokost ({totalChildren, plural, one {# barn} other {# barn}}) x {totalBreakfasts}",
"Breakfast buffet": "Breakfast buffet",
"Breakfast charge": "Pris for frokost",
"Breakfast deal can be purchased at the hotel.": "Frokostdeal kan kjøpes på hotellet.",
"Breakfast excluded": "Frokost ekskludert",
"Breakfast included": "Frokost inkludert",
"Breakfast is included.": "Frokost er inkludert.",
"Breakfast restaurant": "Breakfast restaurant",
"Breakfast selection in next step.": "Frokostvalg i neste steg.",
"Breakfast charge": "Pris for frokost",
"Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}": "Frokost ({totalAdults, plural, one {# voksen} other {# voksne}}) x {totalBreakfasts}",
"Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}": "Frokost ({totalChildren, plural, one {# barn} other {# barn}}) x {totalBreakfasts}",
"Bus terminal": "Bussterminal",
"Business": "Forretnings",
"By accepting the <termsAndConditionsLink>Terms and Conditions for Scandic Friends</termsAndConditionsLink> I understand that my personal data will be processed in accordance with <privacyPolicy>Scandic's Privacy Policy</privacyPolicy>.": "Ved å akseptere <termsAndConditionsLink>vilkårene og betingelsene for Scandic Friends</termsAndConditionsLink>, er jeg inneforstått med at mine personopplysninger vil bli behandlet i samsvar med <privacyPolicy>Scandics personvernpolicy</privacyPolicy>.",

View File

@@ -62,16 +62,16 @@
"Booking confirmation": "Bokningsbekräftelse",
"Booking number": "Bokningsnummer",
"Breakfast": "Frukost",
"Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}": "Frukost ({totalAdults, plural, one {# vuxen} other {# vuxna}}) x {totalBreakfasts}",
"Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}": "Frukost ({totalChildren, plural, one {# barn} other {# barn}}) x {totalBreakfasts}",
"Breakfast buffet": "Frukostbuffé",
"Breakfast charge": "Frukostpris",
"Breakfast deal can be purchased at the hotel.": "Frukostdeal kan köpas på hotellet.",
"Breakfast excluded": "Frukost ingår ej",
"Breakfast included": "Frukost ingår",
"Breakfast is included.": "Frukost ingår.",
"Breakfast restaurant": "Breakfast restaurant",
"Breakfast selection in next step.": "Frukostval i nästa steg.",
"Breakfast charge": "Frukostpris",
"Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}": "Frukost ({totalAdults, plural, one {# vuxen} other {# vuxna}}) x {totalBreakfasts}",
"Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}": "Frukost ({totalChildren, plural, one {# barn} other {# barn}}) x {totalBreakfasts}",
"Bus terminal": "Bussterminal",
"Business": "Business",
"By accepting the <termsAndConditionsLink>Terms and Conditions for Scandic Friends</termsAndConditionsLink> I understand that my personal data will be processed in accordance with <privacyPolicy>Scandic's Privacy Policy</privacyPolicy>.": "Genom att acceptera <termsAndConditionsLink>villkoren för Scandic Friends</termsAndConditionsLink> förstår jag att mina personuppgifter kommer att behandlas i enlighet med <privacyPolicy>Scandics Integritetspolicy</privacyPolicy>.",

View File

@@ -1,6 +1,8 @@
import { create } from "zustand"
import { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek"
import { trackOpenSidePeekEvent } from "@/utils/tracking"
import type { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek"
interface SidePeekState {
activeSidePeek: SidePeekEnum | null
@@ -26,8 +28,10 @@ const useSidePeekStore = create<SidePeekState>((set) => ({
hotelId: null,
roomTypeCode: null,
showCTA: true,
openSidePeek: ({ key, hotelId, roomTypeCode, showCTA }) =>
set({ activeSidePeek: key, hotelId, roomTypeCode, showCTA }),
openSidePeek: ({ key, hotelId, roomTypeCode, showCTA }) => {
trackOpenSidePeekEvent(key, hotelId, window.location.pathname, roomTypeCode)
set({ activeSidePeek: key, hotelId, roomTypeCode, showCTA })
},
closeSidePeek: () =>
set({ activeSidePeek: null, hotelId: null, roomTypeCode: null }),
}))

View File

@@ -74,7 +74,7 @@ export type TrackingSDKHotelInfo = {
bedTypePosition?: number // Which position the bed type had in the list of available bed types
breakfastOption?: string // "no breakfast" or "breakfast buffet"
bnr?: string // Booking number
analyticsrateCode?: string // flex, save, change
analyticsrateCode?: "flex" | "change" | "save" | string
specialRoomType?: string // allergy room, pet-friendly, accesibillity room
//modifyValues?: string // <price:<value>,roomtype:value>,bed:<value,<breakfast:value>
country?: string // Country of the hotel
@@ -83,6 +83,18 @@ export type TrackingSDKHotelInfo = {
totalPrice?: number
lowestRoomPrice?: number
searchType?: "destination" | "hotel"
ancillaries?: Ancillary[]
}
export type Ancillary = {
productId: string
productUnits?: number
hotelid?: string
productPoints: number
productPrice: number
productType: string
productName: string
productCategory: string
}
export type TrackingSDKPaymentInfo = {
@@ -127,6 +139,14 @@ export type PaymentEvent =
| PaymentCancelEvent
| PaymentFailEvent
export type LowestRoomPriceEvent = {
hotelId: string | null
arrivalDate: string | null
departureDate: string | null
lowestPrice: number
currency?: string
}
// Old tracking setup types:
// TODO: Remove this when we delete "current site"
export type TrackingProps = {

View File

@@ -1,4 +1,6 @@
import type { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek"
import type {
LowestRoomPriceEvent,
PaymentEvent,
PaymentFailEvent,
TrackingPosition,
@@ -100,6 +102,26 @@ export function trackUpdatePaymentMethod(hotelId: string, method: string) {
pushToDataLayer(paymentSelectionEvent)
}
export function trackOpenSidePeekEvent(
sidePeek: SidePeekEnum | null,
hotelId: string,
pathName: string,
roomTypeCode?: string | null
) {
const openSidePeekEvent = {
event: "openSidePeek",
hotelInfo: {
hotelId: hotelId,
},
cta: {
name: sidePeek,
roomTypeCode,
pathName,
},
}
pushToDataLayer(openSidePeekEvent)
}
export function trackPaymentEvent(paymentEvent: PaymentEvent) {
const paymentAttempt = {
event: paymentEvent.event,
@@ -119,6 +141,22 @@ export function trackPaymentEvent(paymentEvent: PaymentEvent) {
pushToDataLayer(paymentAttempt)
}
export function trackLowestRoomPrice(event: LowestRoomPriceEvent) {
const lowestRoomPrice = {
event: "lowestRoomPrice",
hotelInfo: {
hotelId: event.hotelId,
arrivalDate: event.arrivalDate,
departureDate: event.departureDate,
},
price: {
lowestPrice: event.lowestPrice,
currency: event.currency,
},
}
pushToDataLayer(lowestRoomPrice)
}
export function pushToDataLayer(data: any) {
if (typeof window !== "undefined" && window.adobeDataLayer) {
window.adobeDataLayer.push(data)