import stringify from "json-stable-stringify-without-jsonify" import { cookies } from "next/headers" import { notFound } from "next/navigation" import { Suspense } from "react" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { FamilyAndFriendsCodes } from "@/constants/booking" import { alternativeHotels, alternativeHotelsMap, selectHotel, selectHotelMap, } from "@/constants/routes/hotelReservation" import StaticMap from "@/components/Maps/StaticMap" import Breadcrumbs from "@/components/TempDesignSystem/Breadcrumbs" import Button from "@/components/TempDesignSystem/Button" import Link from "@/components/TempDesignSystem/Link" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import TrackingSDK from "@/components/TrackingSDK" import { getIntl } from "@/i18n" import { getHotelSearchDetails } from "@/utils/hotelSearchDetails" import { convertObjToSearchParams } from "@/utils/url" import FnFNotAllowedAlert from "../FnFNotAllowedAlert/FnFNotAllowedAlert" import HotelCardListing from "../HotelCardListing" import BookingCodeFilter from "./BookingCodeFilter" import { getFiltersFromHotels, getHotels } from "./helpers" import HotelCount from "./HotelCount" import HotelFilter from "./HotelFilter" import HotelSorter from "./HotelSorter" import MobileMapButtonContainer from "./MobileMapButtonContainer" import NoAvailabilityAlert from "./NoAvailabilityAlert" import { getTracking } from "./tracking" import styles from "./selectHotel.module.css" import type { SelectHotelProps } from "@/types/components/hotelReservation/selectHotel/selectHotel" import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams" export default async function SelectHotel({ params, searchParams, isAlternativeHotels, }: SelectHotelProps) { const intl = await getIntl() const searchDetails = await getHotelSearchDetails( { searchParams: searchParams as SelectHotelSearchParams & { [key: string]: string }, }, isAlternativeHotels ) if (!searchDetails) return notFound() const { adultsInRoom, bookingCode, childrenInRoom, city, hotel: isAlternativeFor, noOfRooms, redemption, selectHotelParams, } = searchDetails if (!city) return notFound() if (bookingCode && FamilyAndFriendsCodes.includes(bookingCode)) { const cookieStore = cookies() const isInValidFNF = cookieStore.get("sc")?.value !== "1" if (isInValidFNF) { return } } const hotels = await getHotels( selectHotelParams, isAlternativeFor, bookingCode, city, !!redemption ) const arrivalDate = new Date(selectHotelParams.fromDate) const departureDate = new Date(selectHotelParams.toDate) const isCityWithCountry = (city: any): city is { country: string } => "country" in city const filterList = getFiltersFromHotels(hotels) const convertedSearchParams = convertObjToSearchParams(selectHotelParams) const breadcrumbs = [ { title: intl.formatMessage({ defaultMessage: "Home", }), href: `/${params.lang}`, uid: "home-page", }, { title: intl.formatMessage({ defaultMessage: "Hotel reservation", }), href: `/${params.lang}/hotelreservation`, uid: "hotel-reservation", }, isAlternativeFor ? { title: intl.formatMessage({ defaultMessage: "Alternative hotels", }), href: `${alternativeHotels(params.lang)}/?${convertedSearchParams}`, uid: "alternative-hotels", } : { title: intl.formatMessage({ defaultMessage: "Select hotel", }), href: `${selectHotel(params.lang)}/?${convertedSearchParams}`, uid: "select-hotel", }, isAlternativeFor ? { title: isAlternativeFor.name, uid: isAlternativeFor.id, } : { title: city.name, uid: city.id, }, ] const isAllUnavailable = !hotels.length const isRedemptionAvailability = redemption ? hotels.some( (hotel) => hotel.availability.productType?.redemptions?.length ) : false const suspenseKey = stringify(searchParams) const isFullPriceHotelAvailable = bookingCode ? hotels?.some( (hotel) => !hotel.availability.productType?.public?.bookingCode && !hotel.availability.productType?.member?.bookingCode ) : false const isBookingCodeRateAvailable = bookingCode ? hotels?.some( (hotel) => hotel.availability.productType?.public?.bookingCode || hotel.availability.productType?.member?.bookingCode ) : false const { hotelsTrackingData, pageTrackingData } = getTracking( params.lang, !!isAlternativeFor, arrivalDate, departureDate, adultsInRoom, childrenInRoom, hotels?.length ?? 0, selectHotelParams.hotelId, noOfRooms, hotels?.[0]?.hotel.address.country, hotels?.[0]?.hotel.address.city, selectHotelParams.city, bookingCode, isBookingCodeRateAvailable ? "true" : "false", redemption, isRedemptionAvailability ) // Special rates (corporate cheque, voucher and reward nights) will not have regular rate hotels availability const isSpecialRate = hotels?.some( (hotel) => hotel.availability.productType?.bonusCheque || hotel.availability.productType?.voucher || hotel.availability.productType?.redemptions ) return ( <>
{isAlternativeFor ? intl.formatMessage( { defaultMessage: "Alternatives for {value}", }, { value: isAlternativeFor.name, } ) : city.name}
{isBookingCodeRateAvailable && isFullPriceHotelAvailable && !isSpecialRate ? ( ) : null}
{hotels.length ? (
) : (
)}
) }