Merged in chore/cleanup-scandic-web (pull request #2831)

chore: Cleanup scandic-web

* Remove unused files

* Remove unused and add missing packages

* Remove unused exports


Approved-by: Linus Flood
This commit is contained in:
Anton Gunnarsson
2025-09-18 15:33:00 +00:00
parent cc99f26727
commit 08804e8675
113 changed files with 45 additions and 2891 deletions

View File

@@ -1,83 +0,0 @@
"use client"
import { useEffect, useState } from "react"
import { clearPaymentInfoSessionStorage } from "@scandic-hotels/booking-flow/components/EnterDetails/Payment/helpers"
import { useSearchHistory } from "@scandic-hotels/booking-flow/hooks/useSearchHistory"
import { useBookingConfirmationStore } from "@scandic-hotels/booking-flow/stores/booking-confirmation"
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
import useLang from "@/hooks/useLang"
import { getTracking } from "./tracking"
import type { Room } from "@scandic-hotels/booking-flow/types/stores/booking-confirmation"
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
export default function Tracking({
bookingConfirmation,
refId,
}: {
bookingConfirmation: BookingConfirmation
refId: string
}) {
const lang = useLang()
const bookingRooms = useBookingConfirmationStore((state) => state.rooms)
const [loadedBookingConfirmationRefId] = useState(() => {
if (typeof window !== "undefined") {
return sessionStorage.getItem("loadedBookingConfirmationRefId")
}
return null
})
useEffect(() => {
sessionStorage.setItem("loadedBookingConfirmationRefId", refId)
}, [refId])
const searchHistory = useSearchHistory()
const searchTerm = searchHistory.searchHistory[0]?.name
let trackingData = null
if (bookingRooms.every(Boolean)) {
const rooms = bookingRooms.filter((room): room is Room => !!room)
trackingData = getTracking(
lang,
bookingConfirmation.booking,
bookingConfirmation.hotel,
rooms,
searchTerm
)
}
useEffect(() => {
if (trackingData?.paymentInfo) {
clearPaymentInfoSessionStorage()
}
}, [trackingData])
if (!trackingData) {
return null
}
const { hotelsTrackingData, pageTrackingData, paymentInfo, ancillaries } =
trackingData
return (
<TrackingSDK
pageData={pageTrackingData}
hotelInfo={
loadedBookingConfirmationRefId === refId
? undefined
: hotelsTrackingData
}
paymentInfo={
loadedBookingConfirmationRefId === refId ? undefined : paymentInfo
}
ancillaries={
loadedBookingConfirmationRefId === refId ? undefined : ancillaries
}
/>
)
}

View File

@@ -1,213 +0,0 @@
import { createHash } from "crypto"
import { differenceInCalendarDays, format, isWeekend } from "date-fns"
import { readPaymentInfoFromSessionStorage } from "@scandic-hotels/booking-flow/components/EnterDetails/Payment/helpers"
import { invertedBedTypeMap } from "@scandic-hotels/booking-flow/utils/SelectRate"
import { getSpecialRoomType } from "@scandic-hotels/booking-flow/utils/specialRoomType"
import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
import { RateEnum } from "@scandic-hotels/common/constants/rate"
import {
TrackingChannelEnum,
type TrackingSDKAncillaries,
type TrackingSDKHotelInfo,
type TrackingSDKPageData,
type TrackingSDKPaymentInfo,
} from "@scandic-hotels/tracking/types"
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
import type { Room } from "@scandic-hotels/booking-flow/types/stores/booking-confirmation"
import type { Lang } from "@scandic-hotels/common/constants/language"
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
import type { RateDefinition } from "@scandic-hotels/trpc/types/roomAvailability"
function getRate(cancellationRule: RateDefinition["cancellationRule"] | null) {
switch (cancellationRule) {
case "CancellableBefore6PM":
return RateEnum.flex
case "Changeable":
return RateEnum.change
case "NotCancellable":
return RateEnum.save
default:
return ""
}
}
function mapAncillaryPackage(
ancillaryPackage: BookingConfirmation["booking"]["packages"][number],
operaId: string
) {
const isPoints = ancillaryPackage.currency === CurrencyEnum.POINTS
return {
hotelid: operaId,
productCategory: "", // TODO: Add category
productId: ancillaryPackage.code,
productName: ancillaryPackage.description,
productPoints: isPoints ? ancillaryPackage.totalPrice : 0,
productPrice: isPoints ? 0 : ancillaryPackage.totalPrice,
productType:
ancillaryPackage.code === BreakfastPackageEnum.REGULAR_BREAKFAST
? "food"
: "room preference",
productUnits: ancillaryPackage.totalUnit,
productDeliveryTime: "",
}
}
export function getTracking(
lang: Lang,
booking: BookingConfirmation["booking"],
hotel: BookingConfirmation["hotel"],
rooms: Room[],
searchTerm?: string
) {
const arrivalDate = new Date(booking.checkInDate)
const departureDate = new Date(booking.checkOutDate)
const paymentInfoSessionData = readPaymentInfoFromSessionStorage()
const pageTrackingData: TrackingSDKPageData = {
channel: TrackingChannelEnum.hotelreservation,
domainLanguage: lang,
pageId: "booking-confirmation",
pageName: `hotelreservation|confirmation`,
pageType: "confirmation",
siteSections: `hotelreservation|confirmation`,
siteVersion: "new-web",
}
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 isGuaranteedFlexBooking = booking.guaranteeInfo && isFlexBooking
const ancillaries: TrackingSDKAncillaries = rooms
.flatMap((r) => r.packages)
.filter(
(p) =>
p.code === RoomPackageCodeEnum.PET_ROOM ||
p.code === BreakfastPackageEnum.REGULAR_BREAKFAST
)
.map((pkg) => mapAncillaryPackage(pkg, hotel.operaId))
const hotelsTrackingData: TrackingSDKHotelInfo = {
ageOfChildren: rooms.map((r) => r.childrenAges?.join(",") ?? "").join("|"),
analyticsRateCode: rooms
.map((r) => getRate(r.rateDefinition.cancellationRule))
.join("|"),
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
bedType: rooms
.map((r) => r.bedType)
.join(",")
.toLowerCase(),
bnr: rooms.map((r) => r.confirmationNumber).join(","),
bookingCode: rooms.map((room) => room.bookingCode ?? "n/a").join(", "),
bookingCodeAvailability: booking.bookingCode
? rooms.map((room) => (room.bookingCode ? "true" : "false")).join(", ")
: undefined,
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
breakfastOption: rooms
.map((r) => {
if (r.breakfastIncluded || r.breakfast) {
return "breakfast buffet"
}
return "no breakfast"
})
.join(","),
childBedPreference: rooms
.map(
(r) =>
r.childBedPreferences
.map((cbp) =>
Array(cbp.quantity).fill(invertedBedTypeMap[cbp.bedType])
)
.join(",") ?? ""
)
.join("|"),
country: hotel?.address.country,
departureDate: format(departureDate, "yyyy-MM-dd"),
duration: differenceInCalendarDays(departureDate, arrivalDate),
hotelID: hotel.operaId,
leadTime: differenceInCalendarDays(arrivalDate, new Date()),
noOfAdults,
noOfChildren,
noOfRooms,
rateCode: rooms.map((r) => r.rateDefinition.rateCode).join(","),
rateCodeCancellationRule: rooms
.map((r) => r.rateDefinition.cancellationRule)
.join(",")
.toLowerCase(),
rateCodeName: rooms.map(constructRateCodeName).join(","),
rateCodeType: rooms.map((r) => r.rateCodeType?.toLowerCase()).join(","),
region: hotel?.address.city,
revenueCurrencyCode: [...new Set(rooms.map((r) => r.currencyCode))].join(
","
),
rewardNight: booking.roomPoints > 0 ? "yes" : "no",
rewardNightAvailability: booking.roomPoints > 0 ? "true" : "false",
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))
.join(","),
totalPrice: rooms.reduce((total, room) => total + room.totalPrice, 0),
lateArrivalGuarantee: booking.rateDefinition.mustBeGuaranteed
? "mandatory"
: isFlexBooking
? booking.guaranteeInfo
? "yes"
: "no"
: "na",
guaranteedProduct: isGuaranteedFlexBooking ? "room" : "na",
emailId: getSHAHash(booking.guest.email),
mobileNumber: getSHAHash(booking.guest.phoneNumber),
}
const paymentInfo: TrackingSDKPaymentInfo = {
paymentStatus: isGuaranteedFlexBooking
? "glacardsaveconfirmed"
: "confirmed",
type:
booking.guaranteeInfo?.cardType ?? paymentInfoSessionData?.paymentMethod,
}
return {
hotelsTrackingData,
pageTrackingData,
paymentInfo,
ancillaries,
}
}
function constructRateCodeName(room: Room) {
if (room.cheques) {
return "corporate cheque"
} else if (room.vouchers) {
return "voucher"
} else if (room.roomPoints) {
return "redemption"
}
const rate = getRate(room.rateDefinition.cancellationRule)
const bookingCodeStr = room.bookingCode ? room.bookingCode.toUpperCase() : ""
const breakfastIncludedStr = room.breakfastIncluded
? "incl. breakfast"
: "excl. breakfast"
return [bookingCodeStr, rate, breakfastIncludedStr]
.filter(Boolean)
.join(" - ")
}
function getSHAHash(key: string) {
return createHash("sha256").update(key).digest("hex")
}

