Skip to content

Commit

Permalink
feat: implemented select crypto step
Browse files Browse the repository at this point in the history
  • Loading branch information
milan-bc committed Jul 3, 2020
1 parent 617cfd5 commit 4bda1dc
Show file tree
Hide file tree
Showing 22 changed files with 468 additions and 16 deletions.
Expand Up @@ -1111,6 +1111,8 @@
"modals.simplebuy.refresh": "Refresh",
"modals.simplebuy.save_my_card": "Save My Card",
"modals.simplebuy.selectcurrency": "Select Your Currency",
"modals.simplebuy.cryptoselect": "Buy with Cash or Card",
"modals.simplebuy.selectcrypto": "Select the crypto you want to buy.",
"modals.simplebuy.setupaccount": "Next, we'll set up your account.",
"modals.simplebuy.success": "Trade Complete",
"modals.simplebuy.summary.cancelbuy": "Cancel Buy",
Expand Down
Expand Up @@ -1136,6 +1136,8 @@ type MessagesType = {
'modals.simplebuy.refresh': 'Refresh'
'modals.simplebuy.save_my_card': 'Save My Card'
'modals.simplebuy.selectcurrency': 'Select Your Currency'
'modals.simplebuy.cryptoselect': 'Buy with Cash or Card'
'modals.simplebuy.selectcrypto': 'Select the crypto you want to buy.'
'modals.simplebuy.setupaccount': "Next, we'll set up your account."
'modals.simplebuy.success': 'Trade Complete'
'modals.simplebuy.summary.cancelbuy': 'Cancel Buy'
Expand Down
@@ -1,5 +1,4 @@
import { Form as ReduxForm } from 'redux-form'
import PropTypes from 'prop-types'
import React from 'react'
import styled from 'styled-components'

Expand All @@ -17,8 +16,4 @@ const Form = props => {
)
}

Form.propTypes = {
onSubmit: PropTypes.func.isRequired
}

