diff --git a/src/containers/PayoutDetailsForm/PayoutDetailsForm.css b/src/containers/PayoutDetailsForm/PayoutDetailsForm.css new file mode 100644 index 00000000..66d8dbd6 --- /dev/null +++ b/src/containers/PayoutDetailsForm/PayoutDetailsForm.css @@ -0,0 +1,23 @@ +.root { + +} + +.countries { + border: 1px solid #979797; +} + +.error { + color: red; +} + +.formTitle { + margin-top: 0; +} + +.subTitle { + margin-top: 60px; +} + +.submitButton { + margin-top: 40px; +} diff --git a/src/containers/PayoutDetailsForm/PayoutDetailsForm.example.js b/src/containers/PayoutDetailsForm/PayoutDetailsForm.example.js new file mode 100644 index 00000000..12692017 --- /dev/null +++ b/src/containers/PayoutDetailsForm/PayoutDetailsForm.example.js @@ -0,0 +1,11 @@ +import PayoutDetailsForm from './PayoutDetailsForm'; + +export const USD = { + component: PayoutDetailsForm, + props: { + currency: 'USD', + onSubmit: values => { + console.log('submit payout details:', values); // eslint-disable-line + }, + }, +}; diff --git a/src/containers/PayoutDetailsForm/PayoutDetailsForm.js b/src/containers/PayoutDetailsForm/PayoutDetailsForm.js new file mode 100644 index 00000000..7964fe41 --- /dev/null +++ b/src/containers/PayoutDetailsForm/PayoutDetailsForm.js @@ -0,0 +1,251 @@ +import React, { Component, PropTypes } from 'react'; +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { FormattedMessage, injectIntl, intlShape } from 'react-intl'; +import { Field, reduxForm, formValueSelector, propTypes as formPropTypes } from 'redux-form'; +import config from '../../config'; +import { + Button, + StripeBankAccountToken, + Select, + BirthdayInput, + LocationAutocompleteInput, +} from '../../components'; +import * as validators from '../../util/validators'; +import { enhancedField } from '../../util/forms'; + +import css from './PayoutDetailsForm.css'; + +const supportedCountries = config.stripe.supportedCountries.map(c => c.code); + +const requiresAddress = countryCode => { + const country = config.stripe.supportedCountries.find(c => c.code === countryCode); + if (!country) { + throw new Error(`Country code not found in Stripe config ${countryCode}`); + } + return country.payoutAddressRequired; +}; + +const CountriesSelect = props => { + const { input } = props; + return ( + + ); +}; + +const { string, bool, object } = PropTypes; + +CountriesSelect.propTypes = { + input: object.isRequired, +}; + +class PayoutDetailsFormComponent extends Component { + constructor(props) { + super(props); + this.EnhancedInput = enhancedField('input', { + errorClassName: css.error, + }); + this.EnhancedCountriesDropdown = enhancedField(CountriesSelect, { + errorClassName: css.error, + }); + this.EnhancedBirthdayInput = enhancedField(BirthdayInput, { + errorClassName: css.error, + }); + this.EnhancedLocationAutocompleteInput = enhancedField(LocationAutocompleteInput, { + errorClassName: css.error, + }); + } + render() { + const { country, currency, handleSubmit, pristine, submitting, inProgress, intl } = this.props; + + const nameLabel = intl.formatMessage({ id: 'PayoutDetailsForm.nameLabel' }); + const nameRequired = validators.required( + intl.formatMessage({ + id: 'PayoutDetailsForm.nameRequired', + }) + ); + + const birthdayLabel = intl.formatMessage({ id: 'PayoutDetailsForm.birthdayLabel' }); + const birthdayRequired = validators.required( + intl.formatMessage({ + id: 'PayoutDetailsForm.birthdayRequired', + }) + ); + + const countryLabel = intl.formatMessage({ id: 'PayoutDetailsForm.countryLabel' }); + const countryRequired = validators.required( + intl.formatMessage({ + id: 'PayoutDetailsForm.countryRequired', + }) + ); + + const streetAddressLabel = intl.formatMessage({ id: 'PayoutDetailsForm.streetAddressLabel' }); + const streetAddressPlaceholder = intl.formatMessage({ + id: 'PayoutDetailsForm.streetAddressPlaceholder', + }); + const streetAddressRequiredMessage = intl.formatMessage({ + id: 'PayoutDetailsForm.streetAddressRequired', + }); + const streetAddressNotRecognizedMessage = intl.formatMessage({ + id: 'PayoutDetailsForm.streetAddressNotRecognized', + }); + const validateStreetAddress = [ + validators.autocompleteSearchRequired(streetAddressRequiredMessage), + validators.autocompletePlaceSelected(streetAddressNotRecognizedMessage), + ]; + + const postalCodeLabel = intl.formatMessage({ id: 'PayoutDetailsForm.postalCodeLabel' }); + const postalCodePlaceholder = intl.formatMessage({ + id: 'PayoutDetailsForm.postalCodePlaceholder', + }); + const postalCodeRequired = validators.required( + intl.formatMessage({ + id: 'PayoutDetailsForm.postalCodeRequired', + }) + ); + + const cityLabel = intl.formatMessage({ id: 'PayoutDetailsForm.cityLabel' }); + const cityPlaceholder = intl.formatMessage({ id: 'PayoutDetailsForm.cityPlaceholder' }); + const cityRequired = validators.required( + intl.formatMessage({ + id: 'PayoutDetailsForm.cityRequired', + }) + ); + + const showAddressFields = country && requiresAddress(country); + const addressSection = showAddressFields + ?