132 lines
4.3 KiB
TypeScript
132 lines
4.3 KiB
TypeScript
"use client"
|
|
import { useSearchParams } from "next/navigation"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { alternativeHotels } from "@/constants/routes/hotelReservation"
|
|
import { useBookingCodeFilterStore } from "@/stores/bookingCode-filter"
|
|
|
|
import BookingCodeFilter from "@/components/HotelReservation/SelectHotel/BookingCodeFilter"
|
|
import Alert from "@/components/TempDesignSystem/Alert"
|
|
import { useRoomContext } from "@/contexts/Room"
|
|
import useLang from "@/hooks/useLang"
|
|
|
|
import RoomCard from "./RoomCard"
|
|
import RoomTypeFilter from "./RoomTypeFilter"
|
|
|
|
import styles from "./roomSelectionPanel.module.css"
|
|
|
|
import { AvailabilityEnum } from "@/types/components/hotelReservation/selectHotel/selectHotel"
|
|
import { AlertTypeEnum } from "@/types/enums/alert"
|
|
import { BookingCodeFilterEnum } from "@/types/enums/bookingCodeFilter"
|
|
import { RateTypeEnum } from "@/types/enums/rateType"
|
|
|
|
export default function RoomSelectionPanel() {
|
|
const { rooms } = useRoomContext()
|
|
const searchParams = useSearchParams()
|
|
const bookingCode = searchParams.get("bookingCode")
|
|
const intl = useIntl()
|
|
const lang = useLang()
|
|
const noAvailableRooms = rooms.every(
|
|
(roomConfig) => roomConfig.status === AvailabilityEnum.NotAvailable
|
|
)
|
|
const activeCodeFilter = useBookingCodeFilterStore(
|
|
(state) => state.activeCodeFilter
|
|
)
|
|
|
|
let filteredRooms = rooms,
|
|
isRegularRatesAvailableWithCode: boolean = false,
|
|
noAvailabilityWithBookingCode: boolean = false
|
|
if (bookingCode) {
|
|
isRegularRatesAvailableWithCode = bookingCode
|
|
? rooms?.some((room) => {
|
|
return (
|
|
room.status === AvailabilityEnum.Available &&
|
|
room.products.some(
|
|
(product) =>
|
|
product.productType.public.rateType === RateTypeEnum.Regular
|
|
)
|
|
)
|
|
})
|
|
: false
|
|
|
|
noAvailabilityWithBookingCode = bookingCode
|
|
? !rooms?.some((room) => {
|
|
return (
|
|
room.status === AvailabilityEnum.Available &&
|
|
room.products.some(
|
|
(product) =>
|
|
product.productType.public.rateType !== RateTypeEnum.Regular
|
|
)
|
|
)
|
|
})
|
|
: false
|
|
|
|
filteredRooms =
|
|
noAvailabilityWithBookingCode ||
|
|
!isRegularRatesAvailableWithCode ||
|
|
activeCodeFilter === BookingCodeFilterEnum.All
|
|
? rooms
|
|
: rooms.filter((room) => {
|
|
return (
|
|
room.status === AvailabilityEnum.Available &&
|
|
room.products.every(
|
|
(product) =>
|
|
(activeCodeFilter === BookingCodeFilterEnum.Discounted &&
|
|
product.productType.public.rateType !==
|
|
RateTypeEnum.Regular) ||
|
|
(activeCodeFilter === BookingCodeFilterEnum.Regular &&
|
|
product.productType.public.rateType ===
|
|
RateTypeEnum.Regular)
|
|
)
|
|
)
|
|
})
|
|
}
|
|
|
|
return (
|
|
<>
|
|
{noAvailableRooms ||
|
|
(bookingCode &&
|
|
isRegularRatesAvailableWithCode &&
|
|
noAvailabilityWithBookingCode) ? (
|
|
<div className={styles.hotelAlert}>
|
|
<Alert
|
|
type={AlertTypeEnum.Info}
|
|
heading={intl.formatMessage({ id: "No availability" })}
|
|
text={
|
|
noAvailabilityWithBookingCode
|
|
? intl.formatMessage(
|
|
{
|
|
id: "We found no available rooms using this booking code ({bookingCode}). See available rates below.",
|
|
},
|
|
{ bookingCode }
|
|
)
|
|
: intl.formatMessage({
|
|
id: "There are no rooms available that match your request.",
|
|
})
|
|
}
|
|
link={{
|
|
title: intl.formatMessage({ id: "See alternative hotels" }),
|
|
url: `${alternativeHotels(lang)}`,
|
|
keepSearchParams: true,
|
|
}}
|
|
/>
|
|
</div>
|
|
) : null}
|
|
<RoomTypeFilter />
|
|
{bookingCode &&
|
|
isRegularRatesAvailableWithCode &&
|
|
!noAvailabilityWithBookingCode ? (
|
|
<BookingCodeFilter />
|
|
) : null}
|
|
<ul className={styles.roomList}>
|
|
{filteredRooms.map((roomConfiguration) => (
|
|
<RoomCard
|
|
key={roomConfiguration.roomTypeCode}
|
|
roomConfiguration={roomConfiguration}
|
|
/>
|
|
))}
|
|
</ul>
|
|
</>
|
|
)
|
|
}
|