mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-29 21:21:19 +10:00
Fetch available time slots for listing page
This commit is contained in:
parent
1b96549962
commit
e3cfa970ad
3 changed files with 74 additions and 1 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import pick from 'lodash/pick';
|
||||
import moment from 'moment';
|
||||
import config from '../../config';
|
||||
import { types as sdkTypes } from '../../util/sdkLoader';
|
||||
import { storableError } from '../../util/errors';
|
||||
|
|
@ -21,6 +22,10 @@ export const FETCH_REVIEWS_REQUEST = 'app/ListingPage/FETCH_REVIEWS_REQUEST';
|
|||
export const FETCH_REVIEWS_SUCCESS = 'app/ListingPage/FETCH_REVIEWS_SUCCESS';
|
||||
export const FETCH_REVIEWS_ERROR = 'app/ListingPage/FETCH_REVIEWS_ERROR';
|
||||
|
||||
export const FETCH_TIME_SLOTS_REQUEST = 'app/ListingPage/FETCH_TIME_SLOTS_REQUEST';
|
||||
export const FETCH_TIME_SLOTS_SUCCESS = 'app/ListingPage/FETCH_TIME_SLOTS_SUCCESS';
|
||||
export const FETCH_TIME_SLOTS_ERROR = 'app/ListingPage/FETCH_TIME_SLOTS_ERROR';
|
||||
|
||||
export const SEND_ENQUIRY_REQUEST = 'app/ListingPage/SEND_ENQUIRY_REQUEST';
|
||||
export const SEND_ENQUIRY_SUCCESS = 'app/ListingPage/SEND_ENQUIRY_SUCCESS';
|
||||
export const SEND_ENQUIRY_ERROR = 'app/ListingPage/SEND_ENQUIRY_ERROR';
|
||||
|
|
@ -32,6 +37,8 @@ const initialState = {
|
|||
showListingError: null,
|
||||
reviews: [],
|
||||
fetchReviewsError: null,
|
||||
timeSlots: [],
|
||||
fetchTimesLotsError: null,
|
||||
sendEnquiryInProgress: false,
|
||||
sendEnquiryError: null,
|
||||
enquiryModalOpenForListingId: null,
|
||||
|
|
@ -55,6 +62,13 @@ const listingPageReducer = (state = initialState, action = {}) => {
|
|||
case FETCH_REVIEWS_ERROR:
|
||||
return { ...state, fetchReviewsError: payload };
|
||||
|
||||
case FETCH_TIME_SLOTS_REQUEST:
|
||||
return { ...state, fetchTimeSlotsError: null };
|
||||
case FETCH_TIME_SLOTS_SUCCESS:
|
||||
return { ...state, timeSlots: payload };
|
||||
case FETCH_TIME_SLOTS_ERROR:
|
||||
return { ...state, fetchTimeSlotsError: payload };
|
||||
|
||||
case SEND_ENQUIRY_REQUEST:
|
||||
return { ...state, sendEnquiryInProgress: true, sendEnquiryError: null };
|
||||
case SEND_ENQUIRY_SUCCESS:
|
||||
|
|
@ -95,6 +109,17 @@ export const fetchReviewsError = error => ({
|
|||
payload: error,
|
||||
});
|
||||
|
||||
export const fetchTimeSlotsRequest = () => ({ type: FETCH_TIME_SLOTS_REQUEST });
|
||||
export const fetchTimeSlotsSuccess = timeSlots => ({
|
||||
type: FETCH_TIME_SLOTS_SUCCESS,
|
||||
payload: timeSlots,
|
||||
});
|
||||
export const fetchTimeSlotsError = error => ({
|
||||
type: FETCH_TIME_SLOTS_ERROR,
|
||||
error: true,
|
||||
payload: error,
|
||||
});
|
||||
|
||||
export const sendEnquiryRequest = () => ({ type: SEND_ENQUIRY_REQUEST });
|
||||
export const sendEnquirySuccess = () => ({ type: SEND_ENQUIRY_SUCCESS });
|
||||
export const sendEnquiryError = e => ({ type: SEND_ENQUIRY_ERROR, error: true, payload: e });
|
||||
|
|
@ -143,6 +168,7 @@ export const showListing = (listingId, isOwn = false) => (dispatch, getState, sd
|
|||
};
|
||||
|
||||
export const fetchReviews = listingId => (dispatch, getState, sdk) => {
|
||||
dispatch(fetchReviewsRequest);
|
||||
return sdk.reviews
|
||||
.query({
|
||||
listing_id: listingId,
|
||||
|
|
@ -159,6 +185,19 @@ export const fetchReviews = listingId => (dispatch, getState, sdk) => {
|
|||
});
|
||||
};
|
||||
|
||||
export const fetchTimeSlots = params => (dispatch, getState, sdk) => {
|
||||
dispatch(fetchTimeSlotsRequest);
|
||||
return sdk.timeslots
|
||||
.query(params)
|
||||
.then(response => {
|
||||
const timeSlots = denormalisedResponseEntities(response);
|
||||
dispatch(fetchTimeSlotsSuccess(timeSlots));
|
||||
})
|
||||
.catch(e => {
|
||||
dispatch(fetchTimeSlotsError(storableError(e)));
|
||||
});
|
||||
};
|
||||
|
||||
export const sendEnquiry = (listingId, message) => (dispatch, getState, sdk) => {
|
||||
dispatch(sendEnquiryRequest());
|
||||
const bodyParams = {
|
||||
|
|
@ -190,5 +229,19 @@ export const loadData = (params, search) => dispatch => {
|
|||
if (params.variant === LISTING_PAGE_PENDING_APPROVAL_VARIANT) {
|
||||
return dispatch(showListing(listingId, true));
|
||||
}
|
||||
return Promise.all([dispatch(showListing(listingId)), dispatch(fetchReviews(listingId))]);
|
||||
|
||||
// fetch time slots for 90 days starting today
|
||||
// as the booking can only be done for 90 days
|
||||
// in the future due to Stripe limitations
|
||||
const start = moment().toDate();
|
||||
const end = moment()
|
||||
.add(90, 'days')
|
||||
.toDate();
|
||||
const timeSlotsParams = { listingId, start, end };
|
||||
|
||||
return Promise.all([
|
||||
dispatch(showListing(listingId)),
|
||||
dispatch(fetchTimeSlots(timeSlotsParams)),
|
||||
dispatch(fetchReviews(listingId)),
|
||||
]);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -497,6 +497,8 @@ ListingPageComponent.defaultProps = {
|
|||
showListingError: null,
|
||||
reviews: [],
|
||||
fetchReviewsError: null,
|
||||
timeSlots: [],
|
||||
fetchTimeSlotsError: null,
|
||||
sendEnquiryError: null,
|
||||
categoriesConfig: config.custom.categories,
|
||||
amenitiesConfig: config.custom.amenities,
|
||||
|
|
@ -532,6 +534,8 @@ ListingPageComponent.propTypes = {
|
|||
useInitialValues: func.isRequired,
|
||||
reviews: arrayOf(propTypes.review),
|
||||
fetchReviewsError: propTypes.error,
|
||||
timeSlots: arrayOf(propTypes.timeSlot),
|
||||
fetchTimeSlotsError: propTypes.error,
|
||||
sendEnquiryInProgress: bool.isRequired,
|
||||
sendEnquiryError: propTypes.error,
|
||||
onSendEnquiry: func.isRequired,
|
||||
|
|
@ -546,6 +550,8 @@ const mapStateToProps = state => {
|
|||
showListingError,
|
||||
reviews,
|
||||
fetchReviewsError,
|
||||
timeSlots,
|
||||
fetchTimeSlotsError,
|
||||
sendEnquiryInProgress,
|
||||
sendEnquiryError,
|
||||
enquiryModalOpenForListingId,
|
||||
|
|
@ -574,6 +580,8 @@ const mapStateToProps = state => {
|
|||
showListingError,
|
||||
reviews,
|
||||
fetchReviewsError,
|
||||
timeSlots,
|
||||
fetchTimeSlotsError,
|
||||
sendEnquiryInProgress,
|
||||
sendEnquiryError,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -187,6 +187,16 @@ propTypes.booking = shape({
|
|||
}),
|
||||
});
|
||||
|
||||
// Denormalised time slot object
|
||||
propTypes.timeSlot = shape({
|
||||
id: propTypes.uuid.isRequired,
|
||||
type: propTypes.value('timeSlot').isRequired,
|
||||
attributes: shape({
|
||||
end: instanceOf(Date).isRequired,
|
||||
start: instanceOf(Date).isRequired,
|
||||
}),
|
||||
});
|
||||
|
||||
// When a customer makes a booking to a listing, a transaction is
|
||||
// created with the initial request transition.
|
||||
export const TRANSITION_REQUEST = 'transition/request';
|
||||
|
|
@ -425,6 +435,7 @@ export const ERROR_CODE_EMAIL_NOT_VERIFIED = 'email-unverified';
|
|||
export const ERROR_CODE_TOO_MANY_VERIFICATION_REQUESTS = 'email-too-many-verification-requests';
|
||||
export const ERROR_CODE_UPLOAD_OVER_LIMIT = 'request-upload-over-limit';
|
||||
export const ERROR_CODE_VALIDATION_INVALID_PARAMS = 'validation-invalid-params';
|
||||
export const ERROR_CODE_VALIDATION_INVALID_VALUE = 'validation-invalid-value';
|
||||
export const ERROR_CODE_NOT_FOUND = 'not-found';
|
||||
export const ERROR_CODE_FORBIDDEN = 'forbidden';
|
||||
export const ERROR_CODE_MISSING_STRIPE_ACCOUNT = 'transaction-missing-stripe-account';
|
||||
|
|
@ -441,6 +452,7 @@ const ERROR_CODES = [
|
|||
ERROR_CODE_TOO_MANY_VERIFICATION_REQUESTS,
|
||||
ERROR_CODE_UPLOAD_OVER_LIMIT,
|
||||
ERROR_CODE_VALIDATION_INVALID_PARAMS,
|
||||
ERROR_CODE_VALIDATION_INVALID_VALUE,
|
||||
ERROR_CODE_NOT_FOUND,
|
||||
ERROR_CODE_FORBIDDEN,
|
||||
ERROR_CODE_MISSING_STRIPE_ACCOUNT,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue