Merged in feat/BOOK-131-tracking-no-availability (pull request #2886)

feat(BOOK-131): add no availability tracking

* feat(BOOK-131): add no availability tracking

* feat(BOOK-131): add no availability tracking

* feat(BOOK-131): extract noAvailability function

* feat(BOOK-131): fix every render problem

* feat(BOOK-131): noavailability handle return in function


Approved-by: Erik Tiekstra
Approved-by: Joakim Jäderberg
This commit is contained in:
Bianca Widstam
2025-10-07 06:59:49 +00:00
parent 973a665aba
commit 30b214c6ff
12 changed files with 393 additions and 57 deletions

View File

@@ -142,6 +142,11 @@ export function getErrorMessage(
defaultMessage: defaultMessage:
"Membership number can't be the same for two different rooms", "Membership number can't be the same for two different rooms",
}) })
case undefined:
case null:
case "":
return errorCode
default: default:
logger.warn("Error code not supported:", errorCode) logger.warn("Error code not supported:", errorCode)
return errorCode return errorCode

View File

@@ -1,17 +1,19 @@
"use client" "use client"
import { usePathname, useSearchParams } from "next/navigation" import { usePathname, useSearchParams } from "next/navigation"
import { useEffect, useRef, useState } from "react" import { useCallback, useEffect, useRef, useState } from "react"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert" import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
import { selectRate } from "@scandic-hotels/common/constants/routes/hotelReservation" import { selectRate } from "@scandic-hotels/common/constants/routes/hotelReservation"
import useStickyPosition from "@scandic-hotels/common/hooks/useStickyPosition" import useStickyPosition from "@scandic-hotels/common/hooks/useStickyPosition"
import { Alert } from "@scandic-hotels/design-system/Alert" import { Alert } from "@scandic-hotels/design-system/Alert"
import { trackNoAvailability } from "@scandic-hotels/tracking/NoAvailabilityTracking"
import { BookingErrorCodeEnum } from "@scandic-hotels/trpc/enums/bookingErrorCode" import { BookingErrorCodeEnum } from "@scandic-hotels/trpc/enums/bookingErrorCode"
import useLang from "../../../../hooks/useLang" import useLang from "../../../../hooks/useLang"
import { useEnterDetailsStore } from "../../../../stores/enter-details" import { useEnterDetailsStore } from "../../../../stores/enter-details"
import { mapPackageToLabel } from "../../../../utils/getRoomFeatureDescription"
import styles from "./bookingAlert.module.css" import styles from "./bookingAlert.module.css"
@@ -19,6 +21,7 @@ function useBookingErrorAlert() {
const updateSearchParams = useEnterDetailsStore( const updateSearchParams = useEnterDetailsStore(
(state) => state.actions.updateSeachParamString (state) => state.actions.updateSeachParamString
) )
const intl = useIntl() const intl = useIntl()
const lang = useLang() const lang = useLang()
const searchParams = useSearchParams() const searchParams = useSearchParams()
@@ -102,6 +105,12 @@ export default function BookingAlert({ isVisible = false }: BookingAlertProps) {
selectRateReturnUrl, selectRateReturnUrl,
} = useBookingErrorAlert() } = useBookingErrorAlert()
const trackNoAvailabilityError = useNoAvailabilityTracking()
const isAvailabilityError =
errorCode === BookingErrorCodeEnum.AvailabilityError ||
errorCode === BookingErrorCodeEnum.NoAvailabilityForRateAndRoomType
const ref = useRef<HTMLDivElement>(null) const ref = useRef<HTMLDivElement>(null)
const { getTopOffset } = useStickyPosition() const { getTopOffset } = useStickyPosition()
@@ -122,11 +131,13 @@ export default function BookingAlert({ isVisible = false }: BookingAlertProps) {
} }
}, [showAlert, getTopOffset]) }, [showAlert, getTopOffset])
if (!showAlert) return null useEffect(() => {
if (showAlert && isAvailabilityError) {
trackNoAvailabilityError()
}
}, [showAlert, isAvailabilityError, trackNoAvailabilityError])
const isAvailabilityError = if (!showAlert) return null
errorCode === BookingErrorCodeEnum.AvailabilityError ||
errorCode === BookingErrorCodeEnum.NoAvailabilityForRateAndRoomType
return ( return (
<div className={styles.wrapper} ref={ref}> <div className={styles.wrapper} ref={ref}>
@@ -149,3 +160,48 @@ export default function BookingAlert({ isVisible = false }: BookingAlertProps) {
</div> </div>
) )
} }
function useNoAvailabilityTracking() {
const { fromDate, toDate, hotelId, bookingCode, searchType, rooms } =
useEnterDetailsStore((state) => state.booking)
const lang = useLang()
const specialRoomType = rooms
?.map((room) => {
const packages = room.packages
?.map((pkg) => mapPackageToLabel(pkg))
.join(",")
return packages ?? ""
})
.join("|")
const track = useCallback(
() =>
trackNoAvailability({
specialRoomType,
lang,
searchTerm: hotelId,
fromDate,
toDate,
hotelId,
noOfRooms: rooms.length,
searchType,
bookingCode: bookingCode ?? "n/a",
pageId: "details",
pageName: "hotelreservation|details",
pageType: "bookingenterdetailspage",
siteSections: "hotelreservation|details",
}),
[
specialRoomType,
lang,
hotelId,
fromDate,
toDate,
rooms.length,
searchType,
bookingCode,
]
)
return track
}

