Merged in feat/sw-3473-remove-tracking-context (pull request #2843)

feat(SW-3473): Rework booking-flow tracking provider

* Remove tracking context and import instead

* Remove unused file


Approved-by: Joakim Jäderberg
This commit is contained in:
Anton Gunnarsson
2025-09-22 13:08:10 +00:00
parent a7b19e8b14
commit 630e89c845
30 changed files with 77 additions and 382 deletions

View File

@@ -1,21 +1,8 @@
"use client" "use client"
import { BookingFlowContextProvider } from "@scandic-hotels/booking-flow/BookingFlowContextProvider" import { BookingFlowContextProvider } from "@scandic-hotels/booking-flow/BookingFlowContextProvider"
import { BookingFlowTrackingProvider } from "@scandic-hotels/booking-flow/BookingFlowTrackingProvider"
import { useIsUserLoggedIn } from "../hooks/useIsUserLoggedIn" import { useIsUserLoggedIn } from "../hooks/useIsUserLoggedIn"
import {
trackAccordionItemOpen,
trackBedSelection,
trackBookingSearchClick,
trackBreakfastSelection,
trackGenericEvent,
trackGlaSaveCardAttempt,
trackLoginClick,
trackOpenSidePeek,
trackPaymentEvent,
trackUpdatePaymentMethod,
} from "../utils/tracking"
import type { ReactNode } from "react" import type { ReactNode } from "react"
@@ -24,22 +11,7 @@ export function BookingFlowProviders({ children }: { children: ReactNode }) {
return ( return (
<BookingFlowContextProvider data={{ isLoggedIn }}> <BookingFlowContextProvider data={{ isLoggedIn }}>
<BookingFlowTrackingProvider {children}
trackingFunctions={{
trackBookingSearchClick,
trackAccordionItemOpen,
trackOpenSidePeek,
trackGenericEvent,
trackGlaSaveCardAttempt,
trackLoginClick,
trackPaymentEvent,
trackUpdatePaymentMethod,
trackBreakfastSelection,
trackBedSelection,
}}
>
{children}
</BookingFlowTrackingProvider>
</BookingFlowContextProvider> </BookingFlowContextProvider>
) )
} }

View File

@@ -1,152 +0,0 @@
"use client"
import type {
PaymentEvent,
PaymentFailEvent,
} from "@scandic-hotels/tracking/types"
import type { BreakfastPackages } from "@scandic-hotels/trpc/routers/hotels/output"
export function trackBookingSearchClick(
searchTerm: string,
searchType: "hotel" | "destination"
) {
console.warn("TODO: Implement trackBookingSearchClick", {
searchTerm,
searchType,
})
}
export function trackAccordionItemOpen(option: string) {
console.warn("TODO: Implement trackAccordionItemOpen", { option })
}
export function trackOpenSidePeek(input: {
name: string | null
hotelId: string
includePathname?: boolean
roomTypeCode?: string | null
}) {
console.warn("TODO: Implement trackOpenSidePeek", { input })
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function trackGenericEvent(data: any) {
console.warn("TODO: Implement trackGenericEvent", { data })
}
export function trackGlaSaveCardAttempt({
hotelId,
hasSavedCreditCard,
creditCardType,
lateArrivalGuarantee,
}: {
hotelId: string
hasSavedCreditCard: boolean
creditCardType?: string
lateArrivalGuarantee: "mandatory" | "yes" | "no" | "na"
}) {
console.warn("TODO: Implement trackGlaSaveCardAttempt", {
event: "glaCardSaveAttempt",
hotelInfo: {
hotelId,
lateArrivalGuarantee,
guaranteedProduct: "room",
},
paymentInfo: {
status: "glacardsaveattempt",
isSavedCreditCard: hasSavedCreditCard,
type: creditCardType,
},
})
}
export function trackLoginClick(
position:
| "top menu"
| "hamburger menu"
| "join scandic friends sidebar"
| "enter details"
| "my stay"
) {
console.warn("TODO: Implement trackLoginClick", {
event: "loginStart",
login: {
position,
action: "login start",
ctaName: "login",
},
})
}
export function trackPaymentEvent(paymentEvent: PaymentEvent) {
console.warn("TODO: Implement trackPaymentEvent", {
event: paymentEvent.event,
hotelInfo: {
hotelId: paymentEvent.hotelId,
},
paymentInfo: {
isSavedCard: paymentEvent.isSavedCreditCard,
status: paymentEvent.status,
type: paymentEvent.method,
smsEnable: paymentEvent.smsEnable,
errorMessage: isPaymentFailEvent(paymentEvent)
? paymentEvent.errorMessage
: undefined,
},
})
}
export function trackUpdatePaymentMethod({ method }: { method: string }) {
console.warn("TODO: Implement trackUpdatePaymentMethod", {
event: "paymentSelection",
hotelInfo: {
hotelId: "", // TODO: Needs to be verified with analytics if this should even be here
},
cta: {
name: method,
},
})
}
export function trackBreakfastSelection({
breakfastPackage,
hotelId,
units,
}: {
breakfastPackage: BreakfastPackages[number]
hotelId: string
units: number
}) {
console.warn("TODO: Implement trackBreakfastSelection", {
event: "breakfastSelection",
selection: {
name: "breakfast options selection click",
},
...(units > 0 && {
ancillaries: [
{
hotelId,
productCategory: "",
productId: breakfastPackage.code,
productUnits: units,
productPrice: breakfastPackage.localPrice.price * units,
productPoints: 0,
productType: "food",
productName: breakfastPackage.packageType,
},
],
}),
})
}
export function trackBedSelection(bedType: string) {
console.warn("TODO: Implement trackBedSelection", {
event: "bedSelection",
selection: {
name: "bed options selection click",
bedType: bedType,
},
})
}
function isPaymentFailEvent(event: PaymentEvent): event is PaymentFailEvent {
return "errorMessage" in event
}

View File

@@ -1,23 +1,8 @@
"use client" "use client"
import { BookingFlowContextProvider } from "@scandic-hotels/booking-flow/BookingFlowContextProvider" import { BookingFlowContextProvider } from "@scandic-hotels/booking-flow/BookingFlowContextProvider"
import { BookingFlowTrackingProvider } from "@scandic-hotels/booking-flow/BookingFlowTrackingProvider"
import { trackEvent } from "@scandic-hotels/tracking/base"
import { useIsUserLoggedIn } from "@/hooks/useIsUserLoggedIn" import { useIsUserLoggedIn } from "@/hooks/useIsUserLoggedIn"
import {
trackAccordionClick,
trackLoginClick,
trackOpenSidePeekEvent,
trackPaymentEvent,
trackUpdatePaymentMethod,
} from "@/utils/tracking"
import {
trackBedSelection,
trackBookingSearchClick,
trackBreakfastSelection,
} from "@/utils/tracking/booking"
import { trackGlaSaveCardAttempt } from "@/utils/tracking/myStay"
import type { ReactNode } from "react" import type { ReactNode } from "react"
@@ -26,22 +11,7 @@ export function BookingFlowProviders({ children }: { children: ReactNode }) {
return ( return (
<BookingFlowContextProvider data={{ isLoggedIn }}> <BookingFlowContextProvider data={{ isLoggedIn }}>
<BookingFlowTrackingProvider {children}
trackingFunctions={{
trackBookingSearchClick,
trackAccordionItemOpen: trackAccordionClick,
trackOpenSidePeek: trackOpenSidePeekEvent,
trackGenericEvent: trackEvent,
trackGlaSaveCardAttempt,
trackLoginClick,
trackPaymentEvent,
trackUpdatePaymentMethod,
trackBreakfastSelection,
trackBedSelection,
}}
>
{children}
</BookingFlowTrackingProvider>
</BookingFlowContextProvider> </BookingFlowContextProvider>
) )
} }

