Merged in fix/SW-2668-tracking-room-details-missing (pull request #2015)

fix(SW-2668): added search term and room details to tracking

* fix(SW-2668): added search term and room details to tracking

* fix: change to optional type


Approved-by: Christian Andolf
Approved-by: Matilda Landström
This commit is contained in:
Tobias Johansson
2025-05-08 14:13:51 +00:00
parent 8d864df5b3
commit 02b26e7965
7 changed files with 21 additions and 11 deletions

View File

@@ -13,10 +13,10 @@ import { Typography } from "@scandic-hotels/design-system/Typography"
import { type AutoCompleteLocation } from "@/server/routers/autocomplete/schema"
import SkeletonShimmer from "@/components/SkeletonShimmer"
import { useSearchHistory } from "@/hooks/useSearchHistory"
import { Input } from "../Input"
import SearchList from "./SearchList"
import { useSearchHistory } from "./useSearchHistory"
import styles from "./search.module.css"

View File

@@ -1,86 +0,0 @@
import { useCallback, useEffect, useState } from "react"
import {
type AutoCompleteLocation,
autoCompleteLocationSchema,
} from "@/server/routers/autocomplete/schema"
import useLang from "@/hooks/useLang"
export function useSearchHistory() {
const MAX_HISTORY_LENGTH = 5
const KEY = useSearchHistoryKey()
const getHistoryFromLocalStorage = useCallback((): AutoCompleteLocation[] => {
const stringifiedHistory = localStorage.getItem(KEY)
try {
const parsedHistory = JSON.parse(stringifiedHistory ?? "[]")
if (!Array.isArray(parsedHistory)) {
throw new Error("Invalid search history format")
}
const existingHistory = parsedHistory.map((item) =>
autoCompleteLocationSchema.parse(item)
)
return existingHistory
} catch (error) {
console.error("Failed to parse search history:", error)
localStorage.removeItem(KEY)
return []
}
}, [KEY])
function updateSearchHistory(newItem: AutoCompleteLocation) {
const existingHistory = getHistoryFromLocalStorage()
if (!autoCompleteLocationSchema.safeParse(newItem).success) {
return existingHistory
}
const oldSearchHistoryWithoutTheNew = existingHistory.filter(
(h) => h.type !== newItem.type || h.id !== newItem.id
)
const updatedSearchHistory = [
newItem,
...oldSearchHistoryWithoutTheNew.slice(0, MAX_HISTORY_LENGTH - 1),
]
localStorage.setItem(KEY, JSON.stringify(updatedSearchHistory))
return updatedSearchHistory
}
const [searchHistory, setSearchHistory] = useState<AutoCompleteLocation[]>([])
useEffect(() => {
setSearchHistory(getHistoryFromLocalStorage())
}, [KEY, getHistoryFromLocalStorage])
function clearHistory() {
localStorage.removeItem(KEY)
setSearchHistory([])
}
function insertSearchHistoryItem(
newItem: AutoCompleteLocation
): AutoCompleteLocation[] {
const updatedHistory = updateSearchHistory(newItem)
setSearchHistory(updatedHistory)
return updatedHistory
}
return {
searchHistory,
insertSearchHistoryItem,
clearHistory,
}
}
function useSearchHistoryKey() {
const SEARCH_HISTORY_LOCALSTORAGE_KEY = "searchHistory"
const lang = useLang()
return `${SEARCH_HISTORY_LOCALSTORAGE_KEY}-${lang}`.toLowerCase()
}

View File

@@ -6,6 +6,7 @@ import { useBookingConfirmationStore } from "@/stores/booking-confirmation"
import TrackingSDK from "@/components/TrackingSDK"
import useLang from "@/hooks/useLang"
import { useSearchHistory } from "@/hooks/useSearchHistory"
import { getTracking } from "./tracking"
@@ -33,6 +34,9 @@ export default function Tracking({
sessionStorage.setItem("loadedBookingConfirmationRefId", refId)
}, [refId])
const searchHistory = useSearchHistory()
const searchTerm = searchHistory.searchHistory[0]?.name
if (!bookingRooms.every(Boolean)) {
return null
}
@@ -44,7 +48,8 @@ export default function Tracking({
lang,
bookingConfirmation.booking,
bookingConfirmation.hotel,
rooms
rooms,
searchTerm
)
return (

View File

@@ -58,7 +58,8 @@ export function getTracking(
lang: Lang,
booking: BookingConfirmation["booking"],
hotel: BookingConfirmation["hotel"],
rooms: Room[]
rooms: Room[],
searchTerm?: string
) {
const arrivalDate = new Date(booking.checkInDate)
const departureDate = new Date(booking.checkOutDate)
@@ -150,6 +151,7 @@ export function getTracking(
points: booking.roomPoints > 0 ? booking.roomPoints : undefined,
roomPrice: rooms.reduce((total, room) => total + room.roomPrice, 0),
roomTypeCode: rooms.map((r) => r.roomTypeCode ?? "").join(","),
searchTerm,
searchType: "hotel",
specialRoomType: rooms
.map((room) => getSpecialRoomType(room.packages))

View File

@@ -3,6 +3,7 @@
import { useEnterDetailsStore } from "@/stores/enter-details"
import TrackingSDK from "@/components/TrackingSDK"
import { useSearchHistory } from "@/hooks/useSearchHistory"
import { getTracking } from "./tracking"
@@ -16,7 +17,6 @@ interface TrackingWrapperProps {
booking: SelectHotelParams<SelectRateSearchParams>
hotel: Hotel
rooms: Room[]
city: string | undefined
isMember: boolean
lang: Lang
}
@@ -25,7 +25,6 @@ export default function EnterDetailsTrackingWrapper({
booking,
hotel,
rooms,
city,
isMember,
lang,
}: TrackingWrapperProps) {
@@ -34,15 +33,18 @@ export default function EnterDetailsTrackingWrapper({
breakfastPackages: state.breakfastPackages,
}))
const searchHistory = useSearchHistory()
const searchTerm = searchHistory.searchHistory[0]?.name
const { hotelsTrackingData, pageTrackingData, ancillaries } = getTracking(
booking,
hotel,
rooms,
city,
isMember,
lang,
storedRooms,
breakfastPackages
breakfastPackages,
searchTerm
)
return (
<TrackingSDK

View File

@@ -31,11 +31,11 @@ export function getTracking(
booking: SelectHotelParams<SelectRateSearchParams>,
hotel: Hotel,
rooms: Room[],
city: string | undefined,
isMember: boolean,
lang: Lang,
storedRooms: RoomState[],
breakfastPackages: BreakfastPackages
breakfastPackages: BreakfastPackages,
searchTerm?: string
) {
const arrivalDate = new Date(booking.fromDate)
const departureDate = new Date(booking.toDate)
@@ -185,12 +185,14 @@ export function getTracking(
rewardNightAvailability:
booking.searchType === REDEMPTION ? "true" : "false",
roomPrice: calcTotalRoomPrice(storedRooms, isMember),
roomTypeCode: rooms.map((room) => room.roomTypeCode).join("|"),
roomTypeName: rooms.map((room) => room.roomType).join("|"),
totalPrice: calcTotalPrice(storedRooms, isMember),
points:
// @ts-expect-error - redemption object doesn't exist error
rooms.find((room) => "redemption" in room.roomRate)?.roomRate.redemption
.localPrice.pointsPerStay ?? "n/a",
searchTerm: city,
searchTerm,
searchType: "hotel",
specialRoomType: rooms
.map((room) => getSpecialRoomType(room.packages))