@qite/tide-booking-component
Version:
React Booking wizard & Booking product component for Tide
80 lines (65 loc) • 2.74 kB
text/typescript
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';
import { RootState } from '../../store';
import { BookingPriceDetail, BookingPriceDetails, BookingProductNotification } from '@qite/tide-client/build/types';
import { setPackage } from '../booking/booking-slice';
import { selectBookingPackageBookRequest, selectLanguageCode, selectPackageDetails } from '../booking/selectors';
import priceDetailsApi from './price-details-api';
import { updatePackageDetails } from './util';
export interface PriceDetailsState {
priceDetails: BookingPriceDetail[];
notifications: BookingProductNotification[];
deposit?: number;
commission?: number;
isBusy: boolean;
}
export const fetchPriceDetails = createAsyncThunk('priceDetails/fetchPriceDetails', async (_, { dispatch, getState, signal }) => {
dispatch(setFetchingPriceDetails(true));
dispatch(resetPriceDetails());
const state = getState() as RootState;
const languageCode = selectLanguageCode(state);
const request = selectBookingPackageBookRequest(state);
if (!request) {
throw Error('Product not available.');
}
const priceDetails: BookingPriceDetails = await priceDetailsApi.fetchPriceDetails(state.apiSettings, request, signal, languageCode);
dispatch(setFetchingPriceDetails(false));
const packageDetails = selectPackageDetails(state);
if (packageDetails) {
const updatedPackageDetails = updatePackageDetails(packageDetails, priceDetails.changedLines);
dispatch(setPackage(updatedPackageDetails));
}
return priceDetails;
});
const priceDetailsSlice = createSlice({
name: 'priceDetails',
initialState: <PriceDetailsState>{
priceDetails: [],
notifications: [],
isBusy: false
},
reducers: {
setFetchingPriceDetails(state, action: PayloadAction<boolean>) {
state.isBusy = action.payload;
},
setNotifications(state, action: PayloadAction<BookingProductNotification[]>) {
state.notifications = action.payload;
},
resetPriceDetails(state, _: PayloadAction<void>) {
state.priceDetails = [];
}
},
extraReducers: (builder) => {
builder.addCase(fetchPriceDetails.fulfilled, (state, action) => {
if (action.payload) {
state.deposit = action.payload.deposit;
state.commission = action.payload.commission;
state.priceDetails = action.payload.details;
state.notifications = action.payload.notifications;
}
});
}
});
const { setFetchingPriceDetails } = priceDetailsSlice.actions;
export const { resetPriceDetails, setNotifications } = priceDetailsSlice.actions;
export const selectNotifications = (state: RootState) => state.priceDetails.notifications;
export default priceDetailsSlice.reducer;