View File

@@ -19,6 +19,7 @@ import Link from "@scandic-hotels/design-system/Link"
import { LoadingSpinner } from "@scandic-hotels/design-system/LoadingSpinner" import { LoadingSpinner } from "@scandic-hotels/design-system/LoadingSpinner"
import { toast } from "@scandic-hotels/design-system/Toast" import { toast } from "@scandic-hotels/design-system/Toast"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { trackGlaSaveCardAttempt } from "@scandic-hotels/tracking/payment"
import { isWebview } from "@/constants/routes/webviews" import { isWebview } from "@/constants/routes/webviews"
import { env } from "@/env/client" import { env } from "@/env/client"
@@ -27,7 +28,6 @@ import { useMyStayStore } from "@/stores/my-stay"
import { useGuaranteeBooking } from "@/hooks/booking/useGuaranteeBooking" import { useGuaranteeBooking } from "@/hooks/booking/useGuaranteeBooking"
import useLang from "@/hooks/useLang" import useLang from "@/hooks/useLang"
import { trackUpdatePaymentMethod } from "@/utils/tracking" import { trackUpdatePaymentMethod } from "@/utils/tracking"
import { trackGlaSaveCardAttempt } from "@/utils/tracking/myStay"
import { type GuaranteeFormData, paymentSchema } from "./schema" import { type GuaranteeFormData, paymentSchema } from "./schema"

View File

@@ -8,6 +8,7 @@ import { useIntl } from "react-intl"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import SkeletonShimmer from "@scandic-hotels/design-system/SkeletonShimmer" import SkeletonShimmer from "@scandic-hotels/design-system/SkeletonShimmer"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { trackLanguageSwitchClick } from "@scandic-hotels/tracking/navigation"
import { trpc } from "@scandic-hotels/trpc/client" import { trpc } from "@scandic-hotels/trpc/client"
import { languages } from "@/constants/languages" import { languages } from "@/constants/languages"
@@ -16,7 +17,6 @@ import useDropdownStore from "@/stores/main-menu"
import useClickOutside from "@/hooks/useClickOutside" import useClickOutside from "@/hooks/useClickOutside"
import { useHandleKeyUp } from "@/hooks/useHandleKeyUp" import { useHandleKeyUp } from "@/hooks/useHandleKeyUp"
import useLang from "@/hooks/useLang" import useLang from "@/hooks/useLang"
import { trackLanguageSwitchClick } from "@/utils/tracking/navigation"
import LanguageSwitcherContainer from "./LanguageSwitcherContainer" import LanguageSwitcherContainer from "./LanguageSwitcherContainer"
import LanguageSwitcherContent from "./LanguageSwitcherContent" import LanguageSwitcherContent from "./LanguageSwitcherContent"

View File

@@ -1,11 +1,17 @@
export { trackAccordionClick, trackOpenSidePeekEvent } from "./componentEvents"
export { trackHotelMapClick, trackHotelTabClick } from "./hotelPage" export { trackHotelMapClick, trackHotelTabClick } from "./hotelPage"
export { trackCancelStay, trackMyStayPageLink } from "./myStay" export { trackCancelStay, trackMyStayPageLink } from "./myStay"
export { trackClick } from "@scandic-hotels/tracking/base"
export {
trackAccordionClick,
trackOpenSidePeekEvent,
} from "@scandic-hotels/tracking/componentEvents"
export { export {
trackFooterClick, trackFooterClick,
trackLoginClick, trackLoginClick,
trackSocialMediaClick, trackSocialMediaClick,
} from "./navigation" } from "@scandic-hotels/tracking/navigation"
export { trackPaymentEvent, trackUpdatePaymentMethod } from "./payment"
export { trackClick } from "@scandic-hotels/tracking/base"
export { trackPageViewStart } from "@scandic-hotels/tracking/pageview" export { trackPageViewStart } from "@scandic-hotels/tracking/pageview"
export {
trackPaymentEvent,
trackUpdatePaymentMethod,
} from "@scandic-hotels/tracking/payment"

View File

