mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
Onboarding V2 Secure Your Wallet view (#12208)
* secure-your-wallet onboarding view
This commit is contained in:
parent
fc41321470
commit
614228cba7
@ -1042,6 +1042,9 @@
|
||||
"getStarted": {
|
||||
"message": "Get Started"
|
||||
},
|
||||
"goBack": {
|
||||
"message": "Go Back"
|
||||
},
|
||||
"goerli": {
|
||||
"message": "Goerli Test Network"
|
||||
},
|
||||
@ -1900,6 +1903,12 @@
|
||||
"seedPhraseEnterMissingWords": {
|
||||
"message": "Confirm Secret Recovery Phrase"
|
||||
},
|
||||
"seedPhraseIntroNotRecommendedButtonCopy": {
|
||||
"message": "Remind me later (not recommended)"
|
||||
},
|
||||
"seedPhraseIntroRecommendedButtonCopy": {
|
||||
"message": "Secure my wallet (recommended)"
|
||||
},
|
||||
"seedPhraseIntroSidebarBulletFour": {
|
||||
"message": "Write down and store in multiple secret places."
|
||||
},
|
||||
@ -1913,13 +1922,13 @@
|
||||
"message": "Store in a bank vault."
|
||||
},
|
||||
"seedPhraseIntroSidebarCopyOne": {
|
||||
"message": "Your Secret Recovery Phrase is the “master key” to your wallet and funds."
|
||||
"message": "Your Secret Recovery Phrase is a 12-word phrase that is the “master key” to your wallet and your funds"
|
||||
},
|
||||
"seedPhraseIntroSidebarCopyThree": {
|
||||
"message": "If someone asks for your Secret Recovery Phrase, they are most likely trying to scam you."
|
||||
"message": "If someone asks for your recovery phrase they are likely trying to scam you and steal your wallet funds"
|
||||
},
|
||||
"seedPhraseIntroSidebarCopyTwo": {
|
||||
"message": "Never, ever share your Secret Recovery Phrase, even with MetaMask!"
|
||||
"message": "Never, ever share your Secret Recovery Phrase, not even with MetaMask!"
|
||||
},
|
||||
"seedPhraseIntroSidebarTitleOne": {
|
||||
"message": "What is a Secret Recovery Phrase?"
|
||||
@ -2071,6 +2080,15 @@
|
||||
"signed": {
|
||||
"message": "Signed"
|
||||
},
|
||||
"skip": {
|
||||
"message": "Skip"
|
||||
},
|
||||
"skipAccountSecurity": {
|
||||
"message": "Skip Account Security?"
|
||||
},
|
||||
"skipAccountSecurityDetails": {
|
||||
"message": "I understand that until I back up my Secret Recovery Phrase, I may lose my accounts and all of their assets."
|
||||
},
|
||||
"slow": {
|
||||
"message": "Slow"
|
||||
},
|
||||
|
BIN
app/images/warning-icon.png
Normal file
BIN
app/images/warning-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
@ -14,7 +14,7 @@ const stages = {
|
||||
export default function StepProgressBar({ stage = 'PASSWORD_CREATE' }) {
|
||||
const t = useI18nContext();
|
||||
return (
|
||||
<Box margin={4}>
|
||||
<Box>
|
||||
<ul className="progressbar">
|
||||
<li
|
||||
className={classnames({
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
JUSTIFY_CONTENT,
|
||||
SIZES,
|
||||
TEXT_ALIGN,
|
||||
FLEX_DIRECTION,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
|
||||
const ValidSize = PropTypes.oneOf([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
|
||||
@ -72,6 +73,7 @@ export default function Box({
|
||||
alignItems,
|
||||
justifyContent,
|
||||
textAlign,
|
||||
flexDirection = FLEX_DIRECTION.ROW,
|
||||
display,
|
||||
width,
|
||||
height,
|
||||
@ -115,6 +117,7 @@ export default function Box({
|
||||
!display && (Boolean(justifyContent) || Boolean(alignItems)),
|
||||
[`box--justify-content-${justifyContent}`]: Boolean(justifyContent),
|
||||
[`box--align-items-${alignItems}`]: Boolean(alignItems),
|
||||
[`box--flex-direction-${flexDirection}`]: Boolean(flexDirection),
|
||||
// text align
|
||||
[`box--text-align-${textAlign}`]: Boolean(textAlign),
|
||||
// display
|
||||
@ -132,6 +135,7 @@ export default function Box({
|
||||
|
||||
Box.propTypes = {
|
||||
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
|
||||
flexDirection: PropTypes.oneOf(Object.values(FLEX_DIRECTION)),
|
||||
margin: MultipleSizes,
|
||||
marginTop: ValidSize,
|
||||
marginBottom: ValidSize,
|
||||
|
@ -84,6 +84,12 @@ $attributes: padding, margin;
|
||||
}
|
||||
}
|
||||
|
||||
@each $direction in design-system.$flex-direction {
|
||||
&--flex-direction-#{$direction} {
|
||||
flex-direction: $direction;
|
||||
}
|
||||
}
|
||||
|
||||
// Width and Height
|
||||
&--width-full {
|
||||
width: 100%;
|
||||
|
@ -10,7 +10,15 @@ const CHECKBOX_STATE = {
|
||||
|
||||
export const { CHECKED, INDETERMINATE, UNCHECKED } = CHECKBOX_STATE;
|
||||
|
||||
const CheckBox = ({ className, disabled, id, onClick, checked, title }) => {
|
||||
const CheckBox = ({
|
||||
className,
|
||||
disabled,
|
||||
id,
|
||||
onClick,
|
||||
checked,
|
||||
title,
|
||||
dataTestId,
|
||||
}) => {
|
||||
if (typeof checked === 'boolean') {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
checked = checked ? CHECKBOX_STATE.CHECKED : CHECKBOX_STATE.UNCHECKED;
|
||||
@ -43,6 +51,7 @@ const CheckBox = ({ className, disabled, id, onClick, checked, title }) => {
|
||||
readOnly
|
||||
ref={ref}
|
||||
title={title}
|
||||
data-testid={dataTestId}
|
||||
type="checkbox"
|
||||
/>
|
||||
);
|
||||
@ -56,6 +65,7 @@ CheckBox.propTypes = {
|
||||
checked: PropTypes.oneOf([...Object.keys(CHECKBOX_STATE), true, false])
|
||||
.isRequired,
|
||||
title: PropTypes.string,
|
||||
dataTestId: PropTypes.string,
|
||||
};
|
||||
|
||||
CheckBox.defaultProps = {
|
||||
|
@ -20,6 +20,7 @@ const Popover = ({
|
||||
centerTitle,
|
||||
}) => {
|
||||
const t = useI18nContext();
|
||||
const showHeader = title || onBack || subtitle || onClose;
|
||||
return (
|
||||
<div className="popover-container">
|
||||
{CustomBackground ? (
|
||||
@ -32,36 +33,38 @@ const Popover = ({
|
||||
ref={popoverRef}
|
||||
>
|
||||
{showArrow ? <div className="popover-arrow" /> : null}
|
||||
<header className="popover-header">
|
||||
<div
|
||||
className={classnames(
|
||||
'popover-header__title',
|
||||
centerTitle ? 'center' : '',
|
||||
)}
|
||||
>
|
||||
<h2 title={title}>
|
||||
{onBack ? (
|
||||
{showHeader && (
|
||||
<header className="popover-header">
|
||||
<div
|
||||
className={classnames(
|
||||
'popover-header__title',
|
||||
centerTitle ? 'center' : '',
|
||||
)}
|
||||
>
|
||||
<h2 title={title}>
|
||||
{onBack ? (
|
||||
<button
|
||||
className="fas fa-chevron-left popover-header__button"
|
||||
title={t('back')}
|
||||
onClick={onBack}
|
||||
/>
|
||||
) : null}
|
||||
{title}
|
||||
</h2>
|
||||
{onClose ? (
|
||||
<button
|
||||
className="fas fa-chevron-left popover-header__button"
|
||||
title={t('back')}
|
||||
onClick={onBack}
|
||||
className="fas fa-times popover-header__button"
|
||||
title={t('close')}
|
||||
data-testid="popover-close"
|
||||
onClick={onClose}
|
||||
/>
|
||||
) : null}
|
||||
{title}
|
||||
</h2>
|
||||
{onClose ? (
|
||||
<button
|
||||
className="fas fa-times popover-header__button"
|
||||
title={t('close')}
|
||||
data-testid="popover-close"
|
||||
onClick={onClose}
|
||||
/>
|
||||
</div>
|
||||
{subtitle ? (
|
||||
<p className="popover-header__subtitle">{subtitle}</p>
|
||||
) : null}
|
||||
</div>
|
||||
{subtitle ? (
|
||||
<p className="popover-header__subtitle">{subtitle}</p>
|
||||
) : null}
|
||||
</header>
|
||||
</header>
|
||||
)}
|
||||
{children ? (
|
||||
<div className={classnames('popover-content', contentClassName)}>
|
||||
{children}
|
||||
@ -78,7 +81,7 @@ const Popover = ({
|
||||
};
|
||||
|
||||
Popover.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
title: PropTypes.string,
|
||||
subtitle: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
footer: PropTypes.node,
|
||||
|
@ -13,6 +13,12 @@ $justify-content:
|
||||
space-between,
|
||||
space-evenly;
|
||||
|
||||
$flex-direction:
|
||||
row,
|
||||
row-reverse,
|
||||
column,
|
||||
column-reverse;
|
||||
|
||||
$fractions: (
|
||||
1\/2: 50%,
|
||||
1\/3: 33.333333%,
|
||||
|
@ -88,6 +88,13 @@ export const JUSTIFY_CONTENT = {
|
||||
SPACE_EVENLY: 'space-evenly',
|
||||
};
|
||||
|
||||
export const FLEX_DIRECTION = {
|
||||
ROW: 'row',
|
||||
ROW_REVERSE: 'row-reverse',
|
||||
COLUMN: 'column',
|
||||
COLUMN_REVERSE: 'column-reverse',
|
||||
};
|
||||
|
||||
export const DISPLAY = {
|
||||
BLOCK: 'block',
|
||||
FLEX: 'flex',
|
||||
|
@ -1,6 +1,7 @@
|
||||
@import 'recovery-phrase/index';
|
||||
@import 'new-account/index';
|
||||
@import 'onboarding-app-header/index';
|
||||
@import 'secure-your-wallet/index';
|
||||
|
||||
.onboarding-flow {
|
||||
width: 100%;
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
ONBOARDING_CONFIRM_SRP_ROUTE,
|
||||
ONBOARDING_UNLOCK_ROUTE,
|
||||
DEFAULT_ROUTE,
|
||||
ONBOARDING_SECURE_YOUR_WALLET_ROUTE,
|
||||
} from '../../helpers/constants/routes';
|
||||
import {
|
||||
getCompletedOnboarding,
|
||||
@ -23,6 +24,7 @@ import { getFirstTimeFlowTypeRoute } from '../../selectors';
|
||||
import OnboardingFlowSwitch from './onboarding-flow-switch/onboarding-flow-switch';
|
||||
import NewAccount from './new-account/new-account';
|
||||
import ReviewRecoveryPhrase from './recovery-phrase/review-recovery-phrase';
|
||||
import SecureYourWallet from './secure-your-wallet/secure-your-wallet';
|
||||
import ConfirmRecoveryPhrase from './recovery-phrase/confirm-recovery-phrase';
|
||||
|
||||
export default function OnboardingFlow() {
|
||||
@ -39,7 +41,7 @@ export default function OnboardingFlow() {
|
||||
// For ONBOARDING_V2 dev purposes,
|
||||
// Remove when ONBOARDING_V2 dev complete
|
||||
if (process.env.ONBOARDING_V2) {
|
||||
history.push(ONBOARDING_REVIEW_SRP_ROUTE);
|
||||
history.push(ONBOARDING_SECURE_YOUR_WALLET_ROUTE);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -87,6 +89,11 @@ export default function OnboardingFlow() {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path={ONBOARDING_SECURE_YOUR_WALLET_ROUTE}
|
||||
component={SecureYourWallet}
|
||||
/>
|
||||
<Route
|
||||
path={ONBOARDING_REVIEW_SRP_ROUTE}
|
||||
render={() => <ReviewRecoveryPhrase seedPhrase={seedPhrase} />}
|
||||
|
47
ui/pages/onboarding-flow/secure-your-wallet/index.scss
Normal file
47
ui/pages/onboarding-flow/secure-your-wallet/index.scss
Normal file
@ -0,0 +1,47 @@
|
||||
.secure-your-wallet {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
max-width: 1000px;
|
||||
max-height: 1300px;
|
||||
|
||||
&__details {
|
||||
max-width: 550px;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
button {
|
||||
margin: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&__list {
|
||||
list-style: disc inside;
|
||||
|
||||
li {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
&__highlighted {
|
||||
background-color: $primary-2;
|
||||
padding: 12px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.skip-srp-backup-popover {
|
||||
width: 365px;
|
||||
|
||||
&__checkbox {
|
||||
margin: 8px 12px 0 0;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
button {
|
||||
width: 140px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,167 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useSelector } from 'react-redux';
|
||||
import Box from '../../../components/ui/box';
|
||||
import Button from '../../../components/ui/button';
|
||||
import Typography from '../../../components/ui/typography';
|
||||
import {
|
||||
TEXT_ALIGN,
|
||||
TYPOGRAPHY,
|
||||
JUSTIFY_CONTENT,
|
||||
FONT_WEIGHT,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import ProgressBar from '../../../components/app/step-progress-bar';
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
import { ONBOARDING_REVIEW_SRP_ROUTE } from '../../../helpers/constants/routes';
|
||||
import { getCurrentLocale } from '../../../ducks/metamask/metamask';
|
||||
import SkipSRPBackup from './skip-srp-backup-popover';
|
||||
|
||||
export default function SecureYourWallet() {
|
||||
const history = useHistory();
|
||||
const t = useI18nContext();
|
||||
const currentLocale = useSelector(getCurrentLocale);
|
||||
const [showSkipSRPBackupPopover, setShowSkipSRPBackupPopover] = useState(
|
||||
false,
|
||||
);
|
||||
|
||||
const handleClickRecommended = () => {
|
||||
history.push(ONBOARDING_REVIEW_SRP_ROUTE);
|
||||
};
|
||||
|
||||
const handleClickNotRecommended = () => {
|
||||
setShowSkipSRPBackupPopover(true);
|
||||
};
|
||||
|
||||
const subtitles = {
|
||||
en: 'English',
|
||||
es: 'Spanish',
|
||||
hi: 'Hindi',
|
||||
id: 'Indonesian',
|
||||
ja: 'Japanese',
|
||||
ko: 'Korean',
|
||||
pt: 'Portuguese',
|
||||
ru: 'Russian',
|
||||
tl: 'Tagalog',
|
||||
vi: 'Vietnamese',
|
||||
};
|
||||
|
||||
const defaultLang = subtitles[currentLocale] ? currentLocale : 'en';
|
||||
return (
|
||||
<div className="secure-your-wallet">
|
||||
{showSkipSRPBackupPopover && (
|
||||
<SkipSRPBackup handleClose={() => setShowSkipSRPBackupPopover(false)} />
|
||||
)}
|
||||
<ProgressBar stage="SEED_PHRASE_VIDEO" />
|
||||
<Box
|
||||
justifyContent={JUSTIFY_CONTENT.CENTER}
|
||||
textAlign={TEXT_ALIGN.CENTER}
|
||||
marginBottom={4}
|
||||
>
|
||||
<Typography variant={TYPOGRAPHY.H2} fontWeight={FONT_WEIGHT.BOLD}>
|
||||
{t('seedPhraseIntroTitle')}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
justifyContent={JUSTIFY_CONTENT.CENTER}
|
||||
textAlign={TEXT_ALIGN.CENTER}
|
||||
marginBottom={6}
|
||||
>
|
||||
<Typography
|
||||
variant={TYPOGRAPHY.H4}
|
||||
className="secure-your-wallet__details"
|
||||
>
|
||||
{t('seedPhraseIntroTitleCopy')}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box>
|
||||
<video controls style={{ borderRadius: '10px' }}>
|
||||
<source
|
||||
type="video/webm"
|
||||
src="./images/videos/recovery-onboarding/video.webm"
|
||||
/>
|
||||
{Object.keys(subtitles).map((key) => {
|
||||
return (
|
||||
<track
|
||||
default={Boolean(key === defaultLang)}
|
||||
srcLang={key}
|
||||
label={subtitles[key]}
|
||||
key={`${key}-subtitles`}
|
||||
kind="subtitles"
|
||||
src={`./images/videos/recovery-onboarding/subtitles/${key}.vtt`}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</video>
|
||||
</Box>
|
||||
<Box
|
||||
margin={8}
|
||||
width="10/12"
|
||||
justifyContent={JUSTIFY_CONTENT.SPACE_BETWEEN}
|
||||
className="secure-your-wallet__actions"
|
||||
>
|
||||
<Button
|
||||
type="secondary"
|
||||
rounded
|
||||
large
|
||||
onClick={handleClickNotRecommended}
|
||||
>
|
||||
{t('seedPhraseIntroNotRecommendedButtonCopy')}
|
||||
</Button>
|
||||
<Button type="primary" rounded large onClick={handleClickRecommended}>
|
||||
{t('seedPhraseIntroRecommendedButtonCopy')}
|
||||
</Button>
|
||||
</Box>
|
||||
<Box marginBottom={4} textAlign={TEXT_ALIGN.CENTER}>
|
||||
<Typography
|
||||
tag="span"
|
||||
variant={TYPOGRAPHY.H4}
|
||||
fontWeight={FONT_WEIGHT.BOLD}
|
||||
boxProps={{ display: 'block' }}
|
||||
>
|
||||
{t('seedPhraseIntroSidebarTitleOne')}
|
||||
</Typography>
|
||||
<Typography tag="span" variant={TYPOGRAPHY.H4}>
|
||||
{t('seedPhraseIntroSidebarCopyOne')}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box marginBottom={4} textAlign={TEXT_ALIGN.CENTER}>
|
||||
<Typography
|
||||
tag="span"
|
||||
variant={TYPOGRAPHY.H4}
|
||||
fontWeight={FONT_WEIGHT.BOLD}
|
||||
boxProps={{ display: 'block' }}
|
||||
>
|
||||
{t('seedPhraseIntroSidebarTitleTwo')}
|
||||
</Typography>
|
||||
<ul className="secure-your-wallet__list">
|
||||
<li>{t('seedPhraseIntroSidebarBulletOne')}</li>
|
||||
<li>{t('seedPhraseIntroSidebarBulletTwo')}</li>
|
||||
<li>{t('seedPhraseIntroSidebarBulletThree')}</li>
|
||||
<li>{t('seedPhraseIntroSidebarBulletFour')}</li>
|
||||
</ul>
|
||||
</Box>
|
||||
<Box marginBottom={6} textAlign={TEXT_ALIGN.CENTER}>
|
||||
<Typography
|
||||
tag="span"
|
||||
variant={TYPOGRAPHY.H4}
|
||||
fontWeight={FONT_WEIGHT.BOLD}
|
||||
boxProps={{ display: 'block' }}
|
||||
>
|
||||
{t('seedPhraseIntroSidebarTitleThree')}
|
||||
</Typography>
|
||||
<Typography tag="span" variant={TYPOGRAPHY.H4}>
|
||||
{t('seedPhraseIntroSidebarCopyTwo')}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
className="secure-your-wallet__highlighted"
|
||||
marginBottom={2}
|
||||
textAlign={TEXT_ALIGN.CENTER}
|
||||
>
|
||||
<Typography tag="span" variant={TYPOGRAPHY.H4}>
|
||||
{t('seedPhraseIntroSidebarCopyThree')}
|
||||
</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
import SecureYourWallet from './secure-your-wallet';
|
||||
|
||||
export default {
|
||||
title: 'Onboarding - Secure Your Wallet',
|
||||
id: __filename,
|
||||
};
|
||||
|
||||
export const Base = () => {
|
||||
return (
|
||||
<div style={{ maxHeight: '2000px' }}>
|
||||
<SecureYourWallet />
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1,59 @@
|
||||
import React from 'react';
|
||||
import { fireEvent } from '@testing-library/react';
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
import reactRouterDom from 'react-router-dom';
|
||||
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||
import { ONBOARDING_COMPLETION_ROUTE } from '../../../helpers/constants/routes';
|
||||
import SecureYourWallet from './secure-your-wallet';
|
||||
|
||||
describe('Secure Your Wallet Onboarding View', () => {
|
||||
const useHistoryOriginal = reactRouterDom.useHistory;
|
||||
const pushMock = jest.fn();
|
||||
beforeAll(() => {
|
||||
jest
|
||||
.spyOn(reactRouterDom, 'useHistory')
|
||||
.mockImplementation()
|
||||
.mockReturnValue({ push: pushMock });
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
reactRouterDom.useHistory = useHistoryOriginal;
|
||||
});
|
||||
|
||||
const mockStore = {
|
||||
metamask: {
|
||||
provider: {
|
||||
type: 'test',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const store = configureMockStore()(mockStore);
|
||||
it('should show a popover asking the user if they want to skip account security if they click "Remind me later"', () => {
|
||||
const { queryAllByText, getByText } = renderWithProvider(
|
||||
<SecureYourWallet />,
|
||||
store,
|
||||
);
|
||||
const remindMeLaterButton = getByText('Remind me later (not recommended)');
|
||||
expect(queryAllByText('Skip Account Security?')).toHaveLength(0);
|
||||
fireEvent.click(remindMeLaterButton);
|
||||
expect(queryAllByText('Skip Account Security?')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('should not be able to click "skip" until "Skip Account Security" terms are agreed to', () => {
|
||||
const { getByText, getByTestId } = renderWithProvider(
|
||||
<SecureYourWallet />,
|
||||
store,
|
||||
);
|
||||
const remindMeLaterButton = getByText('Remind me later (not recommended)');
|
||||
fireEvent.click(remindMeLaterButton);
|
||||
const skipButton = getByText('Skip');
|
||||
fireEvent.click(skipButton);
|
||||
expect(pushMock).toHaveBeenCalledTimes(0);
|
||||
const checkbox = getByTestId('skip-srp-backup-popover-checkbox');
|
||||
fireEvent.click(checkbox);
|
||||
fireEvent.click(skipButton);
|
||||
expect(pushMock).toHaveBeenCalledTimes(1);
|
||||
expect(pushMock).toHaveBeenCalledWith(ONBOARDING_COMPLETION_ROUTE);
|
||||
});
|
||||
});
|
@ -0,0 +1,79 @@
|
||||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
import Button from '../../../components/ui/button';
|
||||
import Popover from '../../../components/ui/popover';
|
||||
import Box from '../../../components/ui/box';
|
||||
import Typography from '../../../components/ui/typography';
|
||||
import {
|
||||
ALIGN_ITEMS,
|
||||
FLEX_DIRECTION,
|
||||
FONT_WEIGHT,
|
||||
JUSTIFY_CONTENT,
|
||||
TYPOGRAPHY,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import Checkbox from '../../../components/ui/check-box';
|
||||
import { ONBOARDING_COMPLETION_ROUTE } from '../../../helpers/constants/routes';
|
||||
|
||||
export default function SkipSRPBackup({ handleClose }) {
|
||||
const [checked, setChecked] = useState(false);
|
||||
const t = useI18nContext();
|
||||
const history = useHistory();
|
||||
return (
|
||||
<Popover
|
||||
className="skip-srp-backup-popover"
|
||||
footer={
|
||||
<Box
|
||||
className="skip-srp-backup-popover__footer"
|
||||
justifyContent={JUSTIFY_CONTENT.CENTER}
|
||||
alignItems={ALIGN_ITEMS.CENTER}
|
||||
>
|
||||
<Button onClick={handleClose} type="secondary" rounded>
|
||||
{t('goBack')}
|
||||
</Button>
|
||||
<Button
|
||||
disabled={!checked}
|
||||
type="primary"
|
||||
rounded
|
||||
onClick={() => history.push(ONBOARDING_COMPLETION_ROUTE)}
|
||||
>
|
||||
{t('skip')}
|
||||
</Button>
|
||||
</Box>
|
||||
}
|
||||
>
|
||||
<Box
|
||||
flexDirection={FLEX_DIRECTION.COLUMN}
|
||||
alignItems={ALIGN_ITEMS.CENTER}
|
||||
justifyContent={JUSTIFY_CONTENT.CENTER}
|
||||
margin={4}
|
||||
>
|
||||
<img src="./images/warning-icon.png" />
|
||||
<Typography variant={TYPOGRAPHY.h3} fontWeight={FONT_WEIGHT.BOLD}>
|
||||
{t('skipAccountSecurity')}
|
||||
</Typography>
|
||||
<Box justifyContent={JUSTIFY_CONTENT.CENTER} margin={3}>
|
||||
<Checkbox
|
||||
className="skip-srp-backup-popover__checkbox"
|
||||
onClick={() => {
|
||||
setChecked(!checked);
|
||||
}}
|
||||
checked={checked}
|
||||
dataTestId="skip-srp-backup-popover-checkbox"
|
||||
/>
|
||||
<Typography
|
||||
className="skip-srp-backup-popover__details"
|
||||
variant={TYPOGRAPHY.h7}
|
||||
>
|
||||
{t('skipAccountSecurityDetails')}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
||||
SkipSRPBackup.propTypes = {
|
||||
handleClose: PropTypes.func,
|
||||
};
|
@ -40,7 +40,6 @@ import {
|
||||
CONFIRM_TRANSACTION_ROUTE,
|
||||
CONNECT_ROUTE,
|
||||
DEFAULT_ROUTE,
|
||||
INITIALIZE_ROUTE,
|
||||
INITIALIZE_UNLOCK_ROUTE,
|
||||
LOCK_ROUTE,
|
||||
MOBILE_SYNC_ROUTE,
|
||||
@ -54,6 +53,7 @@ import {
|
||||
BUILD_QUOTE_ROUTE,
|
||||
CONFIRMATION_V_NEXT_ROUTE,
|
||||
CONFIRM_IMPORT_TOKEN_ROUTE,
|
||||
INITIALIZE_ROUTE,
|
||||
ONBOARDING_ROUTE,
|
||||
} from '../../helpers/constants/routes';
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user