View File

@@ -1,16 +1,29 @@
"use client" "use client"
import { usePathname, useSearchParams } from "next/navigation" import { usePathname, useSearchParams } from "next/navigation"
import { useEffect } from "react" import { useCallback, useEffect } from "react"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import { toast } from "@scandic-hotels/design-system/Toast" import { toast } from "@scandic-hotels/design-system/Toast"
import { trackNoAvailability } from "@scandic-hotels/tracking/NoAvailabilityTracking"
import { BookingErrorCodeEnum } from "@scandic-hotels/trpc/enums/bookingErrorCode" import { BookingErrorCodeEnum } from "@scandic-hotels/trpc/enums/bookingErrorCode"
export default function AvailabilityError() { import useLang from "../../hooks/useLang"
import { mapPackageToLabel } from "../../utils/getRoomFeatureDescription"
import type { SelectRateBooking } from "../../types/components/selectRate/selectRate"
type AvailabilityErrorProps = {
booking: SelectRateBooking
}
export default function AvailabilityError({ booking }: AvailabilityErrorProps) {
const intl = useIntl() const intl = useIntl()
const pathname = usePathname() const pathname = usePathname()
const searchParams = useSearchParams() const searchParams = useSearchParams()
const lang = useLang()
const { rooms, fromDate, toDate, hotelId, bookingCode, searchType } = booking
const errorCode = searchParams.get("errorCode") const errorCode = searchParams.get("errorCode")
const hasAvailabilityError = const hasAvailabilityError =
@@ -21,15 +34,51 @@ export default function AvailabilityError() {
"Unfortunately, one of the rooms you selected is sold out. Please choose another room to proceed.", "Unfortunately, one of the rooms you selected is sold out. Please choose another room to proceed.",
}) })
const noAvailabilityTracking = useCallback(() => {
const specialRoomType = rooms
?.map((room) => {
const packages = room.packages
?.map((pkg) => {
mapPackageToLabel(pkg)
})
.join(",")
return packages ?? ""
})
.join("|")
trackNoAvailability({
specialRoomType,
searchTerm: hotelId,
lang,
fromDate,
toDate,
noOfRooms: rooms.length,
searchType,
hotelId,
bookingCode,
pageId: "select-rate",
pageName: "hotelreservation|select-rate",
pageType: "bookingroomsandratespage",
siteSections: "hotelreservation|select-rate",
})
}, [rooms, hotelId, lang, fromDate, toDate, searchType, bookingCode])
useEffect(() => { useEffect(() => {
if (hasAvailabilityError) { if (hasAvailabilityError) {
toast.error(errorMessage) toast.error(errorMessage)
noAvailabilityTracking()
const newParams = new URLSearchParams(searchParams.toString()) const newParams = new URLSearchParams(searchParams.toString())
newParams.delete("errorCode") newParams.delete("errorCode")
window.history.replaceState({}, "", `${pathname}?${newParams.toString()}`) window.history.replaceState({}, "", `${pathname}?${newParams.toString()}`)
} }
}, [errorMessage, hasAvailabilityError, pathname, searchParams]) }, [
errorMessage,
hasAvailabilityError,
noAvailabilityTracking,
pathname,
searchParams,
])
return null return null
} }

