diff --git a/src/containers/BookingDatesForm/BookingDatesForm.js b/src/containers/BookingDatesForm/BookingDatesForm.js
index 48b845e2..16772b22 100644
--- a/src/containers/BookingDatesForm/BookingDatesForm.js
+++ b/src/containers/BookingDatesForm/BookingDatesForm.js
@@ -1,12 +1,11 @@
import React, { Component } from 'react';
-import PropTypes from 'prop-types';
+import { string, bool } from 'prop-types';
import { compose } from 'redux';
-import { connect } from 'react-redux';
-import { reduxForm, formValueSelector, propTypes as formPropTypes } from 'redux-form';
+import { Form as FinalForm } from 'react-final-form';
import { FormattedMessage, intlShape, injectIntl } from 'react-intl';
import classNames from 'classnames';
import moment from 'moment';
-import { required, bookingDatesRequired } from '../../util/validators';
+import { required, bookingDatesRequired, composeValidators } from '../../util/validators';
import { START_DATE, END_DATE } from '../../util/dates';
import { propTypes } from '../../util/types';
import config from '../../config';
@@ -34,7 +33,7 @@ export class BookingDatesFormComponent extends Component {
// focus on that input, otherwise continue with the
// default handleSubmit function.
handleFormSubmit(e) {
- const { startDate, endDate } = this.props.bookingDates;
+ const { startDate, endDate } = e.bookingDates || {};
if (!startDate) {
e.preventDefault();
this.setState({ focusedInput: START_DATE });
@@ -42,28 +41,13 @@ export class BookingDatesFormComponent extends Component {
e.preventDefault();
this.setState({ focusedInput: END_DATE });
} else {
- this.props.handleSubmit(e);
+ this.props.onSubmit(e);
}
}
render() {
- const {
- rootClassName,
- className,
- submitButtonWrapperClassName,
- unitType,
- bookingDates,
- form,
- price: unitPrice,
- intl,
- startDatePlaceholder,
- endDatePlaceholder,
- isOwnListing,
- } = this.props;
-
- const { startDate, endDate } = bookingDates;
+ const { rootClassName, className, price: unitPrice, ...rest } = this.props;
const classes = classNames(rootClassName || css.root, className);
- const submitButtonClasses = classNames(css.submitButtonWrapper, submitButtonWrapperClassName);
if (!unitPrice) {
return (
@@ -84,91 +68,124 @@ export class BookingDatesFormComponent extends Component {
);
}
- const bookingStartLabel = intl.formatMessage({ id: 'BookingDatesForm.bookingStartTitle' });
- const bookingEndLabel = intl.formatMessage({ id: 'BookingDatesForm.bookingEndTitle' });
- const requiredMessage = intl.formatMessage({ id: 'BookingDatesForm.requiredDate' });
- const startDateErrorMessage = intl.formatMessage({
- id: 'FieldDateRangeInput.invalidStartDate',
- });
- const endDateErrorMessage = intl.formatMessage({ id: 'FieldDateRangeInput.invalidEndDate' });
-
- // This is the place to collect breakdown estimation data. See the
- // EstimatedBreakdownMaybe component to change the calculations
- // for customised payment processes.
- const bookingData =
- startDate && endDate
- ? {
- unitType,
- unitPrice,
- startDate,
- endDate,
-
- // NOTE: If unitType is `line-item/units`, a new picker
- // for the quantity should be added to the form.
- quantity: 1,
- }
- : null;
- const bookingInfo = bookingData ? (
-
-
-
-
-
-
- ) : null;
-
- const dateFormatOptions = {
- weekday: 'short',
- month: 'short',
- day: 'numeric',
- };
-
- const now = moment();
- const today = now.startOf('day').toDate();
- const tomorrow = now
- .startOf('day')
- .add(1, 'days')
- .toDate();
- const startDatePlaceholderText =
- startDatePlaceholder || intl.formatDate(today, dateFormatOptions);
- const endDatePlaceholderText =
- endDatePlaceholder || intl.formatDate(tomorrow, dateFormatOptions);
-
return (
-
+ {
+ const {
+ endDatePlaceholder,
+ startDatePlaceholder,
+ form,
+ handleSubmit,
+ intl,
+ isOwnListing,
+ submitButtonWrapperClassName,
+ unitPrice,
+ unitType,
+ values,
+ } = fieldRenderProps;
+ const { startDate, endDate } = values && values.bookingDates ? values.bookingDates : {};
+
+ const bookingStartLabel = intl.formatMessage({
+ id: 'BookingDatesForm.bookingStartTitle',
+ });
+ const bookingEndLabel = intl.formatMessage({ id: 'BookingDatesForm.bookingEndTitle' });
+ const requiredMessage = intl.formatMessage({ id: 'BookingDatesForm.requiredDate' });
+ const startDateErrorMessage = intl.formatMessage({
+ id: 'FieldDateRangeInput.invalidStartDate',
+ });
+ const endDateErrorMessage = intl.formatMessage({
+ id: 'FieldDateRangeInput.invalidEndDate',
+ });
+
+ // This is the place to collect breakdown estimation data. See the
+ // EstimatedBreakdownMaybe component to change the calculations
+ // for customised payment processes.
+ const bookingData =
+ startDate && endDate
+ ? {
+ unitType,
+ unitPrice,
+ startDate,
+ endDate,
+
+ // NOTE: If unitType is `line-item/units`, a new picker
+ // for the quantity should be added to the form.
+ quantity: 1,
+ }
+ : null;
+ const bookingInfo = bookingData ? (
+
+
+
+
+
+
+ ) : null;
+
+ const dateFormatOptions = {
+ weekday: 'short',
+ month: 'short',
+ day: 'numeric',
+ };
+
+ const now = moment();
+ const today = now.startOf('day').toDate();
+ const tomorrow = now
+ .startOf('day')
+ .add(1, 'days')
+ .toDate();
+ const startDatePlaceholderText =
+ startDatePlaceholder || intl.formatDate(today, dateFormatOptions);
+ const endDatePlaceholderText =
+ endDatePlaceholder || intl.formatDate(tomorrow, dateFormatOptions);
+ const submitButtonClasses = classNames(
+ css.submitButtonWrapper,
+ submitButtonWrapperClassName
+ );
+
+ return (
+
+ );
+ }}
+ />
);
}
}
@@ -183,11 +200,7 @@ BookingDatesFormComponent.defaultProps = {
endDatePlaceholder: null,
};
-const { instanceOf, shape, string, bool } = PropTypes;
-
BookingDatesFormComponent.propTypes = {
- ...formPropTypes,
-
rootClassName: string,
className: string,
submitButtonWrapperClassName: string,
@@ -196,12 +209,6 @@ BookingDatesFormComponent.propTypes = {
price: propTypes.money,
isOwnListing: bool,
- // from formValueSelector
- bookingDates: shape({
- startDate: instanceOf(Date),
- endDate: instanceOf(Date),
- }).isRequired,
-
// from injectIntl
intl: intlShape.isRequired,
@@ -210,21 +217,7 @@ BookingDatesFormComponent.propTypes = {
endDatePlaceholder: string,
};
-const formName = 'BookingDates';
-
-// When a field depends on the value of another field, we must connect
-// to the store and select the required values to inject to the
-// component.
-//
-// See: http://redux-form.com/6.6.1/examples/selectingFormValues/
-const selector = formValueSelector(formName);
-const mapStateToProps = state => ({ bookingDates: selector(state, 'bookingDates') || {} });
-
-const BookingDatesForm = compose(
- connect(mapStateToProps),
- reduxForm({ form: formName }),
- injectIntl
-)(BookingDatesFormComponent);
+const BookingDatesForm = compose(injectIntl)(BookingDatesFormComponent);
BookingDatesForm.displayName = 'BookingDatesForm';
export default BookingDatesForm;
diff --git a/src/containers/BookingDatesForm/__snapshots__/BookingDatesForm.test.js.snap b/src/containers/BookingDatesForm/__snapshots__/BookingDatesForm.test.js.snap
index 2164cfc9..7aac3053 100644
--- a/src/containers/BookingDatesForm/__snapshots__/BookingDatesForm.test.js.snap
+++ b/src/containers/BookingDatesForm/__snapshots__/BookingDatesForm.test.js.snap
@@ -1,48 +1,61 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`BookingDatesForm matches snapshot without selected dates 1`] = `
-
+ }
+ invalid={false}
+ isOwnListing={false}
+ onSubmit={[Function]}
+ pristine={true}
+ pure={true}
+ render={[Function]}
+ reset={[Function]}
+ resetSection={[Function]}
+ startDatePlaceholder="today"
+ submit={[Function]}
+ submitButtonWrapperClassName={null}
+ submitFailed={false}
+ submitSucceeded={false}
+ submitting={false}
+ touch={[Function]}
+ unitPrice={
+ Money {
+ "amount": 1099,
+ "currency": "USD",
+ }
+ }
+ unitType="line-item/night"
+ untouch={[Function]}
+ valid={true}
+/>
`;