Skip to content

Commit

Permalink
feat: implemented linked banks
Browse files Browse the repository at this point in the history
  • Loading branch information
milan-bc committed Aug 12, 2020
1 parent 47e38a2 commit d3030ee
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2008,6 +2008,7 @@ type MessagesType = {
'scenes.settings.general.walletid.title': 'Wallet ID'
'scenes.settings.general.walletid.warning': 'Do not share your Wallet ID with others.'
'scenes.settings.linked_banks': 'Linked Banks'
'scenes.settings.linked_banks.daily_limit': '{amount} Daily Limit'
'scenes.settings.linked_cards': 'Linked Cards'
'scenes.settings.menu.title': 'Wallets & Addresses'
'scenes.settings.menu.subtitle': 'Manage your wallet names, addresses and private keys.'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import DisplaySubTitle from './DisplaySubTitle'
import DisplayTitle from './DisplayTitle'
import MultiRowContainer from './MultiRowContainer'

export const DisplayPaymentIcon = styled(DisplayIcon)<{
const DisplayPaymentIcon = styled(DisplayIcon)<{
showBackground: boolean
}>`
align-items: center;
Expand All @@ -28,5 +28,6 @@ export {
Content,
DisplayTitle,
DisplaySubTitle,
MultiRowContainer
MultiRowContainer,
DisplayPaymentIcon
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as AT from './actionTypes'
import { BeneficiariesType, WalletFiatType } from 'core/types'
import { CustodialActionTypes } from './types'

export const fetchCustodialBeneficiaries = (currency: WalletFiatType) => ({
export const fetchCustodialBeneficiaries = (currency?: WalletFiatType) => ({
type: AT.FETCH_CUSTODIAL_BENEFICIARIES,
currency
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { actions, selectors } from 'data'
import { bindActionCreators, Dispatch } from 'redux'
import { connect, ConnectedProps } from 'react-redux'
import { ExtractSuccess, RemoteDataType, WalletFiatType } from 'core/types'
import { getData } from './selectors'
import { RootState } from 'data/rootReducer'
import Loading from './template.loading'
import React, { PureComponent } from 'react'
import Success from './template.success'

class LinkedBanks extends PureComponent<Props> {
componentDidMount () {
this.props.custodialActions.fetchCustodialBeneficiaries()
this.props.simpleBuyActions.fetchSBPaymentMethods(this.props.fiatCurrency)
}

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

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

const mapDispatchToProps = (dispatch: Dispatch) => ({
custodialActions: bindActionCreators(actions.custodial, dispatch),
simpleBuyActions: bindActionCreators(actions.components.simpleBuy, dispatch),
withdrawActions: bindActionCreators(actions.components.withdraw, dispatch)
})

const connector = connect(mapStateToProps, mapDispatchToProps)

type OwnProps = {}
type LinkStatePropsType = {
data: RemoteDataType<string, SuccessStateType>
fiatCurrency: WalletFiatType
}
export type SuccessStateType = ExtractSuccess<ReturnType<typeof getData>>
export type Props = OwnProps & ConnectedProps<typeof connector>

export default connector(LinkedBanks)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ExtractSuccess } from 'core/types'
import { lift } from 'ramda'
import { RootState } from 'data/rootReducer'

import { selectors } from 'data'

export const getData = (state: RootState) => {
const beneficiariesR = selectors.custodial.getBeneficiaries(state)
const paymentMethodsR = selectors.components.simpleBuy.getSBPaymentMethods(
state
)
return lift(
(
beneficiaries: ExtractSuccess<typeof beneficiariesR>,
paymentMethods: ExtractSuccess<typeof paymentMethodsR>
) => ({
beneficiaries,
paymentMethods
})
)(beneficiariesR, paymentMethodsR)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { FormattedMessage } from 'react-intl'
import { SpinningLoader } from 'blockchain-info-components'
import React from 'react'
import styled from 'styled-components'

import {
SettingContainer,
SettingHeader,
SettingSummary
} from 'components/Setting'
import media from 'services/ResponsiveService'

const CustomSettingContainer = styled(SettingContainer)`
${media.atLeastTabletL`
flex-direction: row;
align-items: flex-start;
justify-content: space-between;
`}
`
const CustomSettingHeader = styled(SettingHeader)`
margin-bottom: 18px;
`

const Loading: React.FC = () => {
return (
<CustomSettingContainer>
<SettingSummary>
<CustomSettingHeader>
<FormattedMessage
id='scenes.settings.linked_banks'
defaultMessage='Linked Banks'
/>
</CustomSettingHeader>
<SpinningLoader height='30px' width='30px' />
</SettingSummary>
</CustomSettingContainer>
)
}

export default Loading
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { Button, Icon, Text } from 'blockchain-info-components'
import { convertBaseToStandard } from 'data/components/exchange/services'
import { fiatToString } from 'core/exchange/currency'
import { FormattedMessage } from 'react-intl'
import { InjectedFormProps, reduxForm } from 'redux-form'
import { Props as OwnProps, SuccessStateType } from '.'
import {
SettingContainer,
SettingHeader,
SettingSummary
} from 'components/Setting'
import media from 'services/ResponsiveService'
import React from 'react'
import styled from 'styled-components'

const CardWrapper = styled.div`
display: flex;
padding: 16px;
border-radius: 8px;
margin-bottom: 12px;
justify-content: space-between;
border: 1px solid ${props => props.theme.grey000};
cursor: pointer;
width: 430px;
${media.mobile`
width: 100%;
`}
`
const CustomSettingHeader = styled(SettingHeader)`
margin-bottom: 18px;
`
const RemoveButton = styled(Button)`
&:hover {
border-color: ${props => props.theme.red400};
background-color: transparent;
}
`
const BankIconWrapper = styled.div`
margin-right: 14px;
width: 24px;
justify-content: center;
flex-direction: column;
display: flex;
`
const Child = styled.div`
display: flex;
div:last-child {
margin-top: 4px;
}
`
const CardDetails = styled.div<{ right?: boolean }>`
text-align: ${props => (props.right ? 'right' : 'initial')};
`

const getAvailableAmount = (methods, currency) => {
const method = methods.find(
method => method.type === 'FUNDS' && method.currency === currency
)
return Number(method.limits.max)
}

const Success: React.FC<InjectedFormProps<{}, Props> & Props> = props => {
return (
<SettingContainer>
<SettingSummary>
<CustomSettingHeader>
<FormattedMessage
id='scenes.settings.linked_banks'
defaultMessage='Linked Banks'
/>
</CustomSettingHeader>
<div>
{props.beneficiaries.map((beneficiary, i) => {
return (
<CardWrapper key={i}>
<Child>
<BankIconWrapper>
<Icon name='bank-filled' color='blue600' size='16px' />
</BankIconWrapper>
<CardDetails>
<Text size='16px' color='grey800' weight={600}>
{beneficiary.name}
</Text>

<Text size='14px' color='grey600' weight={500}>
<FormattedMessage
id='scenes.settings.linked_banks.daily_limit'
defaultMessage='{amount} Daily Limit'
values={{
amount: fiatToString({
value: convertBaseToStandard(
'FIAT',
getAvailableAmount(
props.paymentMethods.methods,
beneficiary.currency
)
),
unit: beneficiary.currency || 'EUR'
})
}}
/>
</Text>
</CardDetails>
</Child>
<Child>
<CardDetails right>
<Text size='16px' color='grey800' weight={600}>
{beneficiary.address}
</Text>
</CardDetails>
<RemoveButton
data-e2e='removeCard'
nature='light-red'
disabled={props.submitting}
style={{ marginLeft: '18px', minWidth: 'auto' }}
>
<FormattedMessage
id='buttons.remove'
defaultMessage='Remove'
/>
</RemoveButton>
</Child>
</CardWrapper>
)
})}
</div>
</SettingSummary>
</SettingContainer>
)
}

type Props = OwnProps & SuccessStateType
export default reduxForm<{}, Props>({ form: 'linkedCards' })(Success)
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Banner, Text } from 'blockchain-info-components'
import { FormattedMessage } from 'react-intl'
import About from './About'
import LinkedBanks from './LinkedBanks'
import LinkedCards from './LinkedCards'
import PairingCode from './PairingCode'
import PrivacyPolicy from './PrivacyPolicy'
Expand Down Expand Up @@ -29,6 +30,7 @@ const General = () => {
</Banner>
<WalletId />
<PairingCode />
<LinkedBanks />
<LinkedCards />
<PrivacyPolicy />
<TermsOfService />
Expand Down

0 comments on commit d3030ee

Please sign in to comment.