Merged in feat/SW-1554-sidepeek-tracking-hotel-pages (pull request #1460)

feat(SW-1554): Added tracking support for sidepeeks inside hotel pages

* feat(SW-1554): Added tracking support for sidepeeks inside hotel pages


Approved-by: Linus Flood
This commit is contained in:
Erik Tiekstra
2025-03-04 07:02:04 +00:00
parent b8ad88de1b
commit 1ec479e601
8 changed files with 46 additions and 26 deletions

View File

@@ -64,7 +64,7 @@ export function RoomCard({ room }: RoomCardProps) {
</Body> </Body>
</div> </div>
<Button intent="text" type="button" size="medium" theme="base" asChild> <Button intent="text" type="button" size="medium" theme="base" asChild>
<Link scroll={false} href={`#s-${getRoomNameAsParam(name)}`}> <Link scroll={false} href={`#s-room-${getRoomNameAsParam(name)}`}>
{intl.formatMessage({ id: "See room details" })} {intl.formatMessage({ id: "See room details" })}
<ChevronRightSmallIcon color="burgundy" width={20} height={20} /> <ChevronRightSmallIcon color="burgundy" width={20} height={20} />
</Link> </Link>

View File

@@ -27,7 +27,10 @@ export default async function RoomSidePeek({ room }: RoomSidePeekProps) {
const galleryImages = mapApiImagesToGalleryImages(images) const galleryImages = mapApiImagesToGalleryImages(images)
return ( return (
<SidePeek contentKey={getRoomNameAsParam(room.name)} title={room.name}> <SidePeek
contentKey={`room-${getRoomNameAsParam(room.name)}`}
title={room.name}
>
<div className={styles.content}> <div className={styles.content}>
<div className={styles.innerContent}> <div className={styles.innerContent}>
{totalOccupancy && ( {totalOccupancy && (

View File

@@ -1,6 +0,0 @@
export { default as AboutTheHotelSidePeek } from "./AboutTheHotel"
export { default as ActivitiesSidePeek } from "./Activities"
export { default as AmenitiesSidePeek } from "./Amenities"
export { default as MeetingsAndConferencesSidePeek } from "./MeetingsAndConferences"
export { default as RoomSidePeek } from "./Room"
export { default as WellnessAndExerciseSidePeek } from "./WellnessAndExercise"

View File

@@ -0,0 +1,15 @@
"use client"
import SidePeekProvider from "@/components/SidePeeks/SidePeekProvider"
import { trackOpenSidePeekEvent } from "@/utils/tracking"
interface SidePeeksProps extends React.PropsWithChildren {
hotelId: string
}
export default function SidePeeks({ hotelId, children }: SidePeeksProps) {
function handleOpen(sidePeek: string) {
trackOpenSidePeekEvent(sidePeek, hotelId)
}
return <SidePeekProvider onOpen={handleOpen}>{children}</SidePeekProvider>
}

View File

@@ -10,7 +10,6 @@ import {
import AccordionSection from "@/components/Blocks/Accordion" import AccordionSection from "@/components/Blocks/Accordion"
import Breadcrumbs from "@/components/Breadcrumbs" import Breadcrumbs from "@/components/Breadcrumbs"
import SidePeekProvider from "@/components/SidePeeks/SidePeekProvider"
import Alert from "@/components/TempDesignSystem/Alert" import Alert from "@/components/TempDesignSystem/Alert"
import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/BreadcrumbsSkeleton" import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/BreadcrumbsSkeleton"
import TrackingSDK from "@/components/TrackingSDK" import TrackingSDK from "@/components/TrackingSDK"
@@ -23,20 +22,19 @@ import MapCard from "./Map/MapCard"
import MapWithCardWrapper from "./Map/MapWithCard" import MapWithCardWrapper from "./Map/MapWithCard"
import MobileMapToggle from "./Map/MobileMapToggle" import MobileMapToggle from "./Map/MobileMapToggle"
import StaticMap from "./Map/StaticMap" import StaticMap from "./Map/StaticMap"
import AboutTheHotelSidePeek from "./SidePeeks/AboutTheHotel"
import ActivitiesSidePeek from "./SidePeeks/Activities"
import AmenitiesSidePeek from "./SidePeeks/Amenities"
import MeetingsAndConferencesSidePeek from "./SidePeeks/MeetingsAndConferences"
import RestaurantBarSidePeek from "./SidePeeks/RestaurantBar" import RestaurantBarSidePeek from "./SidePeeks/RestaurantBar"
import RoomSidePeek from "./SidePeeks/Room"
import WellnessAndExerciseSidePeek from "./SidePeeks/WellnessAndExercise"
import AmenitiesList from "./AmenitiesList" import AmenitiesList from "./AmenitiesList"
import Facilities from "./Facilities" import Facilities from "./Facilities"
import IntroSection from "./IntroSection" import IntroSection from "./IntroSection"
import PreviewImages from "./PreviewImages" import PreviewImages from "./PreviewImages"
import { Rooms } from "./Rooms" import { Rooms } from "./Rooms"
import { import SidePeeks from "./SidePeeks"
AboutTheHotelSidePeek,
ActivitiesSidePeek,
AmenitiesSidePeek,
MeetingsAndConferencesSidePeek,
RoomSidePeek,
WellnessAndExerciseSidePeek,
} from "./SidePeeks"
import TabNavigation from "./TabNavigation" import TabNavigation from "./TabNavigation"
import { getTrackingHotelData, getTrackingPageData } from "./utils" import { getTrackingHotelData, getTrackingPageData } from "./utils"
@@ -214,7 +212,7 @@ export default async function HotelPage({ hotelId }: HotelPageProps) {
/> />
</> </>
) : null} ) : null}
<SidePeekProvider> <SidePeeks hotelId={hotelId}>
<AmenitiesSidePeek <AmenitiesSidePeek
amenitiesList={detailedFacilities} amenitiesList={detailedFacilities}
parking={{ parking={{
@@ -275,7 +273,7 @@ export default async function HotelPage({ hotelId }: HotelPageProps) {
{roomCategories.map((room) => ( {roomCategories.map((room) => (
<RoomSidePeek key={room.name} room={room} /> <RoomSidePeek key={room.name} room={room} />
))} ))}
</SidePeekProvider> </SidePeeks>
<Suspense fallback={null}> <Suspense fallback={null}>
<TrackingSDK <TrackingSDK
pageData={trackingPageData} pageData={trackingPageData}

View File

@@ -4,6 +4,10 @@ import { createContext, useEffect, useState } from "react"
import useHash from "@/hooks/useHash" import useHash from "@/hooks/useHash"
interface SidepeekProviderProps extends React.PropsWithChildren {
onOpen?: (sidePeek: string) => void
}
interface ISidePeekContext { interface ISidePeekContext {
handleClose: (isOpen: boolean) => void handleClose: (isOpen: boolean) => void
activeSidePeek: string | null activeSidePeek: string | null
@@ -13,7 +17,8 @@ export const SidePeekContext = createContext<ISidePeekContext | null>(null)
export default function SidePeekProvider({ export default function SidePeekProvider({
children, children,
}: React.PropsWithChildren) { onOpen,
}: SidepeekProviderProps) {
const router = useRouter() const router = useRouter()
const hash = useHash() const hash = useHash()
const [activeSidePeek, setActiveSidePeek] = useState<string | null>(null) const [activeSidePeek, setActiveSidePeek] = useState<string | null>(null)
@@ -26,6 +31,12 @@ export default function SidePeekProvider({
} }
}, [hash, setActiveSidePeek]) }, [hash, setActiveSidePeek])
useEffect(() => {
if (activeSidePeek && onOpen) {
onOpen(activeSidePeek)
}
}, [activeSidePeek, onOpen])
function handleClose(isOpen: boolean) { function handleClose(isOpen: boolean) {
if (!isOpen) { if (!isOpen) {
router.push(window.location.pathname, { scroll: false }) router.push(window.location.pathname, { scroll: false })

View File

@@ -1,4 +1,3 @@
import type { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek"
import type { import type {
LowestRoomPriceEvent, LowestRoomPriceEvent,
PaymentEvent, PaymentEvent,
@@ -103,9 +102,9 @@ export function trackUpdatePaymentMethod(hotelId: string, method: string) {
} }
export function trackOpenSidePeekEvent( export function trackOpenSidePeekEvent(
sidePeek: SidePeekEnum | null, name: string | null,
hotelId: string, hotelId: string,
pathName: string, pathName?: string,
roomTypeCode?: string | null roomTypeCode?: string | null
) { ) {
const openSidePeekEvent = { const openSidePeekEvent = {
@@ -114,9 +113,9 @@ export function trackOpenSidePeekEvent(
hotelId: hotelId, hotelId: hotelId,
}, },
cta: { cta: {
name: sidePeek, name,
roomTypeCode, ...(roomTypeCode ? { roomTypeCode } : {}),
pathName, ...(pathName ? { pathName } : {}),
}, },
} }
trackEvent(openSidePeekEvent) trackEvent(openSidePeekEvent)