fix: Update logic for identifying past stays * fix: Update logic for identifying past stays Approved-by: Erik Tiekstra
124 lines
3.5 KiB
TypeScript
124 lines
3.5 KiB
TypeScript
"use client"
|
|
import { notFound } from "next/navigation"
|
|
import { use, useRef } from "react"
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { dt } from "@scandic-hotels/common/dt"
|
|
import { trpc } from "@scandic-hotels/trpc/client"
|
|
|
|
import { createMyStayStore } from "@/stores/my-stay"
|
|
|
|
import { MyStaySkeleton } from "@/components/HotelReservation/MyStay/myStaySkeleton"
|
|
import { MyStayContext } from "@/contexts/MyStay"
|
|
|
|
import type { Lang } from "@scandic-hotels/common/constants/language"
|
|
import type {
|
|
BookingConfirmation,
|
|
BookingConfirmationSchema,
|
|
} from "@scandic-hotels/trpc/types/bookingConfirmation"
|
|
import type { RoomCategories } from "@scandic-hotels/trpc/types/hotel"
|
|
import type { CreditCard } from "@scandic-hotels/trpc/types/user"
|
|
|
|
import type { Packages } from "@/types/components/myPages/myStay/ancillaries"
|
|
import type { MyStayStore } from "@/types/contexts/my-stay"
|
|
|
|
interface MyStayProviderProps {
|
|
bookingConfirmation: BookingConfirmation
|
|
breakfastPackages: Packages | null
|
|
isLoggedIn?: boolean
|
|
lang: Lang
|
|
linkedReservationsPromise: Promise<BookingConfirmationSchema[]>
|
|
refId: string
|
|
roomCategories: RoomCategories
|
|
savedCreditCards: CreditCard[] | null
|
|
}
|
|
|
|
export default function MyStayProvider({
|
|
bookingConfirmation,
|
|
breakfastPackages,
|
|
children,
|
|
lang,
|
|
linkedReservationsPromise,
|
|
refId,
|
|
roomCategories,
|
|
savedCreditCards,
|
|
isLoggedIn,
|
|
}: React.PropsWithChildren<MyStayProviderProps>) {
|
|
const storeRef = useRef<MyStayStore>(undefined)
|
|
const intl = useIntl()
|
|
|
|
const { data, error, isFetching, isFetchedAfterMount } =
|
|
trpc.booking.get.useQuery(
|
|
{
|
|
refId: bookingConfirmation.booking.refId,
|
|
lang,
|
|
},
|
|
{
|
|
initialData: bookingConfirmation,
|
|
refetchOnMount: false,
|
|
refetchOnWindowFocus: false,
|
|
}
|
|
)
|
|
|
|
// We need this two-step business since `use` must resolve
|
|
// the promise passed from the server whereas `useQuery`
|
|
// needs to own the data when in the client so that invalidations
|
|
// actually triggers a refetch of the data
|
|
const linkedReservationsResponses = use(linkedReservationsPromise)
|
|
const {
|
|
data: linkedReservations,
|
|
error: linkedReservationsError,
|
|
isFetching: linkedReservationsIsFetching,
|
|
isFetchedAfterMount: linkedReservationsIsFetchedAfterMount,
|
|
} = trpc.booking.linkedReservations.useQuery(
|
|
{
|
|
lang,
|
|
refId: bookingConfirmation.booking.refId,
|
|
},
|
|
{
|
|
initialData: linkedReservationsResponses,
|
|
refetchOnMount: false,
|
|
refetchOnWindowFocus: false,
|
|
}
|
|
)
|
|
|
|
if (isFetching || linkedReservationsIsFetching) {
|
|
return <MyStaySkeleton />
|
|
}
|
|
|
|
if (!data || error || linkedReservationsError) {
|
|
return notFound()
|
|
}
|
|
|
|
const rooms = [data.booking, ...linkedReservations]
|
|
|
|
// Following the API logic for determining if booking is in the past.
|
|
// This is the same logic as used for separating stays in /future and /past endpoints on the API
|
|
const now = dt()
|
|
const isPastBooking = dt(data.booking.checkOutDate).isBefore(now, "day")
|
|
|
|
const hasInvalidatedQueryAndRefetched =
|
|
(isFetchedAfterMount && data) ||
|
|
(linkedReservationsIsFetchedAfterMount && linkedReservations)
|
|
|
|
if (!storeRef.current || hasInvalidatedQueryAndRefetched) {
|
|
storeRef.current = createMyStayStore({
|
|
breakfastPackages,
|
|
hotel: bookingConfirmation.hotel,
|
|
intl,
|
|
refId,
|
|
roomCategories,
|
|
rooms,
|
|
savedCreditCards,
|
|
isLoggedIn,
|
|
isPastBooking,
|
|
})
|
|
}
|
|
|
|
return (
|
|
<MyStayContext.Provider value={storeRef.current}>
|
|
{children}
|
|
</MyStayContext.Provider>
|
|
)
|
|
}
|