@@ -35,32 +35,6 @@ export function trackMyStayPageLink(ctaName: string) {
}) })
} }
export function trackGlaSaveCardAttempt({
hotelId,
hasSavedCreditCard,
creditCardType,
lateArrivalGuarantee,
}: {
hotelId: string
hasSavedCreditCard: boolean
creditCardType?: string
lateArrivalGuarantee: "mandatory" | "yes" | "no" | "na"
}) {
trackEvent({
event: "glaCardSaveAttempt",
hotelInfo: {
hotelId,
lateArrivalGuarantee,
guaranteedProduct: "room",
},
paymentInfo: {
status: "glacardsaveattempt",
isSavedCreditCard: hasSavedCreditCard,
type: creditCardType,
},
})
}
export function buildAncillariesTracking( export function buildAncillariesTracking(
packages: { packages: {
code: string code: string

View File

@@ -1,16 +0,0 @@
"use client"
import { TrackingContext, type TrackingFunctions } from "../trackingContext"
import type { ReactNode } from "react"
export function BookingFlowTrackingProvider(props: {
children: ReactNode
trackingFunctions: TrackingFunctions
}) {
return (
<TrackingContext value={props.trackingFunctions}>
{props.children}
</TrackingContext>
)
}

View File

@@ -10,6 +10,7 @@ import {
selectHotelMap, selectHotelMap,
selectRate, selectRate,
} from "@scandic-hotels/common/constants/routes/hotelReservation" } from "@scandic-hotels/common/constants/routes/hotelReservation"
import { trackBookingSearchClick } from "@scandic-hotels/tracking/booking"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
import useLang from "../../../hooks/useLang" import useLang from "../../../hooks/useLang"
@@ -17,7 +18,6 @@ import {
BookingCodeFilterEnum, BookingCodeFilterEnum,
useBookingCodeFilterStore, useBookingCodeFilterStore,
} from "../../../stores/bookingCode-filter" } from "../../../stores/bookingCode-filter"
import { useTrackingContext } from "../../../trackingContext"
import { serializeBookingSearchParams } from "../../../utils/url" import { serializeBookingSearchParams } from "../../../utils/url"
import FormContent, { BookingWidgetFormContentSkeleton } from "./FormContent" import FormContent, { BookingWidgetFormContentSkeleton } from "./FormContent"
import { bookingWidgetVariants } from "./variants" import { bookingWidgetVariants } from "./variants"
@@ -38,7 +38,6 @@ export default function Form({ type, onClose }: BookingWidgetFormProps) {
const pathname = usePathname() const pathname = usePathname()
const lang = useLang() const lang = useLang()
const [isPending, startTransition] = useTransition() const [isPending, startTransition] = useTransition()
const { trackBookingSearchClick } = useTrackingContext()
const setBookingCodeFilter = useBookingCodeFilterStore( const setBookingCodeFilter = useBookingCodeFilterStore(
(state) => state.setFilter (state) => state.setFilter
) )

View File

@@ -5,6 +5,7 @@ import { useCallback, useEffect, useState } from "react"
import { FormProvider, useForm } from "react-hook-form" import { FormProvider, useForm } from "react-hook-form"
import RadioCard from "@scandic-hotels/design-system/Form/RadioCard" import RadioCard from "@scandic-hotels/design-system/Form/RadioCard"
import { trackBedSelection } from "@scandic-hotels/tracking/booking"
import { import {
BedTypeEnum, BedTypeEnum,
type ExtraBedTypeEnum, type ExtraBedTypeEnum,
@@ -13,7 +14,6 @@ import {
import { useRoomContext } from "../../../contexts/EnterDetails/RoomContext" import { useRoomContext } from "../../../contexts/EnterDetails/RoomContext"
import { BED_TYPE_ICONS } from "../../../misc/bedTypeIcons" import { BED_TYPE_ICONS } from "../../../misc/bedTypeIcons"
import { useEnterDetailsStore } from "../../../stores/enter-details" import { useEnterDetailsStore } from "../../../stores/enter-details"
import { useTrackingContext } from "../../../trackingContext"
import { type BedTypeFormSchema, bedTypeFormSchema } from "./schema" import { type BedTypeFormSchema, bedTypeFormSchema } from "./schema"
import styles from "./bedOptions.module.css" import styles from "./bedOptions.module.css"
@@ -29,8 +29,6 @@ export default function BedType() {
const initialBedType = bedType?.roomTypeCode const initialBedType = bedType?.roomTypeCode
const [previousBedType, setPreviousBedType] = useState("") const [previousBedType, setPreviousBedType] = useState("")
const { trackBedSelection } = useTrackingContext()
const methods = useForm<BedTypeFormSchema>({ const methods = useForm<BedTypeFormSchema>({
criteriaMode: "all", criteriaMode: "all",
mode: "all", mode: "all",
@@ -55,7 +53,7 @@ export default function BedType() {
trackBedSelection(bedType.description) trackBedSelection(bedType.description)
} }
}, },
[bedTypes, updateBedType, trackBedSelection] [bedTypes, updateBedType]
) )
const selectedBedType = methods.watch("bedType") const selectedBedType = methods.watch("bedType")

View File

@@ -10,11 +10,11 @@ import Body from "@scandic-hotels/design-system/Body"
import RadioCard from "@scandic-hotels/design-system/Form/RadioCard" import RadioCard from "@scandic-hotels/design-system/Form/RadioCard"
import BreakfastBuffetIcon from "@scandic-hotels/design-system/Icons/BreakfastBuffetIcon" import BreakfastBuffetIcon from "@scandic-hotels/design-system/Icons/BreakfastBuffetIcon"
import NoBreakfastBuffetIcon from "@scandic-hotels/design-system/Icons/NoBreakfastBuffetIcon" import NoBreakfastBuffetIcon from "@scandic-hotels/design-system/Icons/NoBreakfastBuffetIcon"
import { trackBreakfastSelection } from "@scandic-hotels/tracking/booking"
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast" import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
import { useRoomContext } from "../../../contexts/EnterDetails/RoomContext" import { useRoomContext } from "../../../contexts/EnterDetails/RoomContext"
import { useEnterDetailsStore } from "../../../stores/enter-details" import { useEnterDetailsStore } from "../../../stores/enter-details"
import { useTrackingContext } from "../../../trackingContext"
import { type BreakfastFormSchema, breakfastFormSchema } from "./schema" import { type BreakfastFormSchema, breakfastFormSchema } from "./schema"
import styles from "./breakfast.module.css" import styles from "./breakfast.module.css"
@@ -28,8 +28,6 @@ export default function Breakfast() {
room, room,
} = useRoomContext() } = useRoomContext()
const { trackBreakfastSelection } = useTrackingContext()
const hasChildrenInRoom = !!room.childrenInRoom?.length const hasChildrenInRoom = !!room.childrenInRoom?.length
const totalPriceForNoBreakfast = 0 const totalPriceForNoBreakfast = 0
@@ -63,7 +61,7 @@ export default function Breakfast() {
breakfastOption: pkg ? "breakfast buffet" : "no breakfast", breakfastOption: pkg ? "breakfast buffet" : "no breakfast",
}) })
}, },
// eslint-disable-next-line react-hooks/exhaustive-deps
[packages, hotelId, room.adults, updateBreakfast] [packages, hotelId, room.adults, updateBreakfast]
) )

