Skip to content

Commit

Permalink
adrienne/feat: add jurisdiction selection modal (#10587)
Browse files Browse the repository at this point in the history
* feat: added wide wrapper for jurisdiction modal

* feat: added desktop view for jurisdiction modal

* chore: updated package-lock.json for wallets

* chore: removed package-lock.json in wallets

* chore: updated component typings based on comments

* chore: updated comments based on reviews

* chore: fixed issues with circleci for wallets

* chore: removed duplicated packages in wallets

* refactor: added responsive view for step wrapper

* chore: removed unused component

* feat: added responsive view for modal step wrapper

* chore: removed tested code

* chore: fixed circleci issue

* chore: backup for jurisdiction content

* backup

* feat: added responsive view for jurisdiction modal

* chore: removed eslint changes

* chore: updated types based on comments
  • Loading branch information
adrienne-deriv authored Oct 13, 2023
1 parent 5c132b9 commit 4263a92
Show file tree
Hide file tree
Showing 16 changed files with 885 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
display: flex;
flex-direction: column;
justify-content: center;
max-width: 25%;
width: 25%;
position: relative;
transform-style: preserve-3d;
transition-duration: 0.6s;
transition-property: transform, box-shadow;
height: 100%;

@include mobile {
max-width: 100%;
width: 100%;
}

@include mobile {
max-width: 100%;
Expand All @@ -29,22 +32,12 @@
box-shadow: 0px 24px 48px 0px rgba(14, 14, 14, 0.18);
}

&--flip {
transform: rotateY(180deg);
}

&-front {
backface-visibility: hidden;
display: flex;
flex-direction: column;
justify-content: center;
padding: 20px 16px;
transform-style: preserve-3d;
transition: transform 0.6s;

&--flip {
transform: rotateY(180deg);
}
padding: 16px;

&__label {
font-size: 20px;
Expand All @@ -62,23 +55,32 @@
font-weight: 700;
padding: 1rem;

&--assets {
background-color: #661b20;
&-icons {
display: flex;
gap: 6px;
}

&--leverage {
background-color: #ffa912;
&--red-darker {
background: #661b20;
}

&--spreads-from {
background-color: #4a3871;
&--red-dark {
background: #b33037;
}
&--red-light {
background: #ff444f;
}
&--yellow-dark {
background: #b3760d;
}
&--yellow-light {
background: #ffa912;
}
&--violet-dark {
background: #4a3871;
}
&--brown-dark {
background: #664407;
}
}
}

&-back {
backface-visibility: hidden;
transform: rotateY(180deg);
position: absolute;
}
}
135 changes: 86 additions & 49 deletions packages/wallets/src/components/JurisdictionModal/JurisdictionCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import React, { useState } from 'react';
import React, { useMemo } from 'react';
import classNames from 'classnames';
import DocumentsIcon from '../../public/images/ic-documents.svg';
import IdCardIcon from '../../public/images/ic-id-card.svg';
import NotApplicableIcon from '../../public/images/ic-not-applicable.svg';
import SelfieIcon from '../../public/images/ic-selfie.svg';
import { useModal } from '../ModalProvider';
import { getJurisdictionContents } from './jurisdiction-contents/jurisdiction-contents';
import { TJurisdictionCardItems } from './jurisdiction-contents/props.types';
import JurisdictionCardRow from './JurisdictionCardRow';
import JurisdictionCardTag from './JurisdictionCardTag';
import './JurisdictionCard.scss';
Expand All @@ -11,65 +18,95 @@ type TJurisdictionCardProps = {
tag?: string;
};

const JurisdictionCard: React.FC<TJurisdictionCardProps> = ({ isSelected, jurisdiction, onSelect, tag }) => {
const [shouldFlip, setShouldFlip] = useState(false);
const verificationIconsMapper: Record<string, JSX.Element> = {
documentNumber: <IdCardIcon />,
nameAndAddress: <DocumentsIcon />,
notApplicable: <NotApplicableIcon />,
selfie: <SelfieIcon />,
};

const JurisdictionCard: React.FC<TJurisdictionCardProps> = ({ isSelected, jurisdiction, onSelect }) => {
const { modalState } = useModal();

const { contents, header, isOverHeaderAvailable, overHeader, verificationDocs } = useMemo<TJurisdictionCardItems>(
() => getJurisdictionContents()[jurisdiction],
[jurisdiction]
);
const marketType = modalState?.marketType || 'all';
const rows = contents[marketType] || [];

const parseClickableDescription = (clickableDescription: { text: string; type: 'link' | 'text' }[]) => {
return clickableDescription.map(description => {
if (description.type === 'link') {
return (
<a className='wallets-jurisdiction-card__link' key={description?.text}>
{description.text}{' '}
</a>
);
}
return description.text;
});
};

return (
<div
className={classNames('wallets-jurisdiction-card', {
'wallets-jurisdiction-card--flip': shouldFlip,
'wallets-jurisdiction-card--selected': isSelected,
})}
onClick={() => onSelect(jurisdiction)}
onClick={() => {
onSelect(jurisdiction);
}}
>
{!shouldFlip && tag && <JurisdictionCardTag tag={tag} />}
{isOverHeaderAvailable && <JurisdictionCardTag tag={overHeader || ''} />}
<React.Fragment>
<div className='wallets-jurisdiction-card-front'>
<div className='wallets-jurisdiction-card-front__label'>{jurisdiction}</div>
<JurisdictionCardRow
description='Synthetics,baskets,and derived FX'
renderTag={() => (
<div className='wallets-jurisdiction-card-front__tag wallets-jurisdiction-card-front__tag--assets'>
40+
</div>
)}
title='Assets'
/>
<JurisdictionCardRow
description={<div className='wallets-jurisdiction-card__link'>Dynamic leverage</div>}
renderTag={() => (
<div className='wallets-jurisdiction-card-front__tag wallets-jurisdiction-card-front__tag--leverage'>
1:1000
</div>
)}
title='Leverage'
/>
<div className='wallets-jurisdiction-card-front__label'>{header}</div>
{rows.map(row => {
return (
<JurisdictionCardRow
description={
row.clickableDescription
? parseClickableDescription(row.clickableDescription)
: row.description
}
key={`wallets-jurisdiction-card--${row?.title}`}
renderTag={() => {
if (!row?.titleIndicators) return;

if (
row.titleIndicators?.type === 'displayIcons' &&
verificationDocs &&
marketType &&
marketType !== 'all'
) {
return (
<div className='wallets-jurisdiction-card-front__tag-icons'>
{!(marketType in verificationDocs)
? verificationIconsMapper.notApplicable
: verificationDocs[marketType]?.map(doc => {
return verificationIconsMapper[doc];
})}
</div>
);
}

<JurisdictionCardRow
renderTag={() => (
<div className='wallets-jurisdiction-card-front__tag wallets-jurisdiction-card-front__tag--spreads-from'>
0.6 pips
</div>
)}
title='Spreads from'
/>
<JurisdictionCardRow
description={
<div>
<a className='wallets-jurisdiction-card__link' onClick={() => setShouldFlip(true)}>
Learn more
</a>{' '}
about required verifications.
</div>
}
title='Verifications'
/>
<JurisdictionCardRow
description='British Virgin Islands Financial Services Commission (Licence no. SIBA/L/18/1114)'
title='Regulator'
/>
if (row?.titleIndicators?.displayText) {
return (
<div
className={`wallets-jurisdiction-card-front__tag wallets-jurisdiction-card-front__tag--${
row.titleIndicators?.displayTextSkinColor || ''
}`}
>
{row.titleIndicators?.displayText}
</div>
);
}
}}
title={row.title}
/>
);
})}
</div>
<div className='wallets-jurisdiction-card-back'>IM BACK</div>
</React.Fragment>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
border-radius: 16px;
display: flex;
flex-direction: column;
gap: 30px;
justify-content: center;
margin: auto 4rem;
height: 75vh;
Expand Down Expand Up @@ -39,6 +38,7 @@
display: flex;
gap: 16px;
justify-content: center;
width: 100%;

@include mobile {
flex-direction: column;
Expand All @@ -54,6 +54,7 @@
gap: 12px;
justify-content: center;
text-align: center;
margin-top: 20px;

&-checkbox {
align-items: center;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState } from 'react';
import React, { useMemo, useState } from 'react';
import classNames from 'classnames';
import { useAvailableMT5Accounts } from '@deriv/api';
import { MT5PasswordModal } from '../../features/cfd/modals';
import { ModalStepWrapper } from '../Base';
import { useModal } from '../ModalProvider';
Expand All @@ -9,8 +10,18 @@ import './JurisdictionModal.scss';
const JurisdictionModal = () => {
const [selectedJurisdiction, setSelectedJurisdiction] = useState('');
const { modalState, show } = useModal();
const { data, isLoading } = useAvailableMT5Accounts();

const jurisdictions = ['St. Vincent & Grenadines', 'British Virgin Islands', 'Vanuatu'];
const marketType = modalState?.marketType || 'all';

const jurisdictions = useMemo(
() =>
data?.filter(account => account.market_type === modalState?.marketType).map(account => account.shortcode) ||
[],
[isLoading]
);

if (isLoading) return <h1>Loading...</h1>;

return (
<ModalStepWrapper
Expand All @@ -20,7 +31,7 @@ const JurisdictionModal = () => {
className={classNames('wallets-jurisdiction-modal__button', {
'wallets-jurisdiction-modal__button--disabled': !selectedJurisdiction,
})}
onClick={() => show(<MT5PasswordModal marketType={modalState?.marketType || 'all'} />)}
onClick={() => show(<MT5PasswordModal marketType={marketType} />)}
>
Next
</button>
Expand All @@ -33,10 +44,14 @@ const JurisdictionModal = () => {
{jurisdictions.map(jurisdiction => (
<JurisdictionCard
isSelected={selectedJurisdiction === jurisdiction}
jurisdiction={jurisdiction}
jurisdiction={jurisdiction || 'bvi'}
key={jurisdiction}
onSelect={clickedJurisdiction => {
setSelectedJurisdiction(clickedJurisdiction);
if (clickedJurisdiction === selectedJurisdiction) {
setSelectedJurisdiction('');
} else {
setSelectedJurisdiction(clickedJurisdiction);
}
}}
tag='Straight-through processing'
/>
Expand Down
Loading

1 comment on commit 4263a92

@vercel
Copy link

@vercel vercel bot commented on 4263a92 Oct 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

deriv-app – ./

deriv-app.vercel.app
binary.sx
deriv-app-git-master.binary.sx
deriv-app.binary.sx

Please sign in to comment.