export default Form
Expand Up @@ -418,14 +418,29 @@ export const setStep = (
cryptoCurrency?: CoinType
defaultMethod?: SBFormPaymentMethod
fiatCurrency: FiatType
pair: SBPairType
step: 'ENTER_AMOUNT'
}
| {
cryptoCurrency?: CoinType
defaultMethod?: SBFormPaymentMethod
fiatCurrency: FiatType
step: 'CRYPTO_SELECTION'
}
| { order?: SBOrderType; step: '3DS_HANDLER' }
| { step: 'ADD_CARD' | 'CURRENCY_SELECTION' | 'CC_BILLING_ADDRESS' }
): SimpleBuyActionTypes => ({
type: AT.SET_STEP,
payload:
payload.step === 'ENTER_AMOUNT'
? {
step: payload.step,
cryptoCurrency: payload.cryptoCurrency,
defaultMethod: payload.defaultMethod,
fiatCurrency: payload.fiatCurrency,
pair: payload.pair
}
: payload.step === 'CRYPTO_SELECTION'
? {
step: payload.step,
cryptoCurrency: payload.cryptoCurrency,
Expand Down
Expand Up @@ -17,6 +17,7 @@ const INITIAL_STATE: SimpleBuyState = {
order: undefined,
orders: Remote.NotAsked,
pairs: Remote.NotAsked,
pair: undefined,
providerDetails: Remote.NotAsked,
quote: Remote.NotAsked,
step: 'CURRENCY_SELECTION',
Expand Down Expand Up @@ -235,6 +236,16 @@ export function simpleBuyReducer (
case AT.SET_STEP:
switch (action.payload.step) {
case 'ENTER_AMOUNT':
return {
...state,
cryptoCurrency: action.payload.cryptoCurrency,
defaultMethod: action.payload.defaultMethod,
fiatCurrency: action.payload.fiatCurrency,
step: action.payload.step,
pair: action.payload.pair,
order: undefined
}
case 'CRYPTO_SELECTION':
return {
...state,
cryptoCurrency: action.payload.cryptoCurrency,
Expand Down
Expand Up @@ -156,10 +156,12 @@ export default ({
yield put(actions.form.stopSubmit('cancelSBOrderForm'))
yield put(A.fetchSBOrders())
if (state === 'PENDING_CONFIRMATION' && fiatCurrency) {
const pair = S.getSBPair(yield select())
yield put(
A.setStep({
step: 'ENTER_AMOUNT',
fiatCurrency
fiatCurrency,
pair
})
)
} else {
Expand Down Expand Up @@ -204,8 +206,9 @@ export default ({
// Wait for the form to be INITIALIZED and display err
const step = S.getStep(yield select())
if (step !== 'ENTER_AMOUNT') {
const pair = S.getSBPair(yield select())
const fiatCurrency = S.getFiatCurrency(yield select()) || 'EUR'
yield put(A.setStep({ step: 'ENTER_AMOUNT', fiatCurrency }))
yield put(A.setStep({ step: 'ENTER_AMOUNT', fiatCurrency, pair }))
yield take(AT.INITIALIZE_CHECKOUT)
yield delay(3000)
yield put(actions.form.startSubmit('simpleBuyCheckout'))
Expand Down Expand Up @@ -698,7 +701,7 @@ export default ({
)
} else {
yield put(
A.setStep({ step: 'ENTER_AMOUNT', cryptoCurrency, fiatCurrency })
A.setStep({ step: 'CRYPTO_SELECTION', cryptoCurrency, fiatCurrency })
)
}
}
Expand Down
Expand Up @@ -32,6 +32,13 @@ export const getSBQuote = (state: RootState) => state.components.simpleBuy.quote

export const getSBPairs = (state: RootState) => state.components.simpleBuy.pairs

export const getSBPair = (state: RootState) =>
state.components.simpleBuy.pair || {
buyMax: '',
buyMin: '',
pair: ''
}

export const getSBPaymentMethods = (state: RootState) =>
state.components.simpleBuy.methods

Expand Down
Expand Up @@ -49,6 +49,7 @@ export type SBFormPaymentMethod =
})
export enum SimpleBuyStepType {
'CURRENCY_SELECTION',
'CRYPTO_SELECTION',
'ENTER_AMOUNT',
'ORDER_SUMMARY',
'CHECKOUT_CONFIRM',
Expand Down Expand Up @@ -83,6 +84,7 @@ export type SimpleBuyState = {
methods: RemoteDataType<string, SBPaymentMethodsType>
order: undefined | SBOrderType
orders: RemoteDataType<string, Array<SBOrderType>>
pair: undefined | SBPairType
pairs: RemoteDataType<string, Array<SBPairType>>
providerDetails: RemoteDataType<string, SBProviderDetailsType>
quote: RemoteDataType<string, SBQuoteType>
Expand Down Expand Up @@ -292,8 +294,15 @@ interface SetStepAction {
cryptoCurrency?: CoinType
defaultMethod?: SBFormPaymentMethod
fiatCurrency: FiatType
pair: SBPairType
step: 'ENTER_AMOUNT'
}
| {
cryptoCurrency?: CoinType
defaultMethod?: SBFormPaymentMethod
fiatCurrency: FiatType
step: 'CRYPTO_SELECTION'
}
| {
order: SBOrderType
step:
Expand Down
Expand Up @@ -5,6 +5,7 @@ import {
FiatType,
RemoteDataType,
SBBuyOrderType,
SBPairType,
SBPaymentMethodsType,
SBSellOrderType
} from 'core/types'
Expand Down Expand Up @@ -47,7 +48,8 @@ class AddCard extends PureComponent<Props> {

const mapStateToProps = (state: RootState): LinkStatePropsType => ({
data: getData(state),
fiatCurrency: selectors.components.simpleBuy.getFiatCurrency(state) || 'EUR'
fiatCurrency: selectors.components.simpleBuy.getFiatCurrency(state) || 'EUR',
pair: selectors.components.simpleBuy.getSBPair(state)
})

const mapDispatchToProps = (dispatch: Dispatch): LinkDispatchPropsType => ({
Expand All @@ -65,6 +67,7 @@ type LinkDispatchPropsType = {
type LinkStatePropsType = {
data: RemoteDataType<string, SuccessStateType>
fiatCurrency: FiatType
pair: SBPairType
}
export type SuccessStateType = {
formValues?: SBAddCardFormValuesType
Expand Down
Expand Up @@ -65,7 +65,7 @@ const Success: React.FC<InjectedFormProps<{}, Props, ErrorType> &
})
: props.simpleBuyActions.setStep({
fiatCurrency: props.fiatCurrency,
step: 'ENTER_AMOUNT'
step: 'CRYPTO_SELECTION'
})
}
/>
Expand Down
@@ -0,0 +1,93 @@
import {
CoinType,
SBPairType,
SupportedCoinsType,
SupportedCoinType
} from 'core/types'
import { fiatToString } from 'core/exchange/currency'
import {
getCoinFromPair,
getFiatFromPair
} from 'data/components/simpleBuy/model'
import { Icon, Text } from 'blockchain-info-components'
import { RatesType } from 'data/types'
import React from 'react'
import styled from 'styled-components'

const DisplayContainer = styled.div<{
coinType: SupportedCoinType
}>`
display: flex;
width: 100%;
align-items: center;
box-sizing: border-box;
padding: 16px 40px;
border-bottom: 1px solid ${props => props.theme.grey000};
&hover {
background-color: ${props => props.theme.grey100};
}
`
const Display = styled.div`
position: relative;
display: flex;
flex-direction: column;
margin-left: 12px;
width: 100%;
cursor: pointer;
font-size: 16px;
font-weight: 500;
color: ${props => props.theme.grey800};
`
const DisplayName = styled(Text)`
font-weight: 600;
`

const Rate = styled(Text)`
font-size: 14px;
font-weight: 500;
margin-top: 4px;
color: ${props => props.theme.grey600} !important;
> span {
color: ${props => props.theme.green500};
}
`

export type Props = {
onClick: (string) => void
rates: { [key in CoinType]: RatesType }
supportedCoins: SupportedCoinsType
value: SBPairType
}

const CryptoItem: React.FC<Props> = props => {
const coin = getCoinFromPair(props.value.pair)
const fiat = getFiatFromPair(props.value.pair)
const coinType = props.supportedCoins[coin]
const displayName = coinType.displayName
const icon = coinType.icons.circleFilled
const color = coinType.colorCode

return (
<DisplayContainer
coinType={coinType}
data-e2e={`sb${props.value.pair}CurrencySelector`}
role='button'
onClick={props.onClick}
>
<Icon size='32px' color={color} name={icon} />
<Display>
<DisplayName>{displayName}</DisplayName>
<Rate>
{fiatToString({
value: props.rates[coin][fiat].last,
unit: fiat
})}
<span>+ xx.x%</span>
</Rate>
</Display>
<Icon name='chevron-right' size='32px' color='grey600' />
</DisplayContainer>
)
}

export default CryptoItem
@@ -0,0 +1,70 @@
import { actions, selectors } from 'data'
import { bindActionCreators, Dispatch } from 'redux'
import {
CoinType,
FiatEligibleType,
FiatType,
RemoteDataType,
SBCardType,
SBPairType,
SBPaymentMethodsType,
SupportedCoinsType
} from 'core/types'
import { connect, ConnectedProps } from 'react-redux'
import { getData } from './selectors'
import { RatesType } from 'data/types'
import { RootState } from 'data/rootReducer'
import Failure from './template.failure'
import Loading from './template.loading'
import React, { PureComponent } from 'react'
import Success from './template.success'

class CryptoSelection extends PureComponent<Props> {
componentDidMount () {
if (this.props.fiatCurrency) {
this.props.simpleBuyActions.fetchSBPairs(this.props.fiatCurrency)
this.props.simpleBuyActions.fetchSBFiatEligible(this.props.fiatCurrency)
}
}

render () {
return this.props.data.cata({
Success: val => <Success {...val} {...this.props} />,
Failure: () => <Failure {...this.props} />,
Loading: () => <Loading />,
NotAsked: () => <Loading />
})
}
}

const mapStateToProps = (state: RootState): LinkStatePropsType => ({
data: getData(state),
fiatCurrency: selectors.components.simpleBuy.getFiatCurrency(state) || 'USD'
})

export const mapDispatchToProps = (dispatch: Dispatch) => ({
formActions: bindActionCreators(actions.form, dispatch),
simpleBuyActions: bindActionCreators(actions.components.simpleBuy, dispatch)
})

const connector = connect(mapStateToProps, mapDispatchToProps)

export type OwnProps = {
handleClose: () => void
}
export type SuccessStateType = {
cards: Array<SBCardType>
eligibility: FiatEligibleType
pairs: Array<SBPairType>
paymentMethods: SBPaymentMethodsType
rates: { [key in CoinType]: RatesType }
supportedCoins: SupportedCoinsType
}
export type LinkStatePropsType = {
data: RemoteDataType<string, SuccessStateType>
fiatCurrency: FiatType
}
export type LinkDispatchPropsType = ReturnType<typeof mapDispatchToProps>
export type Props = OwnProps & ConnectedProps<typeof connector>

export default connector(CryptoSelection)

0 comments on commit 4bda1dc

Please sign in to comment.