Files
web/packages/booking-flow/lib/pages/AlternativeHotelsMapPage.tsx
Anton Gunnarsson 87402a2092 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
2025-09-01 08:37:00 +00:00

135 lines
3.8 KiB
TypeScript

import { notFound } from "next/navigation"
import { Suspense } from "react"
import { safeTry } from "@scandic-hotels/common/utils/safeTry"
import { env } from "../../env/server"
import { MapContainer } from "../components/MapContainer"
import {
getFiltersFromHotels,
getHotels,
} from "../components/SelectHotel/helpers"
import {
SelectHotelMap,
SelectHotelMapSkeleton,
} from "../components/SelectHotel/SelectHotelMap"
import { getHotelSearchDetails } from "../misc/getHotelSearchDetails"
import { getSelectHotelTracking } from "../misc/selectHotelTracking"
import { getCityCoordinates } from "../trpc/memoizedRequests/getCityCoordinates"
import { parseSelectHotelSearchParams } from "../utils/url"
import type { Lang } from "@scandic-hotels/common/constants/language"
import type {
TrackingSDKHotelInfo,
TrackingSDKPageData,
} from "@scandic-hotels/common/tracking/types"
import type { NextSearchParams } from "../types"
export async function AlternativeHotelsMapPage({
lang,
searchParams,
renderTracking,
}: {
lang: Lang
searchParams: NextSearchParams
renderTracking: (trackingProps: {
hotelsTrackingData: TrackingSDKHotelInfo
pageTrackingData: TrackingSDKPageData
}) => React.ReactNode
}) {
const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
const booking = parseSelectHotelSearchParams(searchParams)
if (!booking) return notFound()
const getHotelSearchDetailsPromise = safeTry(
getHotelSearchDetails({ ...booking, lang, isAlternativeHotels: true })
)
const [searchDetails] = await getHotelSearchDetailsPromise
if (!searchDetails) {
return notFound()
}
const {
city,
cityIdentifier,
hotel: isAlternativeFor,
redemption,
} = searchDetails
if (!city) {
return notFound()
}
const hotels = await getHotels({
fromDate: booking.fromDate,
toDate: booking.toDate,
rooms: booking.rooms,
isAlternativeFor,
bookingCode: booking.bookingCode,
city,
redemption: !!redemption,
lang,
})
const cityCoordinates = await getCityCoordinates({
city: city.name,
hotel: { address: hotels?.[0]?.hotel?.address.streetAddress },
})
const arrivalDate = new Date(booking.fromDate)
const departureDate = new Date(booking.toDate)
const isRedemptionAvailability = redemption
? hotels.some(
(hotel) => hotel.availability.productType?.redemptions?.length
)
: false
const isBookingCodeRateAvailable = booking.bookingCode
? hotels?.some((hotel) => hotel.availability.bookingCode)
: false
const { hotelsTrackingData, pageTrackingData } = getSelectHotelTracking({
lang,
pageId: isAlternativeFor ? "alternative-hotels" : "select-hotel",
pageName: "hotelreservation|alternative-hotels|mapview",
siteSections: "hotelreservation|altervative-hotels|mapview",
arrivalDate,
departureDate,
rooms: booking.rooms,
hotelsResult: hotels.length,
searchTerm: isAlternativeFor ? booking.hotelId : cityIdentifier,
country: hotels?.[0]?.hotel.address.country,
hotelCity: hotels?.[0]?.hotel.address.city,
bookingCode: booking.bookingCode,
isBookingCodeRateAvailable,
isRedemption: redemption,
isRedemptionAvailable: isRedemptionAvailability,
})
const filterList = getFiltersFromHotels(hotels)
return (
<MapContainer>
<Suspense key={booking.hotelId} fallback={<SelectHotelMapSkeleton />}>
<SelectHotelMap
apiKey={googleMapsApiKey}
mapId={googleMapId}
hotels={hotels}
cityCoordinates={cityCoordinates}
bookingCode={booking.bookingCode}
isBookingCodeRateAvailable={isBookingCodeRateAvailable}
isAlternativeHotels={true}
filterList={filterList}
/>
{renderTracking({ hotelsTrackingData, pageTrackingData })}
</Suspense>
</MapContainer>
)
}