From c41dea411851fe9ef68c77558c3c99d6cf68fa4e Mon Sep 17 00:00:00 2001 From: Bianca Widstam Date: Wed, 9 Apr 2025 06:26:19 +0000 Subject: [PATCH] Merged in feat/SW-1414-guarantee-enter-details-tracking (pull request #1744) Feat/SW-1414 guarantee enter details tracking * feat(SW-1414): add tracking for gla enter details * feat(SW-1414): add tracking for gla * feat(SW-1414): add tracking for gla in enter details * feat(SW-1414): fix pr comments * feat(SW-1414): fix pr comment client only * feat(SW-1414): fix pr comments * feat(SW-1414): add tracking on load Approved-by: Christian Andolf --- .../BookingConfirmation/Tracking/tracking.ts | 21 ++++++ .../PaymentCallback/HandleErrorCallback.tsx | 58 +++++++++++++--- .../PaymentCallback/HandleSuccessCallback.tsx | 13 ++++ .../Payment/PaymentCallback/helpers.ts | 24 +++++++ .../EnterDetails/Payment/PaymentClient.tsx | 69 ++++++++++++++----- apps/scandic-web/types/components/tracking.ts | 4 ++ apps/scandic-web/utils/tracking/myStay.ts | 2 - 7 files changed, 160 insertions(+), 31 deletions(-) create mode 100644 apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentCallback/helpers.ts diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Tracking/tracking.ts b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Tracking/tracking.ts index 4cdeece7b..0c5a9cdba 100644 --- a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Tracking/tracking.ts +++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Tracking/tracking.ts @@ -1,5 +1,7 @@ import { differenceInCalendarDays, format, isWeekend } from "date-fns" +import { CancellationRuleEnum } from "@/constants/booking" + import { getSpecialRoomType } from "@/utils/specialRoomType" import { invertedBedTypeMap } from "../../utils" @@ -77,6 +79,9 @@ export function getTracking( const noOfAdults = rooms.map((r) => r.adults).join(",") const noOfChildren = rooms.map((r) => r.childrenAges?.length ?? 0).join(",") const noOfRooms = rooms.length + const isFlexBooking = + booking.rateDefinition.cancellationRule === + CancellationRuleEnum.CancellableBefore6PM const hotelsTrackingData: TrackingSDKHotelInfo = { ageOfChildren: rooms.map((r) => r.childrenAges?.join(",") ?? "-").join("|"), @@ -144,10 +149,26 @@ export function getTracking( .map((room) => getSpecialRoomType(room.packages)) .join(","), totalPrice: rooms.map((r) => r.totalPrice).join(","), + lateArrivalGuarantee: booking.rateDefinition.mustBeGuaranteed + ? "mandatory" + : isFlexBooking + ? booking.guaranteeInfo + ? "yes" + : "no" + : "na", + guaranteedProduct: booking.guaranteeInfo && isFlexBooking ? "room" : "na", } const paymentInfo: TrackingSDKPaymentInfo = { paymentStatus: "confirmed", + status: + booking.guaranteeInfo && isFlexBooking + ? "glacardsaveconfirmed" + : undefined, + type: + booking.guaranteeInfo && isFlexBooking + ? booking.guaranteeInfo.cardType + : undefined, } return { diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentCallback/HandleErrorCallback.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentCallback/HandleErrorCallback.tsx index f9be4f179..6fdea77f2 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentCallback/HandleErrorCallback.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentCallback/HandleErrorCallback.tsx @@ -8,8 +8,11 @@ import { detailsStorageName } from "@/stores/enter-details" import LoadingSpinner from "@/components/LoadingSpinner" import { trackPaymentEvent } from "@/utils/tracking" +import { trackEvent } from "@/utils/tracking/base" import { convertObjToSearchParams } from "@/utils/url" +import { clearGlaSessionStorage, readGlaFromSessionStorage } from "./helpers" + import type { PersistedState } from "@/types/stores/enter-details" export default function HandleErrorCallback({ @@ -35,21 +38,54 @@ export default function HandleErrorCallback({ searchObject ) + const lateArrivalGuarantee = readGlaFromSessionStorage() + if (status === PaymentCallbackStatusEnum.Cancel) { - trackPaymentEvent({ - event: "paymentCancel", - hotelId: detailsStorage.booking.hotelId, - status: "cancelled", - }) + if (lateArrivalGuarantee) { + trackEvent({ + event: "glaCardSaveCancelled", + hotelInfo: { + hotelId: detailsStorage.booking.hotelId, + lateArrivalGuarantee, + guaranteedProduct: "room", + }, + paymentInfo: { + hotelId: detailsStorage.booking.hotelId, + status: "glacardsavecancelled", + }, + }) + } else { + trackPaymentEvent({ + event: "paymentCancel", + hotelId: detailsStorage.booking.hotelId, + status: "cancelled", + }) + } } if (status === PaymentCallbackStatusEnum.Error) { - trackPaymentEvent({ - event: "paymentFail", - hotelId: detailsStorage.booking.hotelId, - errorMessage, - status: "failed", - }) + if (lateArrivalGuarantee) { + trackEvent({ + event: "glaCardSaveFailed", + hotelInfo: { + hotelId: detailsStorage.booking.hotelId, + lateArrivalGuarantee, + guaranteedProduct: "room", + }, + paymentInfo: { + hotelId: detailsStorage.booking.hotelId, + status: "glacardsavefailed", + }, + }) + } else { + trackPaymentEvent({ + event: "paymentFail", + hotelId: detailsStorage.booking.hotelId, + errorMessage, + status: "failed", + }) + } } + clearGlaSessionStorage() if (searchParams.size > 0) { router.replace(`${returnUrl}?${searchParams.toString()}`) diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentCallback/HandleSuccessCallback.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentCallback/HandleSuccessCallback.tsx index 1d4f03aea..eef8e2dc7 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentCallback/HandleSuccessCallback.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentCallback/HandleSuccessCallback.tsx @@ -7,7 +7,9 @@ import { BookingStatusEnum, MEMBERSHIP_FAILED_ERROR } from "@/constants/booking" import LoadingSpinner from "@/components/LoadingSpinner" import { useHandleBookingStatus } from "@/hooks/booking/useHandleBookingStatus" +import { trackEvent } from "@/utils/tracking/base" +import { clearGlaSessionStorage, readGlaFromSessionStorage } from "./helpers" import TimeoutSpinner from "./TimeoutSpinner" const validBookingStatuses = [ @@ -48,6 +50,17 @@ export default function HandleSuccessCallback({ bookingStatus.reservationStatus as BookingStatusEnum ) ) { + const lateArrivalGuarantee = readGlaFromSessionStorage() + if (lateArrivalGuarantee) { + trackEvent({ + event: "guaranteeBookingSuccess", + hotelInfo: { + lateArrivalGuarantee, + guaranteedProduct: "room", + }, + }) + clearGlaSessionStorage() + } // a successful booking can still have membership errors const membershipFailedError = bookingStatus.errors.find( (e) => e.errorCode === MEMBERSHIP_FAILED_ERROR diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentCallback/helpers.ts b/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentCallback/helpers.ts new file mode 100644 index 000000000..55f98882b --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentCallback/helpers.ts @@ -0,0 +1,24 @@ +import "client-only" + +export const glaStorageName = "gla-storage" + +export function readGlaFromSessionStorage(): string | null { + try { + return sessionStorage.getItem(glaStorageName) + } catch (error) { + console.error("Error reading from session storage:", error) + return null + } +} + +export function writeGlaToSessionStorage(lateArrivalGuarantee: string) { + try { + sessionStorage.setItem(glaStorageName, lateArrivalGuarantee) + } catch (error) { + console.error("Error writing to session storage:", error) + } +} + +export function clearGlaSessionStorage() { + sessionStorage.removeItem(glaStorageName) +} diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentClient.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentClient.tsx index 974d969d8..9ca2429b6 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentClient.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentClient.tsx @@ -30,10 +30,13 @@ import { useAvailablePaymentOptions } from "@/hooks/booking/useAvailablePaymentO import { useHandleBookingStatus } from "@/hooks/booking/useHandleBookingStatus" import useLang from "@/hooks/useLang" import { trackPaymentEvent } from "@/utils/tracking" +import { trackEvent } from "@/utils/tracking/base" +import { trackGlaSaveCardAttempt } from "@/utils/tracking/myStay" import { bedTypeMap } from "../../utils" import ConfirmBooking, { ConfirmBookingRedemption } from "../Confirm" import PriceChangeDialog from "../PriceChangeDialog" +import { writeGlaToSessionStorage } from "./PaymentCallback/helpers" import GuaranteeDetails from "./GuaranteeDetails" import { hasFlexibleRate, hasPrepaidRate, isPaymentMethodEnum } from "./helpers" import MixedRatePaymentBreakdown from "./MixedRatePaymentBreakdown" @@ -194,21 +197,45 @@ export default function PaymentClient({ const currentPaymentMethod = methods.getValues("paymentMethod") const smsEnable = methods.getValues("smsConfirmation") + const guarantee = methods.getValues("guarantee") const isSavedCreditCard = savedCreditCards?.some( (card) => card.id === currentPaymentMethod ) - trackPaymentEvent({ - event: "paymentFail", - hotelId, - method: currentPaymentMethod, - isSavedCreditCard, - smsEnable, - errorMessage, - status: "failed", - }) + if (guarantee || (bookingMustBeGuaranteed && hasOnlyFlexRates)) { + const lateArrivalGuarantee = guarantee ? "yes" : "mandatory" + trackEvent({ + event: "glaCardSaveFailed", + hotelInfo: { + hotelId, + lateArrivalGuarantee, + guaranteedProduct: "room", + }, + paymentInfo: { + isSavedCreditCard, + hotelId, + status: "glacardsavefailed", + }, + }) + } else { + trackPaymentEvent({ + event: "paymentFail", + hotelId, + method: currentPaymentMethod, + isSavedCreditCard, + smsEnable, + errorMessage, + status: "failed", + }) + } }, - [methods, savedCreditCards, hotelId] + [ + methods, + savedCreditCards, + hotelId, + bookingMustBeGuaranteed, + hasOnlyFlexRates, + ] ) useEffect(() => { @@ -273,14 +300,20 @@ export default function PaymentClient({ } : undefined - trackPaymentEvent({ - event: "paymentAttemptStart", - hotelId, - method: paymentMethod, - isSavedCreditCard: !!savedCreditCard, - smsEnable: data.smsConfirmation, - status: "attempt", - }) + if (guarantee || (bookingMustBeGuaranteed && hasOnlyFlexRates)) { + const lateArrivalGuarantee = guarantee ? "yes" : "mandatory" + writeGlaToSessionStorage(lateArrivalGuarantee) + trackGlaSaveCardAttempt(hotelId, savedCreditCard, lateArrivalGuarantee) + } else { + trackPaymentEvent({ + event: "paymentAttemptStart", + hotelId, + method: paymentMethod, + isSavedCreditCard: !!savedCreditCard, + smsEnable: data.smsConfirmation, + status: "attempt", + }) + } const payload = { checkInDate: fromDate, diff --git a/apps/scandic-web/types/components/tracking.ts b/apps/scandic-web/types/components/tracking.ts index 10a97a766..418df9b69 100644 --- a/apps/scandic-web/types/components/tracking.ts +++ b/apps/scandic-web/types/components/tracking.ts @@ -93,6 +93,8 @@ export type TrackingSDKHotelInfo = { searchType?: "destination" | "hotel" specialRoomType?: string // allergy room, pet-friendly, accesibillity room totalPrice?: number | string + lateArrivalGuarantee?: string + guaranteedProduct?: string } export type Ancillary = { @@ -114,6 +116,8 @@ export type TrackingSDKPaymentInfo = { isCreditCard?: boolean paymentStatus?: "confirmed" paymentType?: string + type?: string + status?: string } export type TrackingSDKProps = { diff --git a/apps/scandic-web/utils/tracking/myStay.ts b/apps/scandic-web/utils/tracking/myStay.ts index 70e0af110..7427e1f11 100644 --- a/apps/scandic-web/utils/tracking/myStay.ts +++ b/apps/scandic-web/utils/tracking/myStay.ts @@ -38,7 +38,6 @@ export function trackGlaSaveCardAttempt( guaranteedProduct: "room", }, paymentInfo: { - isSavedCreditCard: !!savedCreditCard, status: "glacardsaveattempt", type: savedCreditCard?.cardType, }, @@ -58,7 +57,6 @@ export function trackGlaAncillaryAttempt( trackEvent({ event: "GuaranteeAttemptAncillary", paymentInfo: { - isSavedCreditCard: !!savedCreditCard, status: "glacardsaveattempt", type: savedCreditCard?.cardType, },