View File

@@ -0,0 +1,100 @@
"use client"
import { NoAvailabilityTracking } from "@scandic-hotels/tracking/NoAvailabilityTracking"
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
import { AvailabilityEnum } from "@scandic-hotels/trpc/enums/selectHotel"
import { useSelectRateContext } from "../../../contexts/SelectRate/SelectRateContext"
import useLang from "../../../hooks/useLang"
import { mapPackageToLabel } from "../../../utils/getRoomFeatureDescription"
import { getValidDates } from "../getValidDates"
import { getSelectRateTracking } from "./tracking"
import type { RouterOutput } from "@scandic-hotels/trpc/client"
import type { SelectRateBooking } from "../../../types/components/selectRate/selectRate"
interface TrackingProps {
hotelData: NonNullable<RouterOutput["hotel"]["get"]>
booking: SelectRateBooking
}
export function SelectRateTracking({ hotelData, booking }: TrackingProps) {
const lang = useLang()
const { availability, input } = useSelectRateContext()
const { fromDate, toDate } = getValidDates(booking.fromDate, booking.toDate)
const { rooms, searchType, bookingCode, city: paramCity } = booking
const arrivalDate = fromDate.toDate()
const departureDate = toDate.toDate()
const specialRoomType = input.data?.booking.rooms
?.map((room) => {
const packages = room.packages
?.map((pkg) => mapPackageToLabel(pkg))
.join(",")
return packages ?? ""
})
.join("|")
const { hotelsTrackingData, pageTrackingData } = getSelectRateTracking({
lang,
arrivalDate,
departureDate,
hotelId: hotelData.hotel.id,
hotelName: hotelData.hotel.name,
country: hotelData.hotel.address.country,
hotelCity: hotelData.hotel.address.city,
paramCity,
bookingCode,
isRedemption: searchType === SEARCH_TYPE_REDEMPTION,
specialRoomType,
rooms,
})
let shouldTrackNoAvailability = false
if (availability && !availability.isFetching && availability.data) {
shouldTrackNoAvailability = availability.data.some((room) => {
if (!room || "error" in room) return false
const allRoomsNotAvailable = room.roomConfigurations.every(
(roomConfig) => roomConfig.status === AvailabilityEnum.NotAvailable
)
const isPublicPromotionWithCode = room.roomConfigurations.some((r) => {
const filteredCampaigns = r.campaign.filter(Boolean)
return filteredCampaigns.length
? filteredCampaigns.every(
(product) => !!product.rateDefinition?.isCampaignRate
)
: false
})
const noAvailableBookingCodeRooms =
!isPublicPromotionWithCode &&
room.roomConfigurations.every(
(r) => r.status === AvailabilityEnum.NotAvailable || !r.code.length
)
return (
allRoomsNotAvailable ||
(input.bookingCode && noAvailableBookingCodeRooms)
)
})
}
return (
<>
<NoAvailabilityTracking
lang={lang}
shouldTrackNoAvailability={shouldTrackNoAvailability}
hotelsTrackingData={hotelsTrackingData}
pageTrackingData={pageTrackingData}
/>
<TrackingSDK hotelInfo={hotelsTrackingData} pageData={pageTrackingData} />
</>
)
}

View File

