Files
web/apps/scandic-web/providers/SelectRate/RoomProvider.tsx
Tobias Johansson e6ae6ff650 Merged in feat/SW-2113-allow-feature-combinations (pull request #1719)
Feat/SW-2113 allow feature combinations

* feat(SW-2113): Refactor features data to be fetched on filter room filter change

* feat(SW-2113): added loading state

* fix: now clear room selection when applying filter and room doesnt exists. And added room features to mobile summary

* fix

* fix: add package to price details

* feat(SW-2113): added buttons to room filter

* fix: active room

* fix: remove console log

* fix: added form and close handler to room package filter

* fix: add restriction so you cannot select pet room with allergy room and vice versa

* fix: fixes from review feedback

* fix

* fix: hide modify button if on nextcoming rooms if no selection is made, and adjust filter logic in togglePackage

* fix: forgot to use roomFeatureCodes from input..

* fix: naming


Approved-by: Simon.Emanuelsson
2025-04-07 11:36:34 +00:00

150 lines
4.3 KiB
TypeScript

"use client"
import { useEffect } from "react"
import { REDEMPTION } from "@/constants/booking"
import { trpc } from "@/lib/trpc/client"
import { useRatesStore } from "@/stores/select-rate"
import { RoomContext } from "@/contexts/SelectRate/Room"
import useLang from "@/hooks/useLang"
import { BookingCodeFilterEnum } from "@/types/enums/bookingCodeFilter"
import { RateTypeEnum } from "@/types/enums/rateType"
import type { RoomProviderProps } from "@/types/providers/select-rate/room"
export default function RoomProvider({
children,
idx,
room,
}: RoomProviderProps) {
const lang = useLang()
const {
activeRoom,
booking,
roomAvailability,
searchParams,
selectedFilter,
selectedPackages,
} = useRatesStore((state) => ({
activeRoom: state.activeRoom,
booking: state.booking,
roomAvailability: state.roomsAvailability?.[idx],
searchParams: state.searchParams,
selectedFilter: state.rooms[idx].selectedFilter,
selectedPackages: state.rooms[idx].selectedPackages,
}))
const { appendRegularRates, addRoomFeatures, ...actions } = room.actions
const roomNr = idx + 1
const redemptionSearch = searchParams.has("searchType")
? searchParams.get("searchType") === REDEMPTION
: false
const hasRedemptionRates =
redemptionSearch || room.rooms.some((room) => room.redemptions.length)
const hasCorporateChequeOrVoucherRates = room.rooms.some((room) =>
room.code.some((product) => {
if ("corporateCheque" in product) {
return product.corporateCheque.rateType === RateTypeEnum.CorporateCheque
} else if ("voucher" in product) {
return product.voucher.rateType === RateTypeEnum.Voucher
}
return false
})
)
const dontShowRegularRates =
hasRedemptionRates || hasCorporateChequeOrVoucherRates
// Since input would be the same on single room as already
// done in useRoomsAvailability hook, data is already present
// and thus runs the appendRegularRates updater resulting in
// duplicate data
const enabled = !!(
booking.bookingCode &&
selectedFilter !== BookingCodeFilterEnum.Discounted &&
!dontShowRegularRates
)
// Extra query needed to fetch regular rates upon user
// selecting to view all rates.
// TODO: Setup route to handle singular availability call
const { data, isFetched, isFetching } =
trpc.hotel.availability.roomsCombinedAvailability.useQuery(
{
adultsCount: [room.bookingRoom.adults],
childArray: room.bookingRoom.childrenInRoom
? [room.bookingRoom.childrenInRoom]
: undefined,
hotelId: booking.hotelId,
lang,
roomStayEndDate: booking.toDate,
roomStayStartDate: booking.fromDate,
},
{
enabled,
}
)
useEffect(() => {
if (isFetched && !isFetching && data?.length && enabled) {
const regularRates = data[0]
if ("roomConfigurations" in regularRates) {
appendRegularRates(regularRates.roomConfigurations)
}
}
}, [appendRegularRates, data, enabled, isFetched, isFetching])
const {
data: roomFeaturesData,
isFetched: isRoomFeaturesFetched,
isFetching: isRoomFeaturesFetching,
} = trpc.hotel.availability.roomFeatures.useQuery(
{
adults: room.bookingRoom.adults,
childrenInRoom: room.bookingRoom.childrenInRoom,
hotelId: booking.hotelId,
startDate: booking.fromDate,
endDate: booking.toDate,
roomFeatureCodes: selectedPackages,
roomIndex: idx, // Creates a unique query key for each room
},
{
enabled: !!selectedPackages.length,
}
)
useEffect(() => {
if (
isRoomFeaturesFetched &&
!isRoomFeaturesFetching &&
roomFeaturesData?.length
) {
addRoomFeatures(roomFeaturesData)
}
}, [
addRoomFeatures,
roomFeaturesData,
isRoomFeaturesFetched,
isRoomFeaturesFetching,
])
return (
<RoomContext.Provider
value={{
...room,
actions,
isActiveRoom: activeRoom === idx,
isFetchingAdditionalRate: isFetched ? false : isFetching,
isFetchingRoomFeatures: isRoomFeaturesFetched
? false
: isRoomFeaturesFetching,
isMainRoom: roomNr === 1,
roomAvailability,
roomNr,
totalRooms: room.rooms.length,
}}
>
{children}
</RoomContext.Provider>
)
}