diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx index d54d0ca9a..d77143664 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx @@ -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 diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/enterDetailsTracking.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/enterDetailsTracking.tsx index 0826b7efb..278efc742 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/enterDetailsTracking.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/enterDetailsTracking.tsx @@ -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(false) const previousPathname = useRef(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]) diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/page.tsx index 953c60d5b..afcec344d 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/step/page.tsx @@ -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} /> - - - ) } diff --git a/components/HotelReservation/BookingConfirmation/index.tsx b/components/HotelReservation/BookingConfirmation/index.tsx index a1d63e84a..de0c1d1fe 100644 --- a/components/HotelReservation/BookingConfirmation/index.tsx +++ b/components/HotelReservation/BookingConfirmation/index.tsx @@ -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 = { diff --git a/components/HotelReservation/SelectRate/Rooms/index.tsx b/components/HotelReservation/SelectRate/Rooms/index.tsx index f879c1862..7f72ce6d4 100644 --- a/components/HotelReservation/SelectRate/Rooms/index.tsx +++ b/components/HotelReservation/SelectRate/Rooms/index.tsx @@ -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 (
) } diff --git a/i18n/dictionaries/da.json b/i18n/dictionaries/da.json index e613a7841..b85ca72b2 100644 --- a/i18n/dictionaries/da.json +++ b/i18n/dictionaries/da.json @@ -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 Terms and Conditions for Scandic Friends I understand that my personal data will be processed in accordance with Scandic's Privacy Policy.": "Ved at acceptere vilkårene og betingelserne for Scandic Friends, forstår jeg, at mine personlige oplysninger vil blive behandlet i overensstemmelse med Scandics privatlivspolitik.", diff --git a/i18n/dictionaries/de.json b/i18n/dictionaries/de.json index 5cffa6ec0..09c9e0210 100644 --- a/i18n/dictionaries/de.json +++ b/i18n/dictionaries/de.json @@ -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 Terms and Conditions for Scandic Friends I understand that my personal data will be processed in accordance with Scandic's Privacy Policy.": "Mit der Annahme der Allgemeinen Geschäftsbedingungen für Scandic Friends erkläre ich mich damit einverstanden, dass meine persönlichen Daten in Übereinstimmung mit der Datenschutzrichtlinie von Scandic verarbeitet werden.", "By paying with any of the payment methods available, I accept the terms for this booking and the general Terms & Conditions, and understand that Scandic will process my personal data for this booking in accordance with Scandic's Privacy policy. 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 Geschäftsbedingungen und verstehe, dass Scandic meine personenbezogenen Daten im Zusammenhang mit dieser Buchung gemäß der Scandic Datenschutzrichtlinie verarbeitet. Ich akzeptiere, dass Scandic während meines Aufenthalts eine gültige Kreditkarte für eventuelle Rückerstattungen benötigt.", diff --git a/i18n/dictionaries/en.json b/i18n/dictionaries/en.json index 3f161a249..b3d0e24d9 100644 --- a/i18n/dictionaries/en.json +++ b/i18n/dictionaries/en.json @@ -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 Terms and Conditions for Scandic Friends I understand that my personal data will be processed in accordance with Scandic's Privacy Policy.": "By accepting the Terms and Conditions for Scandic Friends I understand that my personal data will be processed in accordance with Scandic's Privacy Policy.", diff --git a/i18n/dictionaries/fi.json b/i18n/dictionaries/fi.json index 502120436..266e969d5 100644 --- a/i18n/dictionaries/fi.json +++ b/i18n/dictionaries/fi.json @@ -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 Terms and Conditions for Scandic Friends I understand that my personal data will be processed in accordance with Scandic's Privacy Policy.": "Kyllä, hyväksyn Scandic Friends -jäsenyyttä koskevat ehdot ja ymmärrän, että Scandic käsittelee henkilötietojani Scandicin Tietosuojaselosteen mukaisesti.", diff --git a/i18n/dictionaries/no.json b/i18n/dictionaries/no.json index 7111837a9..38f70c947 100644 --- a/i18n/dictionaries/no.json +++ b/i18n/dictionaries/no.json @@ -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 Terms and Conditions for Scandic Friends I understand that my personal data will be processed in accordance with Scandic's Privacy Policy.": "Ved å akseptere vilkårene og betingelsene for Scandic Friends, er jeg inneforstått med at mine personopplysninger vil bli behandlet i samsvar med Scandics personvernpolicy.", diff --git a/i18n/dictionaries/sv.json b/i18n/dictionaries/sv.json index 4e2c42ac7..5ecd2d12d 100644 --- a/i18n/dictionaries/sv.json +++ b/i18n/dictionaries/sv.json @@ -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 Terms and Conditions for Scandic Friends I understand that my personal data will be processed in accordance with Scandic's Privacy Policy.": "Genom att acceptera villkoren för Scandic Friends förstår jag att mina personuppgifter kommer att behandlas i enlighet med Scandics Integritetspolicy.", diff --git a/stores/sidepeek.ts b/stores/sidepeek.ts index 9912617ac..8c76a42b0 100644 --- a/stores/sidepeek.ts +++ b/stores/sidepeek.ts @@ -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((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 }), })) diff --git a/types/components/tracking.ts b/types/components/tracking.ts index e3b052f8c..06aa0ed2a 100644 --- a/types/components/tracking.ts +++ b/types/components/tracking.ts @@ -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 // ,roomtype:value>,bed: 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 = { diff --git a/utils/tracking.ts b/utils/tracking.ts index 5d83145ad..d04fb94cc 100644 --- a/utils/tracking.ts +++ b/utils/tracking.ts @@ -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)