@@ -8,7 +8,6 @@ import {
type TrackingSDKPageData, type TrackingSDKPageData,
} from "@scandic-hotels/tracking/types" } from "@scandic-hotels/tracking/types"
import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum" import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum"
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
import type { Lang } from "@scandic-hotels/common/constants/language" import type { Lang } from "@scandic-hotels/common/constants/language"
import type { Child } from "@scandic-hotels/trpc/types/child" import type { Child } from "@scandic-hotels/trpc/types/child"
@@ -28,6 +27,7 @@ type SelectRateTrackingInput = {
paramCity: string | undefined paramCity: string | undefined
bookingCode?: string bookingCode?: string
isRedemption?: boolean isRedemption?: boolean
specialRoomType?: string
rooms?: Room[] rooms?: Room[]
} }
@@ -42,6 +42,7 @@ export function getSelectRateTracking({
paramCity, paramCity,
bookingCode, bookingCode,
isRedemption = false, isRedemption = false,
specialRoomType,
rooms = [], rooms = [],
}: SelectRateTrackingInput) { }: SelectRateTrackingInput) {
const pageTrackingData: TrackingSDKPageData = { const pageTrackingData: TrackingSDKPageData = {
@@ -83,25 +84,7 @@ export function getSelectRateTracking({
searchType: "hotel", searchType: "hotel",
bookingCode: bookingCode ?? "n/a", bookingCode: bookingCode ?? "n/a",
rewardNight: isRedemption ? "yes" : "no", rewardNight: isRedemption ? "yes" : "no",
specialRoomType: rooms specialRoomType,
?.map((room) => {
const packages = room.packages
?.map((pkg) => {
if (pkg === RoomPackageCodeEnum.ACCESSIBILITY_ROOM) {
return "accessibility"
} else if (pkg === RoomPackageCodeEnum.ALLERGY_ROOM) {
return "allergy friendly"
} else if (pkg === RoomPackageCodeEnum.PET_ROOM) {
return "pet room"
} else {
return ""
}
})
.join(",")
return packages ?? ""
})
.join("|"),
} }
return { return {

View File

@@ -87,7 +87,7 @@ export async function SelectRate({
/> />
)} )}
<AvailabilityError /> <AvailabilityError booking={booking} />
</> </>
) )
} }

View File