View File

@@ -18,8 +18,7 @@ import { PaymentOptionsGroup } from "@scandic-hotels/design-system/Form/PaymentO
import { SelectPaymentMethod } from "@scandic-hotels/design-system/Form/SelectPaymentMethod" import { SelectPaymentMethod } from "@scandic-hotels/design-system/Form/SelectPaymentMethod"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { trackUpdatePaymentMethod } from "@scandic-hotels/tracking/payment"
import { useTrackingContext } from "../../../../trackingContext"
import styles from "./guarantee.module.css" import styles from "./guarantee.module.css"
@@ -32,7 +31,6 @@ interface GuaranteeProps {
export default function Guarantee({ savedCreditCards }: GuaranteeProps) { export default function Guarantee({ savedCreditCards }: GuaranteeProps) {
const intl = useIntl() const intl = useIntl()
const guarantee = useWatch({ name: "guarantee" }) const guarantee = useWatch({ name: "guarantee" })
const { trackUpdatePaymentMethod } = useTrackingContext()
return ( return (
<div className={styles.guarantee}> <div className={styles.guarantee}>

View File

@@ -11,10 +11,10 @@ import Link from "@scandic-hotels/design-system/Link"
import { LoginButton } from "@scandic-hotels/design-system/LoginButton" import { LoginButton } from "@scandic-hotels/design-system/LoginButton"
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton" import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { trackLoginClick } from "@scandic-hotels/tracking/navigation"
import { useRoomContext } from "../../../../../contexts/EnterDetails/RoomContext" import { useRoomContext } from "../../../../../contexts/EnterDetails/RoomContext"
import useLang from "../../../../../hooks/useLang" import useLang from "../../../../../hooks/useLang"
import { useTrackingContext } from "../../../../../trackingContext"
import styles from "./joinScandicFriendsCard.module.css" import styles from "./joinScandicFriendsCard.module.css"
@@ -25,7 +25,6 @@ export default function JoinScandicFriendsCard({ name = "join" }: Props) {
const lang = useLang() const lang = useLang()
const intl = useIntl() const intl = useIntl()
const loginPathname = useLazyPathname({ includeSearchParams: true }) const loginPathname = useLazyPathname({ includeSearchParams: true })
const { trackLoginClick } = useTrackingContext()
const { const {
room, room,
actions: { updateJoin }, actions: { updateJoin },

View File

@@ -6,9 +6,9 @@ import { useEffect } from "react"
import { PaymentCallbackStatusEnum } from "@scandic-hotels/common/constants/paymentCallbackStatusEnum" import { PaymentCallbackStatusEnum } from "@scandic-hotels/common/constants/paymentCallbackStatusEnum"
import { LoadingSpinner } from "@scandic-hotels/design-system/LoadingSpinner" import { LoadingSpinner } from "@scandic-hotels/design-system/LoadingSpinner"
import { trackEvent } from "@scandic-hotels/tracking/base" import { trackEvent } from "@scandic-hotels/tracking/base"
import { trackPaymentEvent } from "@scandic-hotels/tracking/payment"
import { detailsStorageName } from "../../../../stores/enter-details" import { detailsStorageName } from "../../../../stores/enter-details"
import { useTrackingContext } from "../../../../trackingContext"
import { serializeBookingSearchParams } from "../../../../utils/url" import { serializeBookingSearchParams } from "../../../../utils/url"
import { import {
clearPaymentInfoSessionStorage, clearPaymentInfoSessionStorage,
@@ -30,7 +30,6 @@ export function HandleErrorCallback({
errorMessage?: string errorMessage?: string
}) { }) {
const router = useRouter() const router = useRouter()
const { trackPaymentEvent } = useTrackingContext()
useEffect(() => { useEffect(() => {
const bookingData = window.sessionStorage.getItem(detailsStorageName) const bookingData = window.sessionStorage.getItem(detailsStorageName)
@@ -106,7 +105,7 @@ export function HandleErrorCallback({
router.replace(`${returnUrl}?${searchParams.toString()}`) router.replace(`${returnUrl}?${searchParams.toString()}`)
} }
} }
}, [returnUrl, router, searchObject, status, errorMessage, trackPaymentEvent]) }, [returnUrl, router, searchObject, status, errorMessage])
return <LoadingSpinner fullPage /> return <LoadingSpinner fullPage />
} }

View File

@@ -26,6 +26,10 @@ import { PaymentOption } from "@scandic-hotels/design-system/Form/PaymentOption"
import { PaymentOptionsGroup } from "@scandic-hotels/design-system/Form/PaymentOptionsGroup" import { PaymentOptionsGroup } from "@scandic-hotels/design-system/Form/PaymentOptionsGroup"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { trackEvent } from "@scandic-hotels/tracking/base" import { trackEvent } from "@scandic-hotels/tracking/base"
import {
trackGlaSaveCardAttempt,
trackPaymentEvent,
} from "@scandic-hotels/tracking/payment"
import { trpc } from "@scandic-hotels/trpc/client" import { trpc } from "@scandic-hotels/trpc/client"
import { bedTypeMap } from "@scandic-hotels/trpc/constants/bedTypeMap" import { bedTypeMap } from "@scandic-hotels/trpc/constants/bedTypeMap"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
@@ -38,7 +42,6 @@ import { useHandleBookingStatus } from "../../../hooks/useHandleBookingStatus"
import { useIsLoggedIn } from "../../../hooks/useIsLoggedIn" import { useIsLoggedIn } from "../../../hooks/useIsLoggedIn"
import useLang from "../../../hooks/useLang" import useLang from "../../../hooks/useLang"
import { useEnterDetailsStore } from "../../../stores/enter-details" import { useEnterDetailsStore } from "../../../stores/enter-details"
import { useTrackingContext } from "../../../trackingContext"
import ConfirmBooking, { ConfirmBookingRedemption } from "../Confirm" import ConfirmBooking, { ConfirmBookingRedemption } from "../Confirm"
import PriceChangeDialog from "../PriceChangeDialog" import PriceChangeDialog from "../PriceChangeDialog"
import { writeGlaToSessionStorage } from "./PaymentCallback/helpers" import { writeGlaToSessionStorage } from "./PaymentCallback/helpers"
@@ -80,7 +83,6 @@ export default function PaymentClient({
const searchParams = useSearchParams() const searchParams = useSearchParams()
const isUserLoggedIn = useIsLoggedIn() const isUserLoggedIn = useIsLoggedIn()
const { getTopOffset } = useStickyPosition({}) const { getTopOffset } = useStickyPosition({})
const { trackPaymentEvent, trackGlaSaveCardAttempt } = useTrackingContext()
const [showBookingAlert, setShowBookingAlert] = useState(false) const [showBookingAlert, setShowBookingAlert] = useState(false)
@@ -265,7 +267,6 @@ export default function PaymentClient({
bookingMustBeGuaranteed, bookingMustBeGuaranteed,
hasOnlyFlexRates, hasOnlyFlexRates,
setIsSubmitting, setIsSubmitting,
trackPaymentEvent,
] ]
) )
@@ -504,8 +505,6 @@ export default function PaymentClient({
isUserLoggedIn, isUserLoggedIn,
getTopOffset, getTopOffset,
setIsSubmitting, setIsSubmitting,
trackGlaSaveCardAttempt,
trackPaymentEvent,
] ]
) )

View File

@@ -5,8 +5,8 @@ import AccordionItem from "@scandic-hotels/design-system/Accordion/AccordionItem
import ButtonLink from "@scandic-hotels/design-system/ButtonLink" import ButtonLink from "@scandic-hotels/design-system/ButtonLink"
import { IconName } from "@scandic-hotels/design-system/Icons/iconName" import { IconName } from "@scandic-hotels/design-system/Icons/iconName"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { trackAccordionClick } from "@scandic-hotels/tracking/componentEvents"
import { useTrackingContext } from "../../../trackingContext"
import AdditionalAmenities from "../../AdditionalAmenities" import AdditionalAmenities from "../../AdditionalAmenities"
import Contact from "../../Contact" import Contact from "../../Contact"
import BreakfastAccordionItem from "../../SidePeekAccordions/BreakfastAccordionItem" import BreakfastAccordionItem from "../../SidePeekAccordions/BreakfastAccordionItem"
@@ -82,7 +82,6 @@ function AccessibilityAccordionItem({
elevatorPitch, elevatorPitch,
}: AccessibilityAccordionItemProps) { }: AccessibilityAccordionItemProps) {
const intl = useIntl() const intl = useIntl()
const tracking = useTrackingContext()
if (!elevatorPitch) { if (!elevatorPitch) {
return null return null
@@ -96,7 +95,7 @@ function AccessibilityAccordionItem({
iconName={IconName.Accessibility} iconName={IconName.Accessibility}
className={styles.accordionItem} className={styles.accordionItem}
type="sidepeek" type="sidepeek"
onOpen={() => tracking.trackAccordionItemOpen("amenities:accessibility")} onOpen={() => trackAccordionClick("amenities:accessibility")}
> >
<div className={styles.accessibilityContent}> <div className={styles.accessibilityContent}>
<Typography variant="Body/Paragraph/mdRegular"> <Typography variant="Body/Paragraph/mdRegular">

View File

@@ -5,8 +5,8 @@ import { DialogTrigger } from "react-aria-components"
import { Button } from "@scandic-hotels/design-system/Button" import { Button } from "@scandic-hotels/design-system/Button"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import SidePeekSelfControlled from "@scandic-hotels/design-system/SidePeekSelfControlled" import SidePeekSelfControlled from "@scandic-hotels/design-system/SidePeekSelfControlled"
import { trackOpenSidePeekEvent } from "@scandic-hotels/tracking/componentEvents"
import { useTrackingContext } from "../../trackingContext"
import { HotelSidePeekContent } from "./HotelSidePeekContent" import { HotelSidePeekContent } from "./HotelSidePeekContent"
import type { import type {
@@ -58,7 +58,6 @@ export function HotelDetailsSidePeek({
wrapping = true, wrapping = true,
buttonVariant, buttonVariant,
}: HotelDetailsSidePeekProps) { }: HotelDetailsSidePeekProps) {
const tracking = useTrackingContext()
const buttonProps = buttonPropsMap[buttonVariant] const buttonProps = buttonPropsMap[buttonVariant]
return ( return (
@@ -67,7 +66,7 @@ export function HotelDetailsSidePeek({
{...buttonProps} {...buttonProps}
wrapping={wrapping} wrapping={wrapping}
onPress={() => onPress={() =>
tracking.trackOpenSidePeek({ trackOpenSidePeekEvent({
name: SidePeekEnum.hotelDetails, name: SidePeekEnum.hotelDetails,
hotelId: hotel.operaId, hotelId: hotel.operaId,
includePathname: true, includePathname: true,

View File

@@ -5,8 +5,8 @@ import { DialogTrigger } from "react-aria-components"
import { Button } from "@scandic-hotels/design-system/Button" import { Button } from "@scandic-hotels/design-system/Button"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import SidePeekSelfControlled from "@scandic-hotels/design-system/SidePeekSelfControlled" import SidePeekSelfControlled from "@scandic-hotels/design-system/SidePeekSelfControlled"
import { trackOpenSidePeekEvent } from "@scandic-hotels/tracking/componentEvents"
import { useTrackingContext } from "../../trackingContext"
import { RoomSidePeekContent } from "./RoomSidePeekContent" import { RoomSidePeekContent } from "./RoomSidePeekContent"
import type { Room } from "@scandic-hotels/trpc/types/hotel" import type { Room } from "@scandic-hotels/trpc/types/hotel"
@@ -53,7 +53,6 @@ export function RoomDetailsSidePeek({
wrapping = true, wrapping = true,
buttonVariant: variant = "primary", buttonVariant: variant = "primary",
}: RoomDetailsSidePeekProps) { }: RoomDetailsSidePeekProps) {
const tracking = useTrackingContext()
const buttonProps = buttonPropsMap[variant] const buttonProps = buttonPropsMap[variant]
return ( return (
@@ -62,7 +61,7 @@ export function RoomDetailsSidePeek({
{...buttonProps} {...buttonProps}
wrapping={wrapping} wrapping={wrapping}
onPress={() => onPress={() =>
tracking.trackOpenSidePeek({ trackOpenSidePeekEvent({
name: SidePeekEnum.roomDetails, name: SidePeekEnum.roomDetails,
hotelId, hotelId,
roomTypeCode, roomTypeCode,

View File

@@ -3,9 +3,10 @@
import { usePathname, useSearchParams } from "next/navigation" import { usePathname, useSearchParams } from "next/navigation"
import { useCallback, useEffect } from "react" import { useCallback, useEffect } from "react"
import { trackEvent } from "@scandic-hotels/tracking/base"
import useInitializeFiltersFromUrl from "../../../../hooks/useInitializeFiltersFromUrl" import useInitializeFiltersFromUrl from "../../../../hooks/useInitializeFiltersFromUrl"
import { useHotelFilterStore } from "../../../../stores/hotel-filters" import { useHotelFilterStore } from "../../../../stores/hotel-filters"
import { useTrackingContext } from "../../../../trackingContext"
import FilterContent from "../FilterContent" import FilterContent from "../FilterContent"
import type { CategorizedHotelFilters } from "../../../../types" import type { CategorizedHotelFilters } from "../../../../types"
@@ -16,7 +17,6 @@ type HotelFiltersProps = {
} }
export default function HotelFilter({ className, filters }: HotelFiltersProps) { export default function HotelFilter({ className, filters }: HotelFiltersProps) {
const tracking = useTrackingContext()
const searchParams = useSearchParams() const searchParams = useSearchParams()
const pathname = usePathname() const pathname = usePathname()
useInitializeFiltersFromUrl() useInitializeFiltersFromUrl()
@@ -44,18 +44,13 @@ export default function HotelFilter({ className, filters }: HotelFiltersProps) {
.map((id) => surroundingsMap.get(id)) .map((id) => surroundingsMap.get(id))
.join(",") .join(",")
tracking.trackGenericEvent({ trackEvent({
event: "filterUsed", event: "filterUsed",
filter: { filter: {
filtersUsed: `Filters values - hotelfacilities:${hotelFacilitiesFilter}|hotelsurroundings:${hotelSurroundingsFilter}`, filtersUsed: `Filters values - hotelfacilities:${hotelFacilitiesFilter}|hotelsurroundings:${hotelSurroundingsFilter}`,
}, },
}) })
}, [ }, [activeFilters, filters.facilityFilters, filters.surroundingsFilters])
tracking,
activeFilters,
filters.facilityFilters,
filters.surroundingsFilters,
])
// Update the URL when the filters changes // Update the URL when the filters changes
useEffect(() => { useEffect(() => {

View File

@@ -5,8 +5,7 @@ import { useCallback } from "react"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import DeprecatedSelect from "@scandic-hotels/design-system/DeprecatedSelect" import DeprecatedSelect from "@scandic-hotels/design-system/DeprecatedSelect"
import { trackEvent } from "@scandic-hotels/tracking/base"
import { useTrackingContext } from "../../../trackingContext"
const enum SortOrder { const enum SortOrder {
Distance = "distance", Distance = "distance",
@@ -27,7 +26,6 @@ type HotelSorterProps = {
} }
export default function HotelSorter({ discreet }: HotelSorterProps) { export default function HotelSorter({ discreet }: HotelSorterProps) {
const tracking = useTrackingContext()
const searchParams = useSearchParams() const searchParams = useSearchParams()
const pathname = usePathname() const pathname = usePathname()
const intl = useIntl() const intl = useIntl()
@@ -41,7 +39,7 @@ export default function HotelSorter({ discreet }: HotelSorterProps) {
const newSearchParams = new URLSearchParams(searchParams) const newSearchParams = new URLSearchParams(searchParams)
newSearchParams.set("sort", newSort) newSearchParams.set("sort", newSort)
tracking.trackGenericEvent({ trackEvent({
event: "sortOptionClick", event: "sortOptionClick",
filter: { filter: {
sortOptions: newSort, sortOptions: newSort,
@@ -53,7 +51,7 @@ export default function HotelSorter({ discreet }: HotelSorterProps) {
`${pathname}?${newSearchParams.toString()}` `${pathname}?${newSearchParams.toString()}`
) )
}, },
[tracking, pathname, searchParams] [pathname, searchParams]
) )
const sortItems: SortItem[] = [ const sortItems: SortItem[] = [
{ {

View File

@@ -17,6 +17,7 @@ import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import Link from "@scandic-hotels/design-system/Link" import Link from "@scandic-hotels/design-system/Link"
import { InteractiveMap } from "@scandic-hotels/design-system/Map/InteractiveMap" import { InteractiveMap } from "@scandic-hotels/design-system/Map/InteractiveMap"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { trackEvent } from "@scandic-hotels/tracking/base"
import { useIsLoggedIn } from "../../../../hooks/useIsLoggedIn" import { useIsLoggedIn } from "../../../../hooks/useIsLoggedIn"
import useLang from "../../../../hooks/useLang" import useLang from "../../../../hooks/useLang"
@@ -27,7 +28,6 @@ import {
} from "../../../../stores/bookingCode-filter" } from "../../../../stores/bookingCode-filter"
import { useHotelFilterStore } from "../../../../stores/hotel-filters" import { useHotelFilterStore } from "../../../../stores/hotel-filters"
import { useHotelsMapStore } from "../../../../stores/hotels-map" import { useHotelsMapStore } from "../../../../stores/hotels-map"
import { useTrackingContext } from "../../../../trackingContext"
import BookingCodeFilter from "../../../BookingCodeFilter" import BookingCodeFilter from "../../../BookingCodeFilter"
import { getHotelPins } from "../../../HotelCardDialogListing/utils" import { getHotelPins } from "../../../HotelCardDialogListing/utils"
import { RoomCardSkeleton } from "../../../RoomCardSkeleton/RoomCardSkeleton" import { RoomCardSkeleton } from "../../../RoomCardSkeleton/RoomCardSkeleton"
@@ -68,7 +68,6 @@ export function SelectHotelMapContent({
const intl = useIntl() const intl = useIntl()
const map = useMap() const map = useMap()
const isUserLoggedIn = useIsLoggedIn() const isUserLoggedIn = useIsLoggedIn()
const tracking = useTrackingContext()
const isAboveMobile = useMediaQuery("(min-width: 900px)") const isAboveMobile = useMediaQuery("(min-width: 900px)")
const [visibleHotels, setVisibleHotels] = useState<HotelResponse[]>([]) const [visibleHotels, setVisibleHotels] = useState<HotelResponse[]>([])
@@ -284,7 +283,7 @@ export function SelectHotelMapContent({
return return
} }
tracking.trackGenericEvent({ trackEvent({
event: "hotelClickMap", event: "hotelClickMap",
map: { map: {
action: "hotel click - map", action: "hotel click - map",
@@ -297,7 +296,7 @@ export function SelectHotelMapContent({
hotelMapStore.activate(args.hotelName) hotelMapStore.activate(args.hotelName)
}} }}
onClickHotel={(hotelId) => { onClickHotel={(hotelId) => {
tracking.trackGenericEvent({ trackEvent({
event: "hotelClickMap", event: "hotelClickMap",
map: { map: {
action: "hotel click - map", action: "hotel click - map",

View File

@@ -7,10 +7,9 @@ import AccordionItem from "@scandic-hotels/design-system/Accordion/AccordionItem
import { IconName } from "@scandic-hotels/design-system/Icons/iconName" import { IconName } from "@scandic-hotels/design-system/Icons/iconName"
import OpeningHours from "@scandic-hotels/design-system/OpeningHours" import OpeningHours from "@scandic-hotels/design-system/OpeningHours"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { trackAccordionClick } from "@scandic-hotels/tracking/componentEvents"
import { HotelTypeEnum } from "@scandic-hotels/trpc/enums/hotelType" import { HotelTypeEnum } from "@scandic-hotels/trpc/enums/hotelType"
import { useTrackingContext } from "../../trackingContext"
import styles from "./sidePeekAccordion.module.css" import styles from "./sidePeekAccordion.module.css"
import type { Restaurant } from "@scandic-hotels/trpc/types/hotel" import type { Restaurant } from "@scandic-hotels/trpc/types/hotel"
@@ -25,7 +24,6 @@ export default function BreakfastAccordionItem({
hotelType, hotelType,
}: BreakfastAccordionItemProps) { }: BreakfastAccordionItemProps) {
const intl = useIntl() const intl = useIntl()
const tracking = useTrackingContext()
const openingHours = restaurants const openingHours = restaurants
?.map((restaurant) => { ?.map((restaurant) => {
@@ -46,7 +44,7 @@ export default function BreakfastAccordionItem({
iconName={IconName.CoffeeAlt} iconName={IconName.CoffeeAlt}
type="sidepeek" type="sidepeek"
className={styles.accordionItem} className={styles.accordionItem}
onOpen={() => tracking.trackAccordionItemOpen("amenities:breakfast")} onOpen={() => trackAccordionClick("amenities:breakfast")}
> >
{openingHours ? ( {openingHours ? (
<OpeningHours <OpeningHours

View File

@@ -6,8 +6,7 @@ import AccordionItem from "@scandic-hotels/design-system/Accordion/AccordionItem
import { Divider } from "@scandic-hotels/design-system/Divider" import { Divider } from "@scandic-hotels/design-system/Divider"
import { IconName } from "@scandic-hotels/design-system/Icons/iconName" import { IconName } from "@scandic-hotels/design-system/Icons/iconName"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { trackAccordionClick } from "@scandic-hotels/tracking/componentEvents"
import { useTrackingContext } from "../../trackingContext"
import styles from "./sidePeekAccordion.module.css" import styles from "./sidePeekAccordion.module.css"
@@ -21,7 +20,6 @@ export default function CheckInCheckOutAccordionItem({
checkInData, checkInData,
}: CheckInCheckOutAccordionItemProps) { }: CheckInCheckOutAccordionItemProps) {
const intl = useIntl() const intl = useIntl()
const tracking = useTrackingContext()
const { checkInTime, checkOutTime } = checkInData const { checkInTime, checkOutTime } = checkInData
@@ -31,7 +29,7 @@ export default function CheckInCheckOutAccordionItem({
iconName={IconName.Business} iconName={IconName.Business}
type="sidepeek" type="sidepeek"
className={styles.accordionItem} className={styles.accordionItem}
onOpen={() => tracking.trackAccordionItemOpen("amenities:check-in")} onOpen={() => trackAccordionClick("amenities:check-in")}
> >
<div className={styles.checkInCheckOutContent}> <div className={styles.checkInCheckOutContent}>
<Typography variant="Title/Overline/sm"> <Typography variant="Title/Overline/sm">

View File

@@ -7,8 +7,7 @@ import ButtonLink from "@scandic-hotels/design-system/ButtonLink"
import { IconName } from "@scandic-hotels/design-system/Icons/iconName" import { IconName } from "@scandic-hotels/design-system/Icons/iconName"
import ParkingInformation from "@scandic-hotels/design-system/ParkingInformation" import ParkingInformation from "@scandic-hotels/design-system/ParkingInformation"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { trackAccordionClick } from "@scandic-hotels/tracking/componentEvents"
import { useTrackingContext } from "../../trackingContext"
import styles from "./sidePeekAccordion.module.css" import styles from "./sidePeekAccordion.module.css"
@@ -26,7 +25,6 @@ export default function ParkingAccordionItem({
parkingPageHref, parkingPageHref,
}: ParkingAccordionItemProps) { }: ParkingAccordionItemProps) {
const intl = useIntl() const intl = useIntl()
const tracking = useTrackingContext()
if (!parking.length && !elevatorPitch && !parkingPageHref) { if (!parking.length && !elevatorPitch && !parkingPageHref) {
return null return null
@@ -40,7 +38,7 @@ export default function ParkingAccordionItem({
iconName={IconName.Parking} iconName={IconName.Parking}
type="sidepeek" type="sidepeek"
className={styles.accordionItem} className={styles.accordionItem}
onOpen={() => tracking.trackAccordionItemOpen("amenities:parking")} onOpen={() => trackAccordionClick("amenities:parking")}
> >
<div className={styles.parkingContent}> <div className={styles.parkingContent}>
{elevatorPitch ? ( {elevatorPitch ? (

View File

@@ -1,57 +0,0 @@
"use client"
import { createContext, useContext } from "react"
import type {
PaymentEvent,
TrackingPosition,
} from "@scandic-hotels/tracking/types"
import type { BreakfastPackages } from "@scandic-hotels/trpc/routers/hotels/output"
export type TrackingFunctions = {
trackBookingSearchClick: (
searchTerm: string,
searchType: "hotel" | "destination"
) => void
trackAccordionItemOpen: (option: string) => void
trackOpenSidePeek: (input: {
name: string | null
hotelId: string
includePathname?: boolean
roomTypeCode?: string | null
}) => void
// eslint-disable-next-line @typescript-eslint/no-explicit-any
trackGenericEvent(data: any): void
trackLoginClick(position: TrackingPosition & (string & {})): void
trackPaymentEvent(payment: PaymentEvent): void
trackGlaSaveCardAttempt(args: {
hotelId: string
hasSavedCreditCard: boolean
creditCardType?: string
lateArrivalGuarantee: "mandatory" | "yes" | "no" | "na"
}): void
trackUpdatePaymentMethod(args: { method: string }): void
trackBreakfastSelection(args: {
breakfastPackage: BreakfastPackages[number]
hotelId: string
units: number
breakfastOption: string
}): void
trackBedSelection(bedType: string): void
}
export const TrackingContext = createContext<TrackingFunctions | undefined>(
undefined
)
export const useTrackingContext = (): TrackingFunctions => {
const context = useContext(TrackingContext)
if (!context) {
throw new Error(
"useTrackingContext must be used within a BookingFlowTrackingProvider. Did you forget to use the provider in the consuming app?"
)
}
return context
}

View File

@@ -13,7 +13,6 @@
"exports": { "exports": {
"./BookingFlowConfig": "./lib/bookingFlowConfig/bookingFlowConfig.tsx", "./BookingFlowConfig": "./lib/bookingFlowConfig/bookingFlowConfig.tsx",
"./BookingFlowContextProvider": "./lib/components/BookingFlowContextProvider.tsx", "./BookingFlowContextProvider": "./lib/components/BookingFlowContextProvider.tsx",
"./BookingFlowTrackingProvider": "./lib/components/BookingFlowTrackingProvider.tsx",
"./BookingWidget": "./lib/components/BookingWidget/index.tsx", "./BookingWidget": "./lib/components/BookingWidget/index.tsx",
"./BookingWidget/BookingWidgetForm/FormContent/Search": "./lib/components/BookingWidget/BookingWidgetForm/FormContent/Search/index.tsx", "./BookingWidget/BookingWidgetForm/FormContent/Search": "./lib/components/BookingWidget/BookingWidgetForm/FormContent/Search/index.tsx",
"./BookingWidget/FloatingBookingWidget": "./lib/components/BookingWidget/FloatingBookingWidget/index.tsx", "./BookingWidget/FloatingBookingWidget": "./lib/components/BookingWidget/FloatingBookingWidget/index.tsx",

View File

@@ -1,6 +1,6 @@
"use client" "use client"
import { trackEvent } from "@scandic-hotels/tracking/base" import { trackEvent } from "./base"
import type { BreakfastPackages } from "@scandic-hotels/trpc/routers/hotels/output" import type { BreakfastPackages } from "@scandic-hotels/trpc/routers/hotels/output"

View File

@@ -1,5 +1,5 @@
"use client" "use client"
import { trackEvent } from "@scandic-hotels/tracking/base" import { trackEvent } from "./base"
export function trackAccordionClick(option: string) { export function trackAccordionClick(option: string) {
trackEvent({ trackEvent({

View File

@@ -39,3 +39,29 @@ export function trackPaymentEvent(paymentEvent: PaymentEvent) {
} }
trackEvent(paymentAttempt) trackEvent(paymentAttempt)
} }
export function trackGlaSaveCardAttempt({
hotelId,
hasSavedCreditCard,
creditCardType,
lateArrivalGuarantee,
}: {
hotelId: string
hasSavedCreditCard: boolean
creditCardType?: string
lateArrivalGuarantee: "mandatory" | "yes" | "no" | "na"
}) {
trackEvent({
event: "glaCardSaveAttempt",
hotelInfo: {
hotelId,
lateArrivalGuarantee,
guaranteedProduct: "room",
},
paymentInfo: {
status: "glacardsaveattempt",
isSavedCreditCard: hasSavedCreditCard,
type: creditCardType,
},
})
}