Merged in feat/sw-2873-move-selecthotel-to-booking-flow (pull request #2727)

feat(SW-2873): Move select-hotel to booking flow

* crude setup of select-hotel in partner-sas

* wip

* Fix linting

* restructure tracking files

* Remove dependency on trpc in tracking hooks

* Move pageview tracking to common

* Fix some lint and import issues

* Add AlternativeHotelsPage

* Add SelectHotelMapPage

* Add AlternativeHotelsMapPage

* remove next dependency in tracking store

* Remove dependency on react in tracking hooks

* move isSameBooking to booking-flow

* Inject searchParamsComparator into tracking store

* Move useTrackHardNavigation to common

* Move useTrackSoftNavigation to common

* Add TrackingSDK to partner-sas

* call serverclient in layout

* Remove unused css

* Update types

* Move HotelPin type

* Fix todos

* Merge branch 'master' into feat/sw-2873-move-selecthotel-to-booking-flow

* Merge branch 'master' into feat/sw-2873-move-selecthotel-to-booking-flow

* Fix component


Approved-by: Joakim Jäderberg
This commit is contained in:
Anton Gunnarsson
2025-09-01 08:37:00 +00:00
parent 93a90bef9d
commit 87402a2092
157 changed files with 2026 additions and 1376 deletions

View File

@@ -1,77 +0,0 @@
import { notFound } from "next/navigation"
import { safeTry } from "@scandic-hotels/common/utils/safeTry"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
import {
type HotelLocation,
isHotelLocation,
type Location,
} from "@scandic-hotels/trpc/types/locations"
import { getLocations } from "@/lib/trpc/memoizedRequests"
import type { BookingSearchType } from "@scandic-hotels/booking-flow/searchType"
import type { Child } from "@scandic-hotels/trpc/types/child"
export type ChildrenInRoom = (Child[] | null)[] | null
interface HotelSearchDetails {
city: Location | null
cityIdentifier: string | undefined
hotel: HotelLocation | null
redemption?: boolean
}
export async function getHotelSearchDetails(
params: {
hotelId?: string
city?: string
rooms?: {
adults: number
childrenInRoom?: Child[]
}[]
searchType?: BookingSearchType
},
isAlternativeHotels?: boolean
): Promise<HotelSearchDetails | null> {
const [locations, error] = await safeTry(getLocations())
if (!locations || error) {
return null
}
const hotel = params.hotelId
? ((locations.find(
(location) =>
isHotelLocation(location) &&
"operaId" in location &&
location.operaId === params.hotelId
) as HotelLocation | undefined) ?? null)
: null
if (isAlternativeHotels && !hotel) {
return notFound()
}
const cityIdentifier = isAlternativeHotels
? hotel?.relationships.city.cityIdentifier
: params.city
const city = cityIdentifier
? (locations.find(
(location) =>
"cityIdentifier" in location &&
location.cityIdentifier?.toLowerCase() ===
cityIdentifier.toLowerCase()
) ?? null)
: null
if (!city && !hotel) return notFound()
if (isAlternativeHotels && (!city || !hotel)) return notFound()
return {
city,
cityIdentifier,
hotel,
redemption: params.searchType === SEARCH_TYPE_REDEMPTION,
}
}

View File

@@ -1,12 +0,0 @@
export const promiseWithTimeout = <T>(
promise: Promise<T>,
timeoutMs: number,
fallbackValue: T | undefined = undefined
) => {
return Promise.race([
promise,
new Promise<T | undefined>((resolve) =>
setTimeout(() => resolve(fallbackValue), timeoutMs)
),
])
}

View File

@@ -3,7 +3,7 @@
import { trackEvent } from "@scandic-hotels/common/tracking/base"
import type { BreakfastPackages } from "@/types/components/hotelReservation/breakfast"
import type { LowestRoomPriceEvent } from "@/types/components/tracking"
import type { LowestRoomPriceEvent } from "@scandic-hotels/common/tracking/types"
export function trackLowestRoomPrice(event: LowestRoomPriceEvent) {
trackEvent({

View File

@@ -11,10 +11,10 @@ export {
trackLoginClick,
trackSocialMediaClick,
} from "./navigation"
export { trackPaymentEvent, trackUpdatePaymentMethod } from "./payment"
export { trackClick } from "@scandic-hotels/common/tracking/base"
export {
createSDKPageObject,
trackPageView,
trackPageViewStart,
} from "./pageview"
export { trackPaymentEvent, trackUpdatePaymentMethod } from "./payment"
export { trackClick } from "@scandic-hotels/common/tracking/base"
} from "@scandic-hotels/common/tracking/pageview"

View File

@@ -1,6 +1,6 @@
import { trackEvent } from "@scandic-hotels/common/tracking/base"
import type { TrackingPosition } from "@/types/components/tracking"
import type { TrackingPosition } from "@scandic-hotels/common/tracking/types"
export function trackFooterClick(group: string, name: string) {
trackEvent({

View File

@@ -1,37 +0,0 @@
import { trackEvent } from "@scandic-hotels/common/tracking/base"
import type { TrackingSDKData } from "@/types/components/tracking"
function convertSlashToPipe(url: string) {
const formattedUrl = url.startsWith("/") ? url.slice(1) : url
return formattedUrl.replaceAll("/", "|")
}
export function trackPageViewStart() {
trackEvent({
event: "pageViewStart",
})
}
export function trackPageView(data: any) {
trackEvent(data)
}
export function createSDKPageObject(
trackingData: TrackingSDKData
): TrackingSDKData {
let pageName = convertSlashToPipe(trackingData.pageName)
let siteSections = convertSlashToPipe(trackingData.siteSections)
if (trackingData.pathName.indexOf("/webview/") > -1) {
pageName = "webview|" + pageName
siteSections = "webview|" + siteSections
}
return {
...trackingData,
domain: typeof window !== "undefined" ? window.location.host : "",
pageName: pageName,
siteSections: siteSections,
}
}

View File

@@ -3,7 +3,7 @@ import { trackEvent } from "@scandic-hotels/common/tracking/base"
import type {
PaymentEvent,
PaymentFailEvent,
} from "@/types/components/tracking"
} from "@scandic-hotels/common/tracking/types"
function isPaymentFailEvent(event: PaymentEvent): event is PaymentFailEvent {
return "errorMessage" in event