@@ -4,6 +4,7 @@ import { notFound } from "next/navigation"
import { Suspense } from "react" import { Suspense } from "react"
import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAndFriends" import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAndFriends"
import { NoAvailabilityTracking } from "@scandic-hotels/tracking/NoAvailabilityTracking"
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK" import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
import { AlternativeHotelsPageTitle } from "../components/AlternativeHotelsPageTitle" import { AlternativeHotelsPageTitle } from "../components/AlternativeHotelsPageTitle"
@@ -110,6 +111,10 @@ export async function AlternativeHotelsPage({
const suspenseKey = stringify(searchParams) const suspenseKey = stringify(searchParams)
const shouldTrackNoAvailability = !!(
hotels.every((hotel) => hotel.availability.status !== "Available") ||
(booking.bookingCode && hotels.length > 0 && !isBookingCodeRateAvailable)
)
return ( return (
<> <>
<SelectHotel <SelectHotel
@@ -128,6 +133,12 @@ export async function AlternativeHotelsPage({
hotelInfo={hotelsTrackingData} hotelInfo={hotelsTrackingData}
pageData={pageTrackingData} pageData={pageTrackingData}
/> />
<NoAvailabilityTracking
lang={lang}
hotelsTrackingData={hotelsTrackingData}
pageTrackingData={pageTrackingData}
shouldTrackNoAvailability={shouldTrackNoAvailability}
/>
</Suspense> </Suspense>
</> </>
) )

View File

@@ -4,6 +4,7 @@ import { notFound } from "next/navigation"
import { Suspense } from "react" import { Suspense } from "react"
import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAndFriends" import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAndFriends"
import { NoAvailabilityTracking } from "@scandic-hotels/tracking/NoAvailabilityTracking"
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK" import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
import FnFNotAllowedAlert from "../components/FnFNotAllowedAlert" import FnFNotAllowedAlert from "../components/FnFNotAllowedAlert"
@@ -85,7 +86,7 @@ export async function SelectHotelPage({
arrivalDate, arrivalDate,
departureDate, departureDate,
hotelsResult: hotels?.length ?? 0, hotelsResult: hotels?.length ?? 0,
searchTerm: booking.hotelId, searchTerm: city.name,
country: hotels?.[0]?.hotel.address.country, country: hotels?.[0]?.hotel.address.country,
hotelCity: hotels?.[0]?.hotel.address.city, hotelCity: hotels?.[0]?.hotel.address.city,
bookingCode: booking.bookingCode, bookingCode: booking.bookingCode,
@@ -96,6 +97,11 @@ export async function SelectHotelPage({
const suspenseKey = stringify(searchParams) const suspenseKey = stringify(searchParams)
const shouldTrackNoAvailability = !!(
hotels.every((hotel) => hotel.availability.status !== "Available") ||
(booking.bookingCode && hotels.length > 0 && !isBookingCodeRateAvailable)
)
return ( return (
<> <>
<SelectHotel <SelectHotel
@@ -111,6 +117,12 @@ export async function SelectHotelPage({
hotelInfo={hotelsTrackingData} hotelInfo={hotelsTrackingData}
pageData={pageTrackingData} pageData={pageTrackingData}
/> />
<NoAvailabilityTracking
lang={lang}
hotelsTrackingData={hotelsTrackingData}
pageTrackingData={pageTrackingData}
shouldTrackNoAvailability={shouldTrackNoAvailability}
/>
</Suspense> </Suspense>
</> </>
) )

View File

@@ -1,12 +1,10 @@
import { notFound } from "next/navigation" import { notFound } from "next/navigation"
import { logger } from "@scandic-hotels/common/logger" import { logger } from "@scandic-hotels/common/logger"
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
import { SelectRate } from "../components/SelectRate" import { SelectRate } from "../components/SelectRate"
import { getValidDates } from "../components/SelectRate/getValidDates" import { SelectRateTracking } from "../components/SelectRate/Tracking/SelectRateTracking"
import { getSelectRateTracking } from "../components/SelectRate/Tracking/tracking"
import { SelectRateProvider } from "../contexts/SelectRate/SelectRateContext" import { SelectRateProvider } from "../contexts/SelectRate/SelectRateContext"
import { getHotel } from "../trpc/memoizedRequests" import { getHotel } from "../trpc/memoizedRequests"
import { parseSelectRateSearchParams } from "../utils/url" import { parseSelectRateSearchParams } from "../utils/url"
@@ -72,33 +70,12 @@ export async function SelectRatePage({
notFound() notFound()
} }
const { fromDate, toDate } = getValidDates(booking.fromDate, booking.toDate)
const { rooms, searchType, bookingCode, city: paramCity } = booking
const arrivalDate = fromDate.toDate()
const departureDate = toDate.toDate()
const { hotelsTrackingData, pageTrackingData } = getSelectRateTracking({
lang,
arrivalDate,
departureDate,
hotelId: hotelData.hotel.id,
hotelName: hotelData.hotel.name,
country: hotelData.hotel.address.country,
hotelCity: hotelData.hotel.address.city,
paramCity,
bookingCode,
isRedemption: searchType === SEARCH_TYPE_REDEMPTION,
rooms,
})
return ( return (
<> <>
<SelectRateProvider hotelData={hotelData}> <SelectRateProvider hotelData={hotelData}>
<SelectRate hotelData={hotelData} booking={booking} /> <SelectRate hotelData={hotelData} booking={booking} />
<SelectRateTracking hotelData={hotelData} booking={booking} />
</SelectRateProvider> </SelectRateProvider>
<TrackingSDK hotelInfo={hotelsTrackingData} pageData={pageTrackingData} />
</> </>
) )
} }

View File

@@ -1,5 +1,6 @@
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter" import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
import type { PackageEnum } from "@scandic-hotels/trpc/types/packages"
import type { IntlShape } from "react-intl" import type { IntlShape } from "react-intl"
export function getRoomFeatureDescription( export function getRoomFeatureDescription(
@@ -21,3 +22,16 @@ export function getRoomFeatureDescription(
return roomFeatureDescriptions[code] ?? description return roomFeatureDescriptions[code] ?? description
} }
export function mapPackageToLabel(pkgCode: PackageEnum): string {
switch (pkgCode) {
case RoomPackageCodeEnum.ACCESSIBILITY_ROOM:
return "accessibility"
case RoomPackageCodeEnum.ALLERGY_ROOM:
return "allergy friendly"
case RoomPackageCodeEnum.PET_ROOM:
return "pet room"
default:
return ""
}
}

View File

@@ -0,0 +1,128 @@
"use client"
import { differenceInCalendarDays, isWeekend } from "date-fns"
import { useEffect } from "react"
import {
TrackingChannelEnum,
type TrackingSDKHotelInfo,
type TrackingSDKPageData,
} from "@scandic-hotels/tracking/types"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
import { trackEvent } from "./base"
import type { Lang } from "@scandic-hotels/common/constants/language"
type NoAvailabilityTrackingProps = {
lang: Lang
shouldTrackNoAvailability: boolean
hotelsTrackingData: TrackingSDKHotelInfo
pageTrackingData: TrackingSDKPageData
}
export function NoAvailabilityTracking({
lang,
shouldTrackNoAvailability,
hotelsTrackingData,
pageTrackingData,
}: NoAvailabilityTrackingProps) {
useEffect(() => {
if (!shouldTrackNoAvailability) {
return
}
const {
searchTerm,
searchType,
hotelID,
leadTime,
noOfRooms,
bookingCode,
rewardNight,
bookingTypeofDay,
duration,
specialRoomType,
} = hotelsTrackingData
trackEvent({
event: "noRoomsAvailable",
hotelInfo: {
searchTerm,
searchType,
noRoomsAvailable: "yes",
hotelID,
leadTime,
noOfRooms,
bookingCode,
rewardNight,
bookingTypeofDay,
duration,
specialRoomType,
},
pageInfo: pageTrackingData,
})
}, [lang, hotelsTrackingData, pageTrackingData])
return null
}
type TrackNoAvailabilityParams = {
specialRoomType: string
fromDate: string
toDate: string
hotelId: string
noOfRooms: number
searchType?: string
bookingCode?: string
searchTerm: string
pageId: string
pageName: string
pageType: string
siteSections: string
lang: Lang
}
export function trackNoAvailability({
specialRoomType,
lang,
fromDate,
toDate,
hotelId,
noOfRooms,
searchType,
bookingCode,
searchTerm,
pageId,
pageName,
pageType,
siteSections,
}: TrackNoAvailabilityParams) {
const arrivalDate = new Date(fromDate)
const departureDate = new Date(toDate)
trackEvent({
event: "noRoomsAvailable",
hotelInfo: {
searchTerm,
searchType,
noRoomsAvailable: "yes",
hotelId,
leadTime: differenceInCalendarDays(arrivalDate, new Date()),
noOfRooms,
bookingCode: bookingCode ?? "n/a",
rewardNight: searchType === SEARCH_TYPE_REDEMPTION ? "yes" : "no",
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
duration: differenceInCalendarDays(departureDate, arrivalDate),
specialRoomType,
},
pageInfo: {
channel: TrackingChannelEnum.hotelreservation,
domain: "www.scandichotels.com",
domainLanguage: lang,
pageId,
pageName,
pageType,
siteSections,
},
})
}

View File

@@ -12,7 +12,8 @@
}, },
"exports": { "exports": {
"./*": "./lib/*.ts", "./*": "./lib/*.ts",
"./TrackingSDK": "./lib/TrackingSDK.tsx" "./TrackingSDK": "./lib/TrackingSDK.tsx",
"./NoAvailabilityTracking": "./lib/NoAvailabilityTracking.tsx"
}, },
"dependencies": { "dependencies": {
"@scandic-hotels/common": "workspace:*", "@scandic-hotels/common": "workspace:*",