Merged in feat/book-504-at-pageview (pull request #3099)

Feat(BOOK-504): basic pageview event

* fix

* Cleanup


Approved-by: Joakim Jäderberg
This commit is contained in:
Linus Flood
2025-11-07 07:57:19 +00:00
parent a9789a8a7c
commit fdf124bd0c
7 changed files with 176 additions and 42 deletions

View File

@@ -337,12 +337,7 @@ export default async function HotelPage({
<DialogshiftWidget hotelId={hotelId} />
<Suspense fallback={null}>
<TrackingSDK
pageData={trackingPageData}
hotelInfo={trackingHotelData}
/>
</Suspense>
<TrackingSDK pageData={trackingPageData} hotelInfo={trackingHotelData} />
</div>
)
}

View File

@@ -124,11 +124,11 @@ export async function AlternativeHotelsMapPage({
isAlternativeHotels={true}
filterList={filterList}
/>
<TrackingSDK
hotelInfo={hotelsTrackingData}
pageData={pageTrackingData}
/>
</Suspense>
<TrackingSDK
hotelInfo={hotelsTrackingData}
pageData={pageTrackingData}
/>
</MapContainer>
</BookingFlowConfig>
)

View File

@@ -1,7 +1,5 @@
import stringify from "json-stable-stringify-without-jsonify"
import { cookies } from "next/headers"
import { notFound } from "next/navigation"
import { Suspense } from "react"
import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAndFriends"
import { NoAvailabilityTracking } from "@scandic-hotels/tracking/NoAvailabilityTracking"
@@ -113,8 +111,6 @@ export async function AlternativeHotelsPage({
config,
})
const suspenseKey = stringify(searchParams)
const shouldTrackNoAvailability = !!(
hotels.every((hotel) => hotel.availability.status !== "Available") ||
(booking.bookingCode && hotels.length > 0 && !isBookingCodeRateAvailable)
@@ -132,18 +128,13 @@ export async function AlternativeHotelsPage({
}
lang={lang}
/>
<Suspense key={`${suspenseKey}-tracking`} fallback={null}>
<TrackingSDK
hotelInfo={hotelsTrackingData}
pageData={pageTrackingData}
/>
<NoAvailabilityTracking
lang={lang}
hotelsTrackingData={hotelsTrackingData}
pageTrackingData={pageTrackingData}
shouldTrackNoAvailability={shouldTrackNoAvailability}
/>
</Suspense>
<NoAvailabilityTracking
lang={lang}
hotelsTrackingData={hotelsTrackingData}
pageTrackingData={pageTrackingData}
shouldTrackNoAvailability={shouldTrackNoAvailability}
/>
<TrackingSDK hotelInfo={hotelsTrackingData} pageData={pageTrackingData} />
</BookingFlowConfig>
)
}

View File

@@ -1,7 +1,5 @@
import stringify from "json-stable-stringify-without-jsonify"
import { cookies } from "next/headers"
import { notFound } from "next/navigation"
import { Suspense } from "react"
import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAndFriends"
import { NoAvailabilityTracking } from "@scandic-hotels/tracking/NoAvailabilityTracking"
@@ -99,8 +97,6 @@ export async function SelectHotelPage({
config,
})
const suspenseKey = stringify(searchParams)
const shouldTrackNoAvailability = !!(
hotels.every((hotel) => hotel.availability.status !== "Available") ||
(booking.bookingCode && hotels.length > 0 && !isBookingCodeRateAvailable)
@@ -116,18 +112,13 @@ export async function SelectHotelPage({
title={city.name}
lang={lang}
/>
<Suspense key={`${suspenseKey}-tracking`} fallback={null}>
<TrackingSDK
hotelInfo={hotelsTrackingData}
pageData={pageTrackingData}
/>
<NoAvailabilityTracking
lang={lang}
hotelsTrackingData={hotelsTrackingData}
pageTrackingData={pageTrackingData}
shouldTrackNoAvailability={shouldTrackNoAvailability}
/>
</Suspense>
<NoAvailabilityTracking
lang={lang}
hotelsTrackingData={hotelsTrackingData}
pageTrackingData={pageTrackingData}
shouldTrackNoAvailability={shouldTrackNoAvailability}
/>
<TrackingSDK hotelInfo={hotelsTrackingData} pageData={pageTrackingData} />
</BookingFlowConfig>
)
}

View File

@@ -3,7 +3,9 @@
import { usePathname } from "next/navigation"
import { useTrackHardNavigation } from "./useTrackHardNavigation"
import { useTrackHardNavigationBasic } from "./useTrackHardNavigationBasic"
import { useTrackSoftNavigation } from "./useTrackSoftNavigation"
import { useTrackSoftNavigationBasic } from "./useTrackSoftNavigationBasic"
import type {
TrackingSDKAncillaries,
@@ -25,6 +27,16 @@ export function TrackingSDK({
}) {
const pathName = usePathname()
useTrackHardNavigationBasic({
pageData,
pathName,
})
useTrackSoftNavigationBasic({
pageData,
pathName,
})
useTrackHardNavigation({
pageData,
hotelInfo,

View File

@@ -0,0 +1,62 @@
"use client"
import { useSession } from "next-auth/react"
import { useEffect } from "react"
import { useSessionId } from "@scandic-hotels/common/hooks/useSessionId"
import { isValidSession } from "@scandic-hotels/trpc/utils/session"
import { createSDKPageObject, trackPageView } from "./pageview"
import type { TrackingSDKPageData } from "./types"
type TrackingSDKProps = {
pageData: TrackingSDKPageData
pathName: string
}
let hasTrackedHardNavigationBasic = false
export const useTrackHardNavigationBasic = ({
pageData,
pathName,
}: TrackingSDKProps) => {
const sessionId = useSessionId()
const { data: session } = useSession()
const validSession = isValidSession(session)
useEffect(() => {
if (hasTrackedHardNavigationBasic) return
trackBasicPageView({
pathName,
sessionId,
pageData,
validSession,
})
hasTrackedHardNavigationBasic = true
}, [pathName, pageData, sessionId, validSession])
}
const trackBasicPageView = async ({
pathName,
sessionId,
pageData,
validSession,
}: {
pathName: string
sessionId: string | null
pageData: TrackingSDKProps["pageData"]
validSession: boolean
}) => {
const trackingData = { ...pageData, pathName, sessionId }
const pageObject = createSDKPageObject(trackingData)
trackPageView({
event: "pageViewBasic",
pageInfo: pageObject,
userInfo: {
loginStatus: validSession ? "logged in" : "Non-logged in",
},
})
}

View File

@@ -0,0 +1,83 @@
"use client"
import { useSession } from "next-auth/react"
import { startTransition, useEffect, useRef, useState } from "react"
import { useSessionId } from "@scandic-hotels/common/hooks/useSessionId"
import useRouterTransitionStore from "@scandic-hotels/common/stores/router-transition"
import { isValidSession } from "@scandic-hotels/trpc/utils/session"
import { createSDKPageObject, trackPageView } from "./pageview"
import type { TrackingSDKPageData } from "./types"
type TrackingSDKProps = {
pageData: TrackingSDKPageData
pathName: string
}
enum TransitionStatusEnum {
NotRun = "NotRun",
Running = "Running",
Done = "Done",
}
type TransitionStatus = keyof typeof TransitionStatusEnum
export const useTrackSoftNavigationBasic = ({
pageData,
pathName,
}: TrackingSDKProps) => {
const [status, setStatus] = useState<TransitionStatus>(
TransitionStatusEnum.NotRun
)
const sessionId = useSessionId()
const { data: session } = useSession()
const validSession = isValidSession(session)
const { isTransitioning, stopRouterTransition } = useRouterTransitionStore()
const previousPathname = useRef<string | null>(null)
useEffect(() => {
if (isTransitioning && status === TransitionStatusEnum.NotRun) {
startTransition(() => {
setStatus(TransitionStatusEnum.Running)
})
return
}
if (isTransitioning && status === TransitionStatusEnum.Running) {
setStatus(TransitionStatusEnum.Done)
stopRouterTransition()
return
}
if (!isTransitioning && status === TransitionStatusEnum.Done) {
const trackingData = {
...pageData,
sessionId,
pathName,
}
const pageObject = createSDKPageObject(trackingData)
trackPageView({
event: "pageViewBasic",
pageInfo: pageObject,
userInfo: {
loginStatus: validSession ? "logged in" : "Non-logged in",
},
})
setStatus(TransitionStatusEnum.NotRun) // Reset status
previousPathname.current = pathName // Update for next render
}
}, [
isTransitioning,
status,
stopRouterTransition,
pageData,
pathName,
sessionId,
])
}