Skip to content

Commit

Permalink
feat(cta-interest): implemented CTA section for interest
Browse files Browse the repository at this point in the history
  • Loading branch information
milan-bc committed Feb 17, 2021
1 parent a6362d7 commit 21ca927
Show file tree
Hide file tree
Showing 19 changed files with 667 additions and 12 deletions.
2 changes: 2 additions & 0 deletions packages/blockchain-info-components/src/Images/Images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import appleAppStoreBadge from './img/apple-app-store-badge.svg'
import bank from './img/bank.svg'
import bankError from './img/bank-error.svg'
import bankSuccess from './img/bank-success.svg'
import bgBannerPattern from './img/bg-banner-pattern.svg'
import bgPattern from './img/bg-pattern.svg'
import bitpayLogo from './img/bitpay-logo.svg'
import blankCard from './img/blank-card.svg'
Expand Down Expand Up @@ -169,6 +170,7 @@ const Images = {
'bank-success': bankSuccess,
'bank-logo-bbt': bankLogoBbt,
'bg-pattern': bgPattern,
'bg-banner-pattern': bgBannerPattern,
'bitpay-logo': bitpayLogo,
'blank-card': blankCard,
'blockchain-logo': blockchainLogo,
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,9 @@ type MessagesType = {
'modals.simplebuy.info_and_residential.dob': 'Date of Birth'
'modals.simplebuy.info_and_residential.dob_caption': 'You must be 18 years of age or older to Buy Crypto.'
'modals.simplebuy.instantly_buy': 'Instantly buy crypto with any Visa or Mastercard.'
'modals.simplebuy.interest_banner.title': 'Earn {interestRate}% on this {displayName} Purchase'
'modals.simplebuy.interest_banner.description': 'Send your {amount}{currency} to your {displayName} Interest Account.'
'modals.simplebuy.interest_banner.earn_now': 'Earn Now ->'
'modals.simplebuy.most_popular': 'Most Popular'
'modals.simplebuy.select_crypto': 'Easily buy and sell Crypto straight from your Wallet.'
'modals.simplebuy.selectcrypto.sell_banner_title': 'Want to sell from your other Wallets?'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,15 @@ export const CustomBox = styled(Box)`
flex-direction: column;
justify-content: space-between;
`
export const CustomBoxRightOriented = styled.div`
position: relative;
padding: 24px;
border-radius: 8px;
border: 1px solid ${props => props.theme.grey000};
background-image: url('/img/bg-banner-pattern.svg');
background-repeat: repeat-y;
background-position: right;
display: flex;
flex-direction: column;
justify-content: space-between;
`
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,13 @@ export const ROUTE_TO_TX_HASH = '@EVENT.INTEREST.ROUTE_TO_TX_HASH'
export const SHOW_INTEREST_MODAL = '@EVENT.INTEREST.SHOW_INTEREST_MODAL'
export const SET_INTEREST_STEP = '@EVENT.INTEREST.SET_INTEREST_STEP'
export const SET_COIN_DISPLAY = '@EVENT.INTEREST.SET_COIN_DISPLAY'

// INTEREST CTA AFTER TRANSACTION
export const FETCH_AFTER_TRANSACTION =
'@EVENT.INTEREST.FETCH_IFETCH_AFTER_TRANSACTIONNTEREST_RATE'
export const FETCH_AFTER_TRANSACTION_FAILURE =
'@EVENT.INTEREST.FETCH_AFTER_TRANSACTION_FAILURE'
export const FETCH_AFTER_TRANSACTION_LOADING =
'@EVENT.INTEREST.FETCH_AFTER_TRANSACTION_LOADING'
export const FETCH_AFTER_TRANSACTION_SUCCESS =
'@EVENT.INTEREST.FETCH_AFTER_TRANSACTION_SUCCESS'
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { CoinType, FiatType, PaymentValue } from 'core/types'
import {
InterestAccountBalanceType,
InterestAccountType,
InterestAfterTransactionType,
InterestEligibleType,
InterestInstrumentsType,
InterestLimitsType,
Expand Down Expand Up @@ -265,3 +266,23 @@ export const showInterestModal = (step: InterestStep, coin: CoinType) => ({
payload: { step, coin },
type: AT.SHOW_INTEREST_MODAL
})

// INTEREST CTA AFTER TRANSACTION
export const fetchAfterTransaction = () => ({
type: AT.FETCH_AFTER_TRANSACTION
})
export const fetchAfterTransactionFailure = (
error: string
): InterestActionTypes => ({
type: AT.FETCH_AFTER_TRANSACTION_FAILURE,
payload: { error }
})
export const fetchAfterTransactionLoading = (): InterestActionTypes => ({
type: AT.FETCH_AFTER_TRANSACTION_LOADING
})
export const fetchAfterTransactionSuccess = (
afterTransaction: InterestAfterTransactionType
): InterestActionTypes => ({
type: AT.FETCH_AFTER_TRANSACTION_SUCCESS,
payload: { afterTransaction }
})
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { InterestActionTypes, InterestState } from './types'
const INITIAL_STATE: InterestState = {
account: Remote.NotAsked,
accountBalance: Remote.NotAsked,
afterTransaction: Remote.NotAsked,
coin: 'BTC',
depositLimits: {
maxFiat: 0,
Expand Down Expand Up @@ -224,7 +225,21 @@ export function interestReducer (
...state,
coin: payload.coin
}

case AT.FETCH_AFTER_TRANSACTION_FAILURE:
return {
...state,
afterTransaction: Remote.Failure(payload.error)
}
case AT.FETCH_AFTER_TRANSACTION_LOADING:
return {
...state,
afterTransaction: Remote.Loading
}
case AT.FETCH_AFTER_TRANSACTION_SUCCESS:
return {
...state,
afterTransaction: Remote.Success(payload.afterTransaction)
}
default:
return state
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,9 @@ export default ({
],
interestSagas.fetchInterestBalance
)
yield takeLatest(
AT.FETCH_AFTER_TRANSACTION,
interestSagas.fetchAfterTransaction
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import BigNumber from 'bignumber.js'
import {
AccountTypes,
CoinType,
InterestAfterTransactionType,
PaymentValue,
RatesType,
RemoteDataType,
Expand Down Expand Up @@ -149,7 +150,6 @@ export default ({
yield put(A.fetchInterestRateFailure(error))
}
}

const fetchInterestTransactions = function * ({
payload
}: ReturnType<typeof A.fetchInterestTransactions>) {
Expand Down Expand Up @@ -458,7 +458,21 @@ export default ({
)
}

const fetchAfterTransaction = function * () {
try {
yield put(A.fetchAfterTransactionLoading())
const response: InterestAfterTransactionType = yield call(
api.getInterestCtaAfterTransaction
)
yield put(A.fetchAfterTransactionSuccess(response))
} catch (e) {
const error = errorHandler(e)
yield put(A.fetchAfterTransactionFailure(error))
}
}

return {
fetchAfterTransaction,
fetchInterestBalance,
fetchInterestEligible,
fetchInterestInstruments,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,6 @@ export const getWalletCurrency = (

export const getWithdrawalMinimums = (state: RootState) =>
state.components.interest.withdrawalMinimums

export const getAfterTransaction = (state: RootState) =>
state.components.interest.afterTransaction
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
FiatType,
InterestAccountBalanceType,
InterestAccountType,
InterestAfterTransactionType,
InterestEligibleType,
InterestInstrumentsType,
InterestLimitsType,
Expand Down Expand Up @@ -59,6 +60,7 @@ export type InterestStep = keyof typeof InterestSteps
export interface InterestState {
account: RemoteDataType<string, InterestAccountType>
accountBalance: RemoteDataType<string, InterestAccountBalanceType>
afterTransaction: RemoteDataType<string, InterestAfterTransactionType>
coin: CoinType
depositLimits: InterestMinMaxType
instruments: RemoteDataType<string, InterestInstrumentsType>
Expand Down Expand Up @@ -266,7 +268,23 @@ interface ShowInterestModal {
type: typeof AT.SHOW_INTEREST_MODAL
}

// INTEREST CTA AFTER TRANSACTION
interface FetchInterestAfterTransactionFailure {
payload: { error: string }
type: typeof AT.FETCH_AFTER_TRANSACTION_FAILURE
}
interface FetchInterestAfterTransactionLoading {
type: typeof AT.FETCH_AFTER_TRANSACTION_LOADING
}
interface FetchInterestAfterTransactionSuccess {
payload: { afterTransaction: InterestAfterTransactionType }
type: typeof AT.FETCH_AFTER_TRANSACTION_SUCCESS
}

export type InterestActionTypes =
| FetchInterestAfterTransactionFailure
| FetchInterestAfterTransactionLoading
| FetchInterestAfterTransactionSuccess
| FetchInterestBalanceFailure
| FetchInterestBalanceLoading
| FetchInterestBalanceSuccess
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { bindActionCreators, Dispatch } from 'redux'
import { connect, ConnectedProps } from 'react-redux'
import React, { PureComponent } from 'react'

import { actions } from 'data'
import { RemoteDataType } from 'core/types'

import { getData } from './selectors'
import Template from './template.success'

class InterestBanner extends PureComponent<Props> {
componentDidMount () {
this.props.interestActions.fetchInterestRate()
}
render () {
return this.props.data.cata({
Success: val => <Template {...this.props} {...val} />,
Failure: () => null,
Loading: () => null,
NotAsked: () => null
})
}
}

const mapStateToProps = (state): LinkStatePropsType => ({
data: getData(state)
})

const mapDispatchToProps = (dispatch: Dispatch) => ({
interestActions: bindActionCreators(actions.components.interest, dispatch)
})

const connector = connect(mapStateToProps, mapDispatchToProps)

export type OwnPropsType = {
handleClose: () => void
}

export type SuccessStateType = ReturnType<typeof getData>['data']

export type LinkStatePropsType = {
data: RemoteDataType<string, SuccessStateType>
}

export type Props = OwnPropsType & ConnectedProps<typeof connector>

export default connector(InterestBanner)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { lift } from 'ramda'

import { ExtractSuccess, SupportedWalletCurrenciesType } from 'core/types'
import { RootState } from 'data/rootReducer'
import { selectors } from 'data'

export const getData = (state: RootState) => {
const supportedCoinsR = selectors.core.walletOptions.getSupportedCoins(state)
const interestRateR = selectors.components.interest.getInterestRate(state)
const afterTransactionR = selectors.components.interest.getAfterTransaction(
state
)

return lift(
(
supportedCoins: SupportedWalletCurrenciesType,
interestRate: ExtractSuccess<typeof interestRateR>,
afterTransaction: ExtractSuccess<typeof afterTransactionR>
) => ({
supportedCoins,
interestRate,
afterTransaction
})
)(supportedCoinsR, interestRateR, afterTransactionR)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { FormattedMessage } from 'react-intl'
import React from 'react'

import { Button, Text } from 'blockchain-info-components'
import { CustomBoxRightOriented } from 'components/Layout'

import { Props as OwnProps, SuccessStateType } from './index'

type Props = OwnProps & SuccessStateType

const InterestBanner: React.FC<Props> = ({
supportedCoins,
interestRate,
afterTransaction,
interestActions
}) => {
const { amount, currency } = afterTransaction
const { displayName } = supportedCoins[currency]
return (
<CustomBoxRightOriented>
<div>
<Text
size='16px'
color='grey900'
weight={600}
style={{ marginTop: '16px' }}
>
<FormattedMessage
id='modals.simplebuy.interest_banner.title'
defaultMessage='Earn {interestRate}% on this {displayName} Purchase'
values={{
displayName,
interestRate: interestRate[currency]
}}
/>
</Text>
<Text
size='14px'
color='grey600'
weight={500}
style={{ marginTop: '4px', lineHeight: 1.5, maxWidth: '286px' }}
>
<FormattedMessage
id='modals.simplebuy.interest_banner.description'
defaultMessage='Send your {amount}{currency} to your {displayName} Interest Account.'
values={{
amount,
currency,
displayName
}}
/>
</Text>
</div>
<Button
style={{ marginTop: '16px', maxWidth: '144px' }}
nature='light'
data-e2e='earnInterestNow'
onClick={() =>
interestActions.showInterestModal('ACCOUNT_SUMMARY', currency)
}
>
<FormattedMessage
id='modals.simplebuy.interest_banner.earn_now'
defaultMessage='Earn Now ->'
/>
</Button>
</CustomBoxRightOriented>
)
}

export default InterestBanner
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { bindActionCreators, Dispatch } from 'redux'
import { connect, ConnectedProps } from 'react-redux'
import { equals } from 'ramda'
import React, { PureComponent } from 'react'

import { actions, selectors } from 'data'
Expand Down Expand Up @@ -36,6 +37,7 @@ class OrderSummary extends PureComponent<Props> {
order: this.props.order
})
}
this.props.interestActions.fetchAfterTransaction()
}

handleRefresh = () => {
Expand All @@ -62,12 +64,14 @@ const mapStateToProps = (state: RootState): LinkStatePropsType => ({
data: getData(state),
supportedCoins: selectors.core.walletOptions
.getSupportedCoins(state)
.getOrFail('Supported coins missing')
.getOrFail('Supported coins missing'),
isGoldVerified: equals(selectors.modules.profile.getCurrentTier(state), 2)
})

const mapDispatchToProps = (dispatch: Dispatch) => ({
simpleBuyActions: bindActionCreators(actions.components.simpleBuy, dispatch),
sendActions: bindActionCreators(actions.components.send, dispatch)
sendActions: bindActionCreators(actions.components.send, dispatch),
interestActions: bindActionCreators(actions.components.interest, dispatch)
})
const connector = connect(mapStateToProps, mapDispatchToProps)

Expand All @@ -80,6 +84,7 @@ export type SuccessStateType = ExtractSuccess<ReturnType<typeof getData>>

type LinkStatePropsType = {
data: RemoteDataType<string, SuccessStateType>
isGoldVerified: boolean
supportedCoins: SupportedWalletCurrenciesType
}
export type Props = OwnProps & ConnectedProps<typeof connector>
Expand Down

0 comments on commit 21ca927

Please sign in to comment.