Skip to content

Commit

Permalink
chore(frictions): restructure frictions code (#6243)
Browse files Browse the repository at this point in the history
  • Loading branch information
mperdomo-bc committed Jan 26, 2024
1 parent 662a6bb commit 10da9da
Show file tree
Hide file tree
Showing 15 changed files with 63 additions and 260 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,4 @@
import React from 'react'
import styled, { css } from 'styled-components'

import { Image } from 'blockchain-info-components'

export const ImageName = {
BUY_CRYPTO: <Image name='cart-green' />,
KYC_VERIFICATION: <Image name='identification' />
}

export const IconColors = {
BUY_CRYPTO: 'green600',
KYC_VERIFICATION: 'purple500'
}
import styled from 'styled-components'

export const ItemButton = styled.button<{ isComplete?: boolean; status: string }>`
border: 1px solid ${(props) => props.theme.grey100};
Expand All @@ -28,45 +15,6 @@ export const ButtonContent = styled.div`
align-items: center;
`

const ItemPurple = styled(ItemButton)`
${(props) =>
props.isComplete
? ''
: css`
&:hover {
border-color: ${(props) => props.theme.purple500};
background-color: ${(props) => props.theme.purple000};
}
`};
`
const ItemBlue = styled(ItemButton)`
${(props) =>
props.isComplete
? ''
: css`
&:hover {
border-color: ${(props) => props.theme.blue600};
background-color: ${(props) => props.theme.blue000};
}
`};
`
const ItemGreen = styled(ItemButton)`
${(props) =>
props.isComplete
? ''
: css`
&:hover {
border-color: ${(props) => props.theme.green600};
background-color: ${(props) => props.theme.green000};
}
`};
`

export const MainContainer = {
BUY_CRYPTO: ItemGreen,
KYC_VERIFICATION: ItemPurple
}

export const IconWrapper = styled.div`
display: flex;
flex-direction: column;
Expand All @@ -79,15 +27,6 @@ export const IconWrapper = styled.div`
align-self: center;
}
`
const PurpleIconWrapper = styled(IconWrapper)`
background-color: ${(props) => props.theme.purple000};
`
const BlueIconWrapper = styled(IconWrapper)`
background-color: ${(props) => props.theme.blue000};
`
const GreenIconWrapper = styled(IconWrapper)`
background-color: ${(props) => props.theme.green000};
`

export const MainSection = styled.div`
display: flex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useRemote } from 'hooks'
import ModalEnhancer from 'providers/ModalEnhancer'

import { Loading, LoadingTextEnum } from '../../components'
import { ModalPropsType } from '../../types'
import LinkItem from './LinkItem'
import {
CloseIconContainer,
Expand All @@ -28,10 +29,10 @@ import {
} from './model'
import { getData } from './selectors'

const CompleteProfile = (props) => {
const CompleteProfile = ({ close, position, total, userClickedOutside }: ModalPropsType) => {
const dispatch = useDispatch()

const data = useSelector(getData)
const { isBankOrCardLinked, isKycVerified } = useSelector(getData)

const { data: handholdData, isLoading, isNotAsked } = useRemote(getVerificationSteps)

Expand All @@ -41,7 +42,7 @@ const CompleteProfile = (props) => {
setShow(false)

setTimeout(() => {
props.close(ModalName.COMPLETE_USER_PROFILE)
close(ModalName.COMPLETE_USER_PROFILE)
}, duration)
}

Expand All @@ -66,19 +67,17 @@ const CompleteProfile = (props) => {
}

const handleLinkBankOrCardClick = () => {
if (data.isVerifiedId) {
if (isKycVerified) {
startAddingCards()
} else {
startVerification()
}
}

const handleBuyCryptoClick = () => {
const { isBankOrCardLinked, isVerifiedId } = data

if (isBankOrCardLinked) {
dispatch(buySell.showModal({ origin: 'CompleteProfile' }))
} else if (isVerifiedId) {
} else if (isKycVerified) {
startAddingCards()
return
} else {
Expand Down Expand Up @@ -146,7 +145,14 @@ const CompleteProfile = (props) => {
const percentage = itemsLength > 0 ? (completedSteps / itemsLength) * 100 : 0

return (
<Flyout {...props} isOpen={show} onClose={handleClose} data-e2e='completeProfileModal'>
<Flyout
total={total}
position={position}
userClickedOutside={userClickedOutside}
isOpen={show}
onClose={handleClose}
data-e2e='completeProfileModal'
>
<FlyoutChild>
<Wrapper>
{(isLoading || isNotAsked) && <Loading text={LoadingTextEnum.LOADING} />}
Expand Down Expand Up @@ -212,8 +218,8 @@ const CompleteProfile = (props) => {
iconUrl={iconUrl}
key={id}
metadata={metadata}
onClick={() => getOnClick(id as COMPLETE_PROFILE_STEPS)}
status={status as 'IDLE' | 'PENDING' | 'COMPLETED' | 'DISABLED'}
onClick={() => getOnClick(id)}
status={status}
subtitle={subtitle}
title={title}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,9 @@ export const CloseIconContainer = styled.div`
}
`

export const CentralContainer = styled.div`
export const LinksWrapper = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
`
export const LinksWrapper = styled(CentralContainer)`
padding-top: 26px;
`
Original file line number Diff line number Diff line change
@@ -1,50 +1,30 @@
import { BSPaymentMethodsType, BSPaymentTypes, TermType } from '@core/types'
import { BSPaymentMethodsType, BSPaymentTypes } from '@core/types'
import { model, selectors } from 'data'
import { RootState } from 'data/rootReducer'

const { KYC_STATES } = model.profile

type ReturnData = {
isBankOrCardLinked: boolean
isBuyCrypto: boolean
isKycPending: boolean
isVerifiedId: boolean
isKycVerified: boolean
}

export const getData = (state: RootState): ReturnData => {
const userData = selectors.modules.profile.getUserData(state).getOrElse({
kycState: undefined,
tiers: { current: 0 }
})

const isKycPending = [KYC_STATES.PENDING, KYC_STATES.UNDER_REVIEW].includes(userData.kycState)

const userData = selectors.modules.profile.getUserData(state).getOrElse({ kycState: undefined })
const isKycVerified = userData.kycState === KYC_STATES.VERIFIED

// user have some cards or banks linked
const cards = selectors.components.buySell.getBSCards(state).getOrElse([])
// Check if user has cards or banks linked
const hasLinkedCards = selectors.components.buySell.getBSCards(state).getOrElse([]).length > 0
const paymentMethods = selectors.components.buySell
.getBSPaymentMethods(state)
.getOrElse({} as BSPaymentMethodsType)
const isAnyBankLinked =
paymentMethods?.methods?.length > 0 &&
paymentMethods.methods.find(
(method) => method.eligible && method.type === BSPaymentTypes.LINK_BANK
)
const isBankOrCardLinked = !!(cards.length > 0 || isAnyBankLinked)

// user accumulated amount all the time
const accumulatedTrades = selectors.components.buySell.getAccumulatedTrades(state).getOrElse([])

const isBuyCrypto =
Number(
accumulatedTrades?.find((accumulated) => accumulated.termType === TermType.ALL)?.amount?.value
) > 0 ?? false
const hasLinkedBank = paymentMethods?.methods?.some(
(method) => method.eligible && method.type === BSPaymentTypes.LINK_BANK
)
const isBankOrCardLinked = hasLinkedCards || hasLinkedBank

return {
isBankOrCardLinked,
isBuyCrypto,
isKycPending,
isVerifiedId: isKycVerified
isKycVerified
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react'
import styled from 'styled-components'

import { Text } from 'blockchain-info-components'
import { useCountDown } from 'hooks'

import { useCountdownTo } from '../../CompleteProfile/countdownTo'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ const Success = ({
}

// BE will provide id to contains OPTIONAL in any children
const isOptional = node.children && node.children.some((item) => item.id.includes('UNDEFINED'))
const isOptional = node?.children?.some((item) => item.id.includes('UNDEFINED'))

return (
<FormGroup key={node.id}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,13 @@ const SelfAssessmentModal = ({ close, position, total, userClickedOutside }: Mod

const [step, setStep] = useState(-1)
const [show, setShow] = useState(false)
const [isLoading, setLoading] = useState(false)
const [loading, setLoading] = useState(false)
const [errorMessage, setErrorMessage] = useState()
const [modalQuestions, setModalQuestions] = useState<SelfAssessmentType>(QUESTIONS_INITIAL)
const [resultData, setResultData] = useState<QuizSubmitResult>({} as QuizSubmitResult)

// Here we hold the ref to the form to send it later without re-rendering extra times
const dataRef = useRef<SelfAssessmentType>({
blocking: false,
introPage: {} as IntroPageType,
pages: []
})
const dataRef = useRef<SelfAssessmentType>(QUESTIONS_INITIAL)

const getModalData = async () => {
setLoading(true)
Expand Down Expand Up @@ -106,9 +102,9 @@ const SelfAssessmentModal = ({ close, position, total, userClickedOutside }: Mod
const { introPage, pages } = modalQuestions

const isLastPage = step === pages?.length - 1
const showResultScreen = !isLoading && !!resultData?.status
const showAssessment = !isLoading && modalQuestions && !showResultScreen
const showError = !isLoading && errorMessage
const showResultScreen = !loading && !!resultData?.status
const showError = !loading && errorMessage
const showAssessment = !loading && modalQuestions && !showResultScreen && !showError

return (
<Flyout
Expand All @@ -121,7 +117,7 @@ const SelfAssessmentModal = ({ close, position, total, userClickedOutside }: Mod
>
<FlyoutChild>
<Wrapper>
{isLoading && <Loading text={LoadingTextEnum.LOADING} />}
{loading && <Loading text={LoadingTextEnum.LOADING} />}
{showError && (
<FlyoutOopsError
errorMessage={errorMessage}
Expand All @@ -133,7 +129,7 @@ const SelfAssessmentModal = ({ close, position, total, userClickedOutside }: Mod
{showAssessment && (
<SelfAssessment
introPage={step < 0 ? introPage : {}}
nodes={pages[step]?.nodes}
nodes={pages[step]?.nodes ?? []}
dataRef={dataRef}
step={step}
onSubmit={isLastPage ? handleSubmit : goToNextStep}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { ExtraQuestionsType, NodeType } from '@core/types'

export type IntroPageType = {
footer: { action?: { type: string; url: string }; text: string; type: string }[]
footer: Array<{ action?: { type: string; url: string }; text: string; type: string }>
header: { description: string; imageUrl: string; title: string }
}

export type Page = { nodes: NodeType }

export type SelfAssessmentType = Omit<ExtraQuestionsType, 'nodes' | 'context'> & {
introPage: IntroPageType
pages: Page[]
pages: Array<Page>
}

export type QuizSubmitResult = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ const Success = ({
<Field
name={item.id}
errorBottom
pattern={item.regex}
validate={isOptional ? null : required}
component={TextBox}
placeholder={GetInputPlaceholder(item)}
Expand Down Expand Up @@ -334,7 +335,7 @@ const Success = ({
}

// BE will provide id to contains OPTIONAL in any children
const isOptional = node.children && node.children.some((item) => item.id.includes('UNDEFINED'))
const isOptional = node?.children?.some((item) => item.id.includes('UNDEFINED'))

return (
<FormGroup key={node.id}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ const SelfClassification = ({ close, position, total, userClickedOutside }: Moda

const showLoading = isLoading || isNotAsked
const hasSomeError = !isLoading && (showError || !!error)
const showQuestion =
!hasSomeError && extraKYCResponse && Object.keys(extraKYCResponse ?? {}).length

return (
<Flyout
Expand All @@ -112,7 +114,7 @@ const SelfClassification = ({ close, position, total, userClickedOutside }: Moda
handler={handleClose}
/>
)}
{!isLoading && extraKYCResponse && (
{showQuestion && (
<>
<Header text='Self Classification Questionaire' onClickBack={handleClose} />
<SelfClassificationSuccess
Expand Down
Loading

0 comments on commit 10da9da

Please sign in to comment.