141 lines
4.4 KiB
TypeScript
141 lines
4.4 KiB
TypeScript
import { cookies } from "next/headers"
|
|
import { notFound } from "next/navigation"
|
|
|
|
import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAndFriends"
|
|
import { NoAvailabilityTracking } from "@scandic-hotels/tracking/NoAvailabilityTracking"
|
|
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
|
|
|
import { BookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
|
|
import { AlternativeHotelsPageTitle } from "../components/AlternativeHotelsPageTitle"
|
|
import FnFNotAllowedAlert from "../components/FnFNotAllowedAlert"
|
|
import { SelectHotel } from "../components/SelectHotel"
|
|
import { getHotels } from "../components/SelectHotel/helpers"
|
|
import { getHotelSearchDetails } from "../misc/getHotelSearchDetails"
|
|
import { getSelectHotelTracking } from "../misc/selectHotelTracking"
|
|
import { parseSelectHotelSearchParams } from "../utils/url"
|
|
|
|
import type { Lang } from "@scandic-hotels/common/constants/language"
|
|
|
|
import type { NextSearchParams } from "../types"
|
|
|
|
export { SelectHotelSkeleton as AlternativeHotelsPageSkeleton } from "../components/SelectHotel"
|
|
|
|
export async function AlternativeHotelsPage({
|
|
lang,
|
|
searchParams,
|
|
config,
|
|
}: {
|
|
lang: Lang
|
|
searchParams: NextSearchParams
|
|
config: BookingFlowConfig
|
|
}) {
|
|
const booking = parseSelectHotelSearchParams(searchParams)
|
|
|
|
if (!booking) return notFound()
|
|
|
|
const searchDetails = await getHotelSearchDetails({
|
|
...booking,
|
|
lang,
|
|
isAlternativeHotels: true,
|
|
})
|
|
|
|
if (!searchDetails || !searchDetails.hotel || !searchDetails.city) {
|
|
return notFound()
|
|
}
|
|
|
|
// TODO move logic to function to reuse
|
|
if (
|
|
booking.bookingCode &&
|
|
FamilyAndFriendsCodes.includes(booking.bookingCode)
|
|
) {
|
|
const cookieStore = await cookies()
|
|
const isInvalidFNF = cookieStore.get("sc")?.value !== "1"
|
|
|
|
if (isInvalidFNF) {
|
|
return <FnFNotAllowedAlert />
|
|
}
|
|
}
|
|
|
|
// TODO: This needs to be refactored into its
|
|
// own functions
|
|
const hotels = await getHotels({
|
|
fromDate: booking.fromDate,
|
|
toDate: booking.toDate,
|
|
rooms: booking.rooms,
|
|
isAlternativeFor: searchDetails.hotel,
|
|
bookingCode: booking.bookingCode,
|
|
city: searchDetails.city,
|
|
redemption: !!searchDetails.redemption,
|
|
lang,
|
|
})
|
|
|
|
const arrivalDate = new Date(booking.fromDate)
|
|
const departureDate = new Date(booking.toDate)
|
|
|
|
const isRedemptionAvailability = searchDetails.redemption
|
|
? hotels.some(
|
|
(hotel) => hotel.availability.productType?.redemptions?.length
|
|
)
|
|
: false
|
|
|
|
const isBookingCodeRateAvailable = booking.bookingCode
|
|
? hotels.some(
|
|
(hotel) =>
|
|
hotel.availability.bookingCode &&
|
|
hotel.availability.status === "Available"
|
|
)
|
|
: false
|
|
|
|
const { hotelsTrackingData, pageTrackingData } = getSelectHotelTracking({
|
|
lang,
|
|
pageId: searchDetails.hotel ? "alternative-hotels" : "select-hotel",
|
|
pageName: searchDetails.hotel
|
|
? "hotelreservation|alternative-hotels"
|
|
: "hotelreservation|select-hotel",
|
|
siteSections: searchDetails.hotel
|
|
? "hotelreservation|alternative-hotels"
|
|
: "hotelreservation|select-hotel",
|
|
arrivalDate,
|
|
departureDate,
|
|
rooms: booking.rooms,
|
|
hotelsResult: hotels?.length ?? 0,
|
|
searchTerm: searchDetails.hotel
|
|
? searchDetails.hotel.name
|
|
: searchDetails.cityIdentifier,
|
|
country: hotels?.[0]?.hotel.address.country,
|
|
hotelCity: hotels?.[0]?.hotel.address.city,
|
|
bookingCode: booking.bookingCode,
|
|
isBookingCodeRateAvailable,
|
|
isRedemption: searchDetails.redemption,
|
|
isRedemptionAvailable: isRedemptionAvailability,
|
|
config,
|
|
})
|
|
|
|
const shouldTrackNoAvailability = !!(
|
|
hotels.every((hotel) => hotel.availability.status !== "Available") ||
|
|
(booking.bookingCode && hotels.length > 0 && !isBookingCodeRateAvailable)
|
|
)
|
|
return (
|
|
<BookingFlowConfig config={config}>
|
|
<SelectHotel
|
|
bookingCode={booking.bookingCode}
|
|
city={searchDetails.city}
|
|
hotels={hotels}
|
|
isAlternative={!!searchDetails.hotel}
|
|
isBookingCodeRateAvailable={isBookingCodeRateAvailable}
|
|
title={
|
|
<AlternativeHotelsPageTitle hotelName={searchDetails.hotel.name} />
|
|
}
|
|
lang={lang}
|
|
/>
|
|
<NoAvailabilityTracking
|
|
lang={lang}
|
|
hotelsTrackingData={hotelsTrackingData}
|
|
pageTrackingData={pageTrackingData}
|
|
shouldTrackNoAvailability={shouldTrackNoAvailability}
|
|
/>
|
|
<TrackingSDK hotelInfo={hotelsTrackingData} pageData={pageTrackingData} />
|
|
</BookingFlowConfig>
|
|
)
|
|
}
|