fix: load room availability separately
This commit is contained in:
@@ -1,22 +1,16 @@
|
|||||||
import { notFound } from "next/navigation"
|
import { notFound } from "next/navigation"
|
||||||
|
import { Suspense } from "react"
|
||||||
|
|
||||||
import { dt } from "@/lib/dt"
|
import { dt } from "@/lib/dt"
|
||||||
import {
|
import { getHotelData, getLocations } from "@/lib/trpc/memoizedRequests"
|
||||||
getHotelData,
|
|
||||||
getLocations,
|
|
||||||
getProfileSafely,
|
|
||||||
} from "@/lib/trpc/memoizedRequests"
|
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
|
||||||
|
|
||||||
|
import LoadingSpinner from "@/components/Current/LoadingSpinner"
|
||||||
import HotelInfoCard from "@/components/HotelReservation/SelectRate/HotelInfoCard"
|
import HotelInfoCard from "@/components/HotelReservation/SelectRate/HotelInfoCard"
|
||||||
import Rooms from "@/components/HotelReservation/SelectRate/Rooms"
|
import { RoomsContainer } from "@/components/HotelReservation/SelectRate/Rooms/RoomsContainer"
|
||||||
import {
|
import { getHotelReservationQueryParams } from "@/components/HotelReservation/SelectRate/RoomSelection/utils"
|
||||||
generateChildrenString,
|
|
||||||
getHotelReservationQueryParams,
|
|
||||||
} from "@/components/HotelReservation/SelectRate/RoomSelection/utils"
|
|
||||||
import { setLang } from "@/i18n/serverContext"
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
import { safeTry } from "@/utils/safeTry"
|
||||||
|
|
||||||
import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
|
|
||||||
import type { SelectRateSearchParams } from "@/types/components/hotelReservation/selectRate/selectRate"
|
import type { SelectRateSearchParams } from "@/types/components/hotelReservation/selectRate/selectRate"
|
||||||
import type { LangParams, PageArgs } from "@/types/params"
|
import type { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
@@ -45,71 +39,48 @@ export default async function SelectRatePage({
|
|||||||
return notFound()
|
return notFound()
|
||||||
}
|
}
|
||||||
|
|
||||||
const validFromDate =
|
const fromDate =
|
||||||
searchParams.fromDate &&
|
searchParams.fromDate &&
|
||||||
dt(searchParams.fromDate).isAfter(dt().subtract(1, "day"))
|
dt(searchParams.fromDate).isAfter(dt().subtract(1, "day"))
|
||||||
? searchParams.fromDate
|
? dt(searchParams.fromDate)
|
||||||
: dt().utc().format("YYYY-MM-DD")
|
: dt().utc()
|
||||||
const validToDate =
|
const toDate =
|
||||||
searchParams.toDate && dt(searchParams.toDate).isAfter(validFromDate)
|
searchParams.toDate && dt(searchParams.toDate).isAfter(fromDate)
|
||||||
? searchParams.toDate
|
? dt(searchParams.toDate)
|
||||||
: dt().utc().add(1, "day").format("YYYY-MM-DD")
|
: dt().utc().add(1, "day")
|
||||||
|
|
||||||
const adults = selectRoomParamsObject.room[0].adults || 1 // TODO: Handle multiple rooms
|
const adults = selectRoomParamsObject.room[0].adults || 1 // TODO: Handle multiple rooms
|
||||||
const childrenCount = selectRoomParamsObject.room[0].child?.length
|
const children = selectRoomParamsObject.room[0].child // TODO: Handle multiple rooms
|
||||||
const children = selectRoomParamsObject.room[0].child
|
|
||||||
? generateChildrenString(selectRoomParamsObject.room[0].child)
|
|
||||||
: undefined // TODO: Handle multiple rooms
|
|
||||||
|
|
||||||
const [hotelData, roomsAvailability, packages, user] = await Promise.all([
|
const [hotelData, hotelDataError] = await safeTry(
|
||||||
getHotelData({ hotelId: searchParams.hotel, language: params.lang }),
|
getHotelData({ hotelId: searchParams.hotel, language: params.lang })
|
||||||
serverClient().hotel.availability.rooms({
|
|
||||||
hotelId: parseInt(searchParams.hotel, 10),
|
|
||||||
roomStayStartDate: validFromDate,
|
|
||||||
roomStayEndDate: validToDate,
|
|
||||||
adults,
|
|
||||||
children,
|
|
||||||
}),
|
|
||||||
serverClient().hotel.packages.get({
|
|
||||||
hotelId: searchParams.hotel,
|
|
||||||
startDate: searchParams.fromDate,
|
|
||||||
endDate: searchParams.toDate,
|
|
||||||
adults,
|
|
||||||
children: childrenCount,
|
|
||||||
packageCodes: [
|
|
||||||
RoomPackageCodeEnum.ACCESSIBILITY_ROOM,
|
|
||||||
RoomPackageCodeEnum.PET_ROOM,
|
|
||||||
RoomPackageCodeEnum.ALLERGY_ROOM,
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
getProfileSafely(),
|
|
||||||
])
|
|
||||||
|
|
||||||
if (!roomsAvailability) {
|
|
||||||
return "No rooms found" // TODO: Add a proper error message
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hotelData) {
|
|
||||||
return "No hotel data found" // TODO: Add a proper error message
|
|
||||||
}
|
|
||||||
|
|
||||||
const roomCategories = hotelData?.included
|
|
||||||
|
|
||||||
const noRoomsAvailable = roomsAvailability.roomConfigurations.reduce(
|
|
||||||
(acc, room) => {
|
|
||||||
return acc && room.status === "NotAvailable"
|
|
||||||
},
|
|
||||||
true
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (!hotelData && !hotelDataError) {
|
||||||
|
return notFound()
|
||||||
|
}
|
||||||
|
|
||||||
|
const hotelId = +searchParams.hotel
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<HotelInfoCard hotelData={hotelData} noAvailability={noRoomsAvailable} />
|
<HotelInfoCard
|
||||||
<Rooms
|
hotelId={hotelId}
|
||||||
roomsAvailability={roomsAvailability}
|
lang={params.lang}
|
||||||
roomCategories={roomCategories ?? []}
|
fromDate={fromDate.toDate()}
|
||||||
user={user}
|
toDate={toDate.toDate()}
|
||||||
packages={packages ?? []}
|
adultCount={adults}
|
||||||
|
childArray={children ?? []}
|
||||||
/>
|
/>
|
||||||
|
<Suspense key={hotelId} fallback={<LoadingSpinner />}>
|
||||||
|
<RoomsContainer
|
||||||
|
hotelId={hotelId}
|
||||||
|
lang={params.lang}
|
||||||
|
fromDate={fromDate.toDate()}
|
||||||
|
toDate={toDate.toDate()}
|
||||||
|
adultCount={adults}
|
||||||
|
childArray={children ?? []}
|
||||||
|
/>
|
||||||
|
</Suspense>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
"use client"
|
import { Suspense, useEffect } from "react"
|
||||||
import { useEffect } from "react"
|
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { Lang } from "@/constants/languages"
|
||||||
|
import { getHotelData } from "@/lib/trpc/memoizedRequests"
|
||||||
import useRoomAvailableStore from "@/stores/roomAvailability"
|
import useRoomAvailableStore from "@/stores/roomAvailability"
|
||||||
|
|
||||||
import { mapFacilityToIcon } from "@/components/ContentType/HotelPage/data"
|
import { mapFacilityToIcon } from "@/components/ContentType/HotelPage/data"
|
||||||
@@ -11,38 +12,54 @@ import Divider from "@/components/TempDesignSystem/Divider"
|
|||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
|
import { getIntl } from "@/i18n"
|
||||||
|
|
||||||
import ReadMore from "../../ReadMore"
|
import ReadMore from "../../ReadMore"
|
||||||
import TripAdvisorChip from "../../TripAdvisorChip"
|
import TripAdvisorChip from "../../TripAdvisorChip"
|
||||||
|
import { NoRoomsAlert } from "./NoRoomsAlert"
|
||||||
|
|
||||||
import styles from "./hotelInfoCard.module.css"
|
import styles from "./hotelInfoCard.module.css"
|
||||||
|
|
||||||
import type { HotelInfoCardProps } from "@/types/components/hotelReservation/selectRate/hotelInfoCardProps"
|
import { Child } from "@/types/components/hotelReservation/selectRate/selectRate"
|
||||||
import { AlertTypeEnum } from "@/types/enums/alert"
|
|
||||||
|
type Props = {
|
||||||
|
hotelId: number
|
||||||
|
lang: Lang
|
||||||
|
fromDate: Date
|
||||||
|
toDate: Date
|
||||||
|
adultCount: number
|
||||||
|
childArray: Child[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function HotelInfoCard({
|
||||||
|
hotelId,
|
||||||
|
lang,
|
||||||
|
...props
|
||||||
|
}: Props) {
|
||||||
|
const hotelData = await getHotelData({
|
||||||
|
hotelId: hotelId.toString(),
|
||||||
|
language: lang,
|
||||||
|
})
|
||||||
|
|
||||||
export default function HotelInfoCard({
|
|
||||||
hotelData,
|
|
||||||
noAvailability = false,
|
|
||||||
}: HotelInfoCardProps) {
|
|
||||||
const hotelAttributes = hotelData?.data.attributes
|
const hotelAttributes = hotelData?.data.attributes
|
||||||
const intl = useIntl()
|
const intl = await getIntl()
|
||||||
|
|
||||||
const noRoomsAvailable = useRoomAvailableStore(
|
// const noRoomsAvailable = useRoomAvailableStore(
|
||||||
(state) => state.noRoomsAvailable
|
// (state) => state.noRoomsAvailable
|
||||||
)
|
// )
|
||||||
const setNoRoomsAvailable = useRoomAvailableStore(
|
// const setNoRoomsAvailable = useRoomAvailableStore(
|
||||||
(state) => state.setNoRoomsAvailable
|
// (state) => state.setNoRoomsAvailable
|
||||||
)
|
// )
|
||||||
|
|
||||||
const sortedFacilities = hotelAttributes?.detailedFacilities
|
const sortedFacilities = hotelAttributes?.detailedFacilities
|
||||||
.sort((a, b) => b.sortOrder - a.sortOrder)
|
.sort((a, b) => b.sortOrder - a.sortOrder)
|
||||||
.slice(0, 5)
|
.slice(0, 5)
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
if (noAvailability) {
|
// if (noAvailability) {
|
||||||
setNoRoomsAvailable()
|
// setNoRoomsAvailable()
|
||||||
}
|
// }
|
||||||
}, [noAvailability, setNoRoomsAvailable])
|
// }, [noAvailability, setNoRoomsAvailable])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<article className={styles.container}>
|
<article className={styles.container}>
|
||||||
@@ -117,16 +134,10 @@ export default function HotelInfoCard({
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
{noRoomsAvailable ? (
|
|
||||||
<div className={styles.hotelAlert}>
|
<Suspense fallback={null} key={hotelId}>
|
||||||
<Alert
|
<NoRoomsAlert hotelId={hotelId} lang={lang} {...props} />
|
||||||
type={AlertTypeEnum.Info}
|
</Suspense>
|
||||||
text={intl.formatMessage({
|
|
||||||
id: "There are no rooms available that match your request",
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</article>
|
</article>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user