View File

@@ -1,6 +1,6 @@
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
export function hasBreakfastPackageFromBookingFlow(
function hasBreakfastPackageFromBookingFlow(
packages: {
code: string
}[]
@@ -13,26 +13,6 @@ export function hasBreakfastPackageFromBookingFlow(
)
}
export function getBreakfastPackagesFromBookingFlow<T extends { code: string }>(
packages: T[]
): T[] | undefined {
// Since `FREE_CHILD_BREAKFAST` has the same code when breakfast is added
// in the booking flow and as ancillary we can't just do a simple filter on the codes.
// So we shortcircuit if there are no booking flow specific packages.
if (!packages || !hasBreakfastPackageFromBookingFlow(packages)) {
return undefined
}
return packages.filter(
(p) =>
p.code === BreakfastPackageEnum.REGULAR_BREAKFAST ||
p.code === BreakfastPackageEnum.FREE_MEMBER_BREAKFAST ||
p.code === BreakfastPackageEnum.CHILD_PAYING_BREAKFAST ||
p.code === BreakfastPackageEnum.FREE_CHILD_BREAKFAST ||
p.code === BreakfastPackageEnum.SPECIAL_PACKAGE_BREAKFAST
)
}
export function getBreakfastPackagesFromAncillaryFlow<
T extends { code: string },
>(packages: T[]): T[] | undefined {