Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(frictions): restructure frictions code #6243

Merged
merged 1 commit into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading