diff --git a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(standard)/details/page.tsx b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(standard)/details/page.tsx index bb54b1c12..37311010a 100644 --- a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(standard)/details/page.tsx +++ b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(standard)/details/page.tsx @@ -100,7 +100,7 @@ export default async function DetailsPage({ booking, hotel, rooms, - !!breakfastPackages?.length, + !!breakfastPackages.length, searchParams.city, !!user, lang diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/BedType/index.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/BedType/index.tsx index 3671a297c..c0d06b40d 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/BedType/index.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/BedType/index.tsx @@ -12,6 +12,7 @@ import { import RadioCard from "@/components/TempDesignSystem/Form/RadioCard" import { useRoomContext } from "@/contexts/Details/Room" +import { trackBedSelection } from "@/utils/tracking" import { bedTypeFormSchema } from "./schema" @@ -47,18 +48,17 @@ export default function BedType() { roomTypeCode: matchingRoom.value, } updateBedType(bedType) + trackBedSelection(bedType.roomTypeCode) } }, [bedTypes, updateBedType] ) + const selectedBedType = methods.watch("bedType") + const handleSubmit = methods.handleSubmit useEffect(() => { - if (methods.formState.isSubmitting) { - return - } - - methods.watch(() => methods.handleSubmit(onSubmit)()) - }, [methods, onSubmit]) + handleSubmit(onSubmit)() + }, [selectedBedType, handleSubmit, onSubmit]) return ( diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Breakfast/index.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Breakfast/index.tsx index 4340b6aa1..4a665f495 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Breakfast/index.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Breakfast/index.tsx @@ -14,6 +14,7 @@ import RadioCard from "@/components/TempDesignSystem/Form/RadioCard" import Body from "@/components/TempDesignSystem/Text/Body" import { useRoomContext } from "@/contexts/Details/Room" import { formatPrice } from "@/utils/numberFormatting" +import { trackBreakfastSelection } from "@/utils/tracking" import { breakfastFormSchema } from "./schema" @@ -25,6 +26,7 @@ import { BreakfastPackageEnum } from "@/types/enums/breakfast" export default function Breakfast() { const intl = useIntl() const packages = useEnterDetailsStore((state) => state.breakfastPackages) + const hotelId = useEnterDetailsStore((state) => state.booking.hotelId) const { actions: { updateBreakfast }, room, @@ -49,22 +51,26 @@ export default function Breakfast() { const onSubmit = useCallback( (values: BreakfastFormSchema) => { - const pkg = packages?.find((p) => p.code === values.breakfast) + const pkg = packages.find((p) => p.code === values.breakfast) if (pkg) { updateBreakfast(pkg) } else { updateBreakfast(false) } + trackBreakfastSelection({ + breakfastPackage: pkg ?? packages[0], + hotelId, + units: pkg ? room.adults : 0, + }) }, - [packages, updateBreakfast] + [packages, hotelId, room.adults, updateBreakfast] ) + const selectedBreakfast = methods.watch("breakfast") + const handleSubmit = methods.handleSubmit useEffect(() => { - if (methods.formState.isSubmitting) { - return - } - methods.watch(() => methods.handleSubmit(onSubmit)()) - }, [methods, onSubmit]) + handleSubmit(onSubmit)() + }, [selectedBreakfast, handleSubmit, onSubmit]) return ( diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Confirm/index.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Confirm/index.tsx index 1eb442b6b..be6daeb6b 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Confirm/index.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Confirm/index.tsx @@ -13,6 +13,7 @@ import { PaymentMethodEnum } from "@/constants/booking" import Modal from "@/components/Modal" import Divider from "@/components/TempDesignSystem/Divider" import Checkbox from "@/components/TempDesignSystem/Form/Checkbox" +import { trackPaymentSectionOpen } from "@/utils/tracking/booking" import MySavedCards from "../Payment/MySavedCards" import PaymentOption from "../Payment/PaymentOption" @@ -40,7 +41,16 @@ export default function ConfirmBooking({
- + { + if (e.target.value) { + trackPaymentSectionOpen() + } + }, + }} + />

{intl.formatMessage({ diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Details/Multiroom/index.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Details/Multiroom/index.tsx index 613a5a554..d5be90a80 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Details/Multiroom/index.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Details/Multiroom/index.tsx @@ -13,7 +13,9 @@ import Input from "@/components/TempDesignSystem/Form/Input" import Phone from "@/components/TempDesignSystem/Form/Phone" import Footnote from "@/components/TempDesignSystem/Text/Footnote" import { useRoomContext } from "@/contexts/Details/Room" +import { trackPaymentSectionOpen } from "@/utils/tracking/booking" +import { hasPrepaidRate } from "../../Payment/helpers" import JoinScandicFriendsCard from "./JoinScandicFriendsCard" import { multiroomDetailsSchema } from "./schema" @@ -25,10 +27,13 @@ const formID = "enter-details" export default function Details() { const intl = useIntl() - const { canProceedToPayment, lastRoom } = useEnterDetailsStore((state) => ({ - canProceedToPayment: state.canProceedToPayment, - lastRoom: state.lastRoom, - })) + const { canProceedToPayment, lastRoom, rooms } = useEnterDetailsStore( + (state) => ({ + canProceedToPayment: state.canProceedToPayment, + lastRoom: state.lastRoom, + rooms: state.rooms, + }) + ) const { actions: { updateDetails }, @@ -61,6 +66,8 @@ export default function Details() { const guestIsGoingToJoin = methods.watch("join") const guestIsMember = methods.watch("membershipNo") + const hasPrepaidRates = rooms.some(hasPrepaidRate) + return (

{isPaymentNext ? intl.formatMessage({ diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Details/RoomOne/index.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Details/RoomOne/index.tsx index 9f1a78fc5..10d2d25f7 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Details/RoomOne/index.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Details/RoomOne/index.tsx @@ -14,6 +14,7 @@ import Input from "@/components/TempDesignSystem/Form/Input" import Phone from "@/components/TempDesignSystem/Form/Phone" import Footnote from "@/components/TempDesignSystem/Text/Footnote" import { useRoomContext } from "@/contexts/Details/Room" +import { trackPaymentSectionOpen } from "@/utils/tracking/booking" import JoinScandicFriendsCard from "./JoinScandicFriendsCard" import MemberPriceModal from "./MemberPriceModal" @@ -162,6 +163,11 @@ export default function Details({ user }: DetailsProps) { typography="Body/Paragraph/mdBold" size="Medium" type="submit" + onPress={ + isPaymentNext && canProceedToPayment && !room.isFlexRate + ? trackPaymentSectionOpen + : undefined + } > {isPaymentNext ? intl.formatMessage({ diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Room/Multiroom.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Room/Multiroom.tsx index 47b5f65dd..514f587c5 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Room/Multiroom.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Room/Multiroom.tsx @@ -26,7 +26,7 @@ export default function Multiroom() { })) const showBreakfastStep = - !room.breakfastIncluded && !!breakfastPackages?.length + !room.breakfastIncluded && !!breakfastPackages.length const arePreviousRoomsValid = rooms.slice(0, idx).every((r) => r.isComplete) diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Room/One.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Room/One.tsx index 9acfa975e..529ce3dce 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Room/One.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Room/One.tsx @@ -40,7 +40,7 @@ export default function RoomOne({ user }: { user: SafeUser }) { ) const showBreakfastStep = - !room.breakfastIncluded && !!breakfastPackages?.length + !room.breakfastIncluded && !!breakfastPackages.length return (
diff --git a/apps/scandic-web/stores/enter-details/index.ts b/apps/scandic-web/stores/enter-details/index.ts index fab511c26..c93b1fe00 100644 --- a/apps/scandic-web/stores/enter-details/index.ts +++ b/apps/scandic-web/stores/enter-details/index.ts @@ -49,7 +49,7 @@ export function createDetailsStore( initialState: InitialState, searchParams: string, user: SafeUser, - breakfastPackages: BreakfastPackages | null + breakfastPackages: BreakfastPackages ) { const isMember = !!user const isRedemption = @@ -134,7 +134,7 @@ export function createDetailsStore( }, } - if (room.breakfastIncluded || !breakfastPackages?.length) { + if (room.breakfastIncluded || !breakfastPackages.length) { delete steps[StepEnum.breakfast] } @@ -318,7 +318,7 @@ export function createDetailsStore( childrenInRoom: initialState.booking.rooms[idx].childrenInRoom, bedType: room.bedType, breakfast: - !breakfastPackages?.length || room.breakfastIncluded + !breakfastPackages.length || room.breakfastIncluded ? false : undefined, guest: diff --git a/apps/scandic-web/types/providers/enter-details.ts b/apps/scandic-web/types/providers/enter-details.ts index 1fe4c3fa4..74806fd6a 100644 --- a/apps/scandic-web/types/providers/enter-details.ts +++ b/apps/scandic-web/types/providers/enter-details.ts @@ -5,7 +5,7 @@ import type { SelectRateSearchParams } from "../components/hotelReservation/sele export interface DetailsProviderProps extends React.PropsWithChildren { booking: SelectRateSearchParams - breakfastPackages: BreakfastPackages | null + breakfastPackages: BreakfastPackages rooms: Room[] searchParamsStr: string user: SafeUser diff --git a/apps/scandic-web/types/stores/enter-details.ts b/apps/scandic-web/types/stores/enter-details.ts index 648e2590e..b5f5118ae 100644 --- a/apps/scandic-web/types/stores/enter-details.ts +++ b/apps/scandic-web/types/stores/enter-details.ts @@ -87,7 +87,7 @@ export interface DetailsState { updateSeachParamString: (searchParamString: string) => void } booking: SelectRateSearchParams - breakfastPackages: BreakfastPackages | null + breakfastPackages: BreakfastPackages canProceedToPayment: boolean isSubmittingDisabled: boolean isSummaryOpen: boolean diff --git a/apps/scandic-web/utils/tracking/booking.ts b/apps/scandic-web/utils/tracking/booking.ts index 83368a72f..b020814c5 100644 --- a/apps/scandic-web/utils/tracking/booking.ts +++ b/apps/scandic-web/utils/tracking/booking.ts @@ -1,5 +1,6 @@ import { trackEvent } from "./base" +import type { BreakfastPackages } from "@/types/components/hotelReservation/breakfast" import type { LowestRoomPriceEvent } from "@/types/components/tracking" export function trackLowestRoomPrice(event: LowestRoomPriceEvent) { @@ -16,3 +17,64 @@ export function trackLowestRoomPrice(event: LowestRoomPriceEvent) { }, }) } + +// Tracking for sections of booking flow enter-details page +export function trackBedSelection(bedType: string) { + trackEvent({ + event: "bedSelection", + selection: { + name: "bed options selection click", + bedType: bedType, + }, + pageInfo: { + pageName: "hotelreservation|bed", + pageType: "bookingbedtypepage", + }, + }) +} + +export function trackBreakfastSelection({ + breakfastPackage, + hotelId, + units, +}: { + breakfastPackage: BreakfastPackages[number] + hotelId: string + units: number +}) { + trackEvent({ + event: "breakfastSelection", + selection: { + name: "breakfast options selection click", + }, + ancillaries: [ + { + hotelId: hotelId, + productCategory: "", + productId: breakfastPackage.code, + productUnits: units, + productPrice: breakfastPackage.localPrice.price, + productPoints: 0, + productType: "food", + productName: breakfastPackage.packageType, + }, + ], + pageInfo: { + pageName: "hotelreservation|breakfast", + pageType: "bookingbreakfastpage", + }, + }) +} + +export function trackPaymentSectionOpen() { + trackEvent({ + event: "paymentSectionOpen", + selection: { + name: "payment section open", + }, + pageInfo: { + pageName: "hotelreservation|payment", + pageType: "bookingpaymentpage", + }, + }) +} diff --git a/apps/scandic-web/utils/tracking/index.ts b/apps/scandic-web/utils/tracking/index.ts index 67120a376..fd09e2dcf 100644 --- a/apps/scandic-web/utils/tracking/index.ts +++ b/apps/scandic-web/utils/tracking/index.ts @@ -1,5 +1,9 @@ export { trackClick } from "./base" -export { trackLowestRoomPrice } from "./booking" +export { + trackBedSelection, + trackBreakfastSelection, + trackLowestRoomPrice, +} from "./booking" export { trackAccordionClick, trackOpenSidePeekEvent } from "./componentEvents" export { trackHotelMapClick, trackHotelTabClick } from "./hotelPage" export { trackCancelStay, trackMyStayPageLink } from "./myStay"