Skip to content

Commit

Permalink
feat(simple buy): billing addr form
Browse files Browse the repository at this point in the history
  • Loading branch information
Philip London committed Apr 28, 2020
1 parent eeb237a commit e3b0475
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ export const FETCH_SB_SUGGESTED_AMOUNTS_SUCCESS =
export const HANDLE_SB_SUGGESTED_AMOUNT_CLICK =
'@EVENT.HANDLE_SB_SUGGESTED_AMOUNT_CLICK'

export const INITIALIZE_BILLING_ADDRESS = '@EVENT.INITIALIZE_SB_BILLING_ADDRESS'

export const INITIALIZE_CHECKOUT = '@EVENT.INITIALIZE_SB_CHECKOUT'

export const POLL_SB_CARD = '@EVENT.POLL_SB_CARD'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,10 @@ export const handleSBSuggestedAmountClick = (amount: string) => ({
}
})

export const initializeBillingAddress = () => ({
type: AT.INITIALIZE_BILLING_ADDRESS
})

export const initializeCheckout = (
pairs: Array<SBPairType>,
paymentMethods: SBPaymentMethodsType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ export default ({ api, coreSagas, networks }) => {
AT.HANDLE_SB_SUGGESTED_AMOUNT_CLICK,
simpleBuySagas.handleSBSuggestedAmountClick
)
yield takeLatest(
AT.INITIALIZE_BILLING_ADDRESS,
simpleBuySagas.initializeBillingAddress
)
yield takeLatest(AT.INITIALIZE_CHECKOUT, simpleBuySagas.initializeCheckout)
yield takeLatest(AT.POLL_SB_CARD, simpleBuySagas.pollSBCard)
yield takeLatest(AT.POLL_SB_ORDER, simpleBuySagas.pollSBOrder)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,28 @@ export default ({
yield put(actions.form.change('simpleBuyCheckout', 'amount', standardAmt))
}

const initializeBillingAddress = function * () {
yield call(waitForUserData)
const userDataR = selectors.modules.profile.getUserData(yield select())
const userData = userDataR.getOrElse(null)
const address = userData
? userData.address
: {
country: 'GB',
line1: '',
line2: '',
city: '',
postCode: '',
state: ''
}

yield put(
actions.form.initialize('ccBillingAddress', {
...address
})
)
}

const initializeCheckout = function * ({
pairs,
paymentMethods,
Expand Down Expand Up @@ -543,6 +565,7 @@ export default ({
fetchSBQuote,
fetchSBSuggestedAmounts,
handleSBSuggestedAmountClick,
initializeBillingAddress,
initializeCheckout,
pollSBCard,
pollSBOrder,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Everypay3DSResponseType,
FiatEligibleType,
FiatType,
NabuAddressType,
RemoteDataType,
SBAccountType,
SBBalancesType,
Expand All @@ -24,6 +25,7 @@ export type SBAddCardFormValuesType = {
'expiry-date': string
'name-on-card': string
}
export type SBBillingAddressFormValuesType = NabuAddressType
export type SBCheckoutFormValuesType = {
amount: string
method?: SBFormPaymentMethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ const SelectBoxCountry = styled(SelectBox)`
.bc__dropdown-indicator {
color: ${props => props.theme.grey600};
}
.bc__single-value {
position: relative;
top: 0;
transform: initial;
margin: 0;
}
`
const DisplayContainer = styled.div<{
isItem: boolean
Expand All @@ -30,20 +36,14 @@ const Display = styled.div`
cursor: pointer;
font-size: 16px;
font-weight: 500;
margin-left: 12px;
color: ${props => props.theme.grey800};
.bc__single-value {
position: relative;
top: 0;
transform: initial;
margin: 0;
}
input {
height: 0;
}
`
const IconContainer = styled.div`
width: 38px;
min-width: 32px;
height: 32px;
font-size: 40px;
overflow: hidden;
border-radius: 16px;
background-color: ${props => props.theme.blue000};
display: flex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ import { connect, ConnectedProps } from 'react-redux'
import { getData } from './selectors'
import { RemoteDataType } from 'core/types'
import { RootState } from 'data/rootReducer'
import { UserDataType } from 'data/types'
import { SBBillingAddressFormValuesType, UserDataType } from 'data/types'
import DataError from 'components/DataError'
import Loading from './template.loading'
import React, { PureComponent } from 'react'
import Success from './template.success'

class BillingAddress extends PureComponent<Props> {
componentDidMount () {
this.props.simpleBuyActions.initializeBillingAddress()
}

render () {
return this.props.data.cata({
Success: val => <Success {...val} {...this.props} />,
Expand Down Expand Up @@ -44,7 +48,7 @@ type OwnProps = {
handleClose: () => void
}
export type SuccessStateType = {
formValues: any
formValues: SBBillingAddressFormValuesType
userData: UserDataType
}
type LinkStatePropsType = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import {
countryUsesPostalcode,
countryUsesZipcode,
required,
requiredZipCode
} from 'services/FormHelper'
import { Field, Form, InjectedFormProps, reduxForm } from 'redux-form'
import { FlyoutWrapper } from 'components/Flyout'
import { FormattedMessage } from 'react-intl'
import {
FormGroup,
FormItem,
FormLabel,
SelectBoxUSState,
TextBox
} from 'components/Form'
import { Icon, Text } from 'blockchain-info-components'
import { InjectedFormProps, reduxForm } from 'redux-form'
import { Props as OwnProps, SuccessStateType } from '.'
import CountrySelect from './CountrySelect'
import React from 'react'
Expand All @@ -20,33 +33,135 @@ const Top = styled(Text)`
export type Props = OwnProps & SuccessStateType

const Success: React.FC<InjectedFormProps<{}, Props> & Props> = props => {
if (!props.formValues) return null

const countryCode = props.formValues.country
const countryIsUS = countryCode === 'US'
const countryUsesZipOrPostcode =
countryUsesZipcode(countryCode) || countryUsesPostalcode(countryCode)

return (
<>
<CustomFlyoutWrapper>
<Top color='grey800' size='20px' weight={600}>
<Icon
cursor
name='arrow-left'
size='20px'
color='grey600'
style={{ marginRight: '24px' }}
role='button'
onClick={() =>
props.simpleBuyActions.setStep({
step: 'ADD_CARD'
})
}
/>
<FormattedMessage
id='modals.simplebuy.billing_address'
defaultMessage='Billing Address'
/>
</Top>
<CountrySelect {...props} />
</CustomFlyoutWrapper>
<FlyoutWrapper>Here</FlyoutWrapper>
<Form>
<CustomFlyoutWrapper>
<Top color='grey800' size='20px' weight={600}>
<Icon
cursor
name='arrow-left'
size='20px'
color='grey600'
style={{ marginRight: '24px' }}
role='button'
onClick={() =>
props.simpleBuyActions.setStep({
step: 'ADD_CARD'
})
}
/>
<FormattedMessage
id='modals.simplebuy.billing_address'
defaultMessage='Billing Address'
/>
</Top>
<CountrySelect {...props} />
</CustomFlyoutWrapper>
<FlyoutWrapper>
<FormGroup margin='24px'>
<FormLabel>
{countryIsUS ? (
<FormattedMessage
id='identityverification.personal.address_line1required'
defaultMessage='Address Line 1 *'
/>
) : (
<FormattedMessage
id='identityverification.personal.streetline1required'
defaultMessage='Street Line 1 *'
/>
)}
</FormLabel>
<Field name='line1' validate={required} component={TextBox} />
</FormGroup>
<FormGroup margin='24px'>
<FormLabel>
{countryIsUS ? (
<FormattedMessage
id='identityverification.personal.address_line2'
defaultMessage='Address Line 2'
/>
) : (
<FormattedMessage
id='identityverification.personal.streetline2'
defaultMessage='Street Line 2'
/>
)}
</FormLabel>
<Field name='line2' component={TextBox} />
</FormGroup>
<FormGroup margin='24px'>
<FormLabel>
<FormattedMessage
id='identityverification.personal.cityrequired'
defaultMessage='City *'
/>
</FormLabel>
<Field name='city' validate={required} component={TextBox} />
</FormGroup>
<FormGroup inline>
<FormItem>
<FormLabel>
{countryIsUS ? (
<FormattedMessage
id='identityverification.personal.staterequired'
defaultMessage='State *'
/>
) : (
<FormattedMessage
id='identityverification.personal.region'
defaultMessage='Region'
/>
)}
</FormLabel>
{countryIsUS ? (
<Field
name='state'
component={SelectBoxUSState}
validate={[required]}
/>
) : (
<Field name='state' component={TextBox} />
)}
</FormItem>
{countryUsesZipOrPostcode && (
<FormItem>
<FormLabel htmlFor='postCode'>
{countryUsesZipcode(countryCode) ? (
<FormattedMessage
id='identityverification.personal.zip'
defaultMessage='Zip Code *'
/>
) : (
<FormattedMessage
id='identityverification.personal.postcoderequired'
defaultMessage='Postcode *'
/>
)}
</FormLabel>
<Field
name='postCode'
validate={requiredZipCode}
component={TextBox}
/>
</FormItem>
)}
</FormGroup>
</FlyoutWrapper>
</Form>
</>
)
}

export default reduxForm<{}, Props>({ form: 'ccBillingAddress' })(Success)
export default reduxForm<{}, Props>({
form: 'ccBillingAddress',
destroyOnUnmount: false
})(Success)
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ export const countryUsesPostalcode = countryCode => {
export const countryUsesZipcode = countryCode => countryCode === 'US'

export const requiredZipCode = (value, allVals) => {
const countryCode = path(['country', 'code'], allVals)
const countryCode =
path(['country', 'code'], allVals) || path(['country'], allVals)
if (!path([countryCode, 'postalCodeFormat'], postalCodes)) return undefined
if (!value) return <M.RequiredMessage />

Expand Down

0 comments on commit e3b0475

Please sign in to comment.