mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +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": {
|
"getStarted": {
|
||||||
"message": "Get Started"
|
"message": "Get Started"
|
||||||
},
|
},
|
||||||
|
"goBack": {
|
||||||
|
"message": "Go Back"
|
||||||
|
},
|
||||||
"goerli": {
|
"goerli": {
|
||||||
"message": "Goerli Test Network"
|
"message": "Goerli Test Network"
|
||||||
},
|
},
|
||||||
@ -1900,6 +1903,12 @@
|
|||||||
"seedPhraseEnterMissingWords": {
|
"seedPhraseEnterMissingWords": {
|
||||||
"message": "Confirm Secret Recovery Phrase"
|
"message": "Confirm Secret Recovery Phrase"
|
||||||
},
|
},
|
||||||
|
"seedPhraseIntroNotRecommendedButtonCopy": {
|
||||||
|
"message": "Remind me later (not recommended)"
|
||||||
|
},
|
||||||
|
"seedPhraseIntroRecommendedButtonCopy": {
|
||||||
|
"message": "Secure my wallet (recommended)"
|
||||||
|
},
|
||||||
"seedPhraseIntroSidebarBulletFour": {
|
"seedPhraseIntroSidebarBulletFour": {
|
||||||
"message": "Write down and store in multiple secret places."
|
"message": "Write down and store in multiple secret places."
|
||||||
},
|
},
|
||||||
@ -1913,13 +1922,13 @@
|
|||||||
"message": "Store in a bank vault."
|
"message": "Store in a bank vault."
|
||||||
},
|
},
|
||||||
"seedPhraseIntroSidebarCopyOne": {
|
"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": {
|
"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": {
|
"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": {
|
"seedPhraseIntroSidebarTitleOne": {
|
||||||
"message": "What is a Secret Recovery Phrase?"
|
"message": "What is a Secret Recovery Phrase?"
|
||||||
@ -2071,6 +2080,15 @@
|
|||||||
"signed": {
|
"signed": {
|
||||||
"message": "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": {
|
"slow": {
|
||||||
"message": "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' }) {
|
export default function StepProgressBar({ stage = 'PASSWORD_CREATE' }) {
|
||||||
const t = useI18nContext();
|
const t = useI18nContext();
|
||||||
return (
|
return (
|
||||||
<Box margin={4}>
|
<Box>
|
||||||
<ul className="progressbar">
|
<ul className="progressbar">
|
||||||
<li
|
<li
|
||||||
className={classnames({
|
className={classnames({
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
JUSTIFY_CONTENT,
|
JUSTIFY_CONTENT,
|
||||||
SIZES,
|
SIZES,
|
||||||
TEXT_ALIGN,
|
TEXT_ALIGN,
|
||||||
|
FLEX_DIRECTION,
|
||||||
} from '../../../helpers/constants/design-system';
|
} from '../../../helpers/constants/design-system';
|
||||||
|
|
||||||
const ValidSize = PropTypes.oneOf([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
|
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,
|
alignItems,
|
||||||
justifyContent,
|
justifyContent,
|
||||||
textAlign,
|
textAlign,
|
||||||
|
flexDirection = FLEX_DIRECTION.ROW,
|
||||||
display,
|
display,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
@ -115,6 +117,7 @@ export default function Box({
|
|||||||
!display && (Boolean(justifyContent) || Boolean(alignItems)),
|
!display && (Boolean(justifyContent) || Boolean(alignItems)),
|
||||||
[`box--justify-content-${justifyContent}`]: Boolean(justifyContent),
|
[`box--justify-content-${justifyContent}`]: Boolean(justifyContent),
|
||||||
[`box--align-items-${alignItems}`]: Boolean(alignItems),
|
[`box--align-items-${alignItems}`]: Boolean(alignItems),
|
||||||
|
[`box--flex-direction-${flexDirection}`]: Boolean(flexDirection),
|
||||||
// text align
|
// text align
|
||||||
[`box--text-align-${textAlign}`]: Boolean(textAlign),
|
[`box--text-align-${textAlign}`]: Boolean(textAlign),
|
||||||
// display
|
// display
|
||||||
@ -132,6 +135,7 @@ export default function Box({
|
|||||||
|
|
||||||
Box.propTypes = {
|
Box.propTypes = {
|
||||||
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
|
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
|
||||||
|
flexDirection: PropTypes.oneOf(Object.values(FLEX_DIRECTION)),
|
||||||
margin: MultipleSizes,
|
margin: MultipleSizes,
|
||||||
marginTop: ValidSize,
|
marginTop: ValidSize,
|
||||||
marginBottom: 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 and Height
|
||||||
&--width-full {
|
&--width-full {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -10,7 +10,15 @@ const CHECKBOX_STATE = {
|
|||||||
|
|
||||||
export const { CHECKED, INDETERMINATE, UNCHECKED } = 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') {
|
if (typeof checked === 'boolean') {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
checked = checked ? CHECKBOX_STATE.CHECKED : CHECKBOX_STATE.UNCHECKED;
|
checked = checked ? CHECKBOX_STATE.CHECKED : CHECKBOX_STATE.UNCHECKED;
|
||||||
@ -43,6 +51,7 @@ const CheckBox = ({ className, disabled, id, onClick, checked, title }) => {
|
|||||||
readOnly
|
readOnly
|
||||||
ref={ref}
|
ref={ref}
|
||||||
title={title}
|
title={title}
|
||||||
|
data-testid={dataTestId}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -56,6 +65,7 @@ CheckBox.propTypes = {
|
|||||||
checked: PropTypes.oneOf([...Object.keys(CHECKBOX_STATE), true, false])
|
checked: PropTypes.oneOf([...Object.keys(CHECKBOX_STATE), true, false])
|
||||||
.isRequired,
|
.isRequired,
|
||||||
title: PropTypes.string,
|
title: PropTypes.string,
|
||||||
|
dataTestId: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
CheckBox.defaultProps = {
|
CheckBox.defaultProps = {
|
||||||
|
@ -20,6 +20,7 @@ const Popover = ({
|
|||||||
centerTitle,
|
centerTitle,
|
||||||
}) => {
|
}) => {
|
||||||
const t = useI18nContext();
|
const t = useI18nContext();
|
||||||
|
const showHeader = title || onBack || subtitle || onClose;
|
||||||
return (
|
return (
|
||||||
<div className="popover-container">
|
<div className="popover-container">
|
||||||
{CustomBackground ? (
|
{CustomBackground ? (
|
||||||
@ -32,6 +33,7 @@ const Popover = ({
|
|||||||
ref={popoverRef}
|
ref={popoverRef}
|
||||||
>
|
>
|
||||||
{showArrow ? <div className="popover-arrow" /> : null}
|
{showArrow ? <div className="popover-arrow" /> : null}
|
||||||
|
{showHeader && (
|
||||||
<header className="popover-header">
|
<header className="popover-header">
|
||||||
<div
|
<div
|
||||||
className={classnames(
|
className={classnames(
|
||||||
@ -62,6 +64,7 @@ const Popover = ({
|
|||||||
<p className="popover-header__subtitle">{subtitle}</p>
|
<p className="popover-header__subtitle">{subtitle}</p>
|
||||||
) : null}
|
) : null}
|
||||||
</header>
|
</header>
|
||||||
|
)}
|
||||||
{children ? (
|
{children ? (
|
||||||
<div className={classnames('popover-content', contentClassName)}>
|
<div className={classnames('popover-content', contentClassName)}>
|
||||||
{children}
|
{children}
|
||||||
@ -78,7 +81,7 @@ const Popover = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
Popover.propTypes = {
|
Popover.propTypes = {
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string,
|
||||||
subtitle: PropTypes.string,
|
subtitle: PropTypes.string,
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
footer: PropTypes.node,
|
footer: PropTypes.node,
|
||||||
|
@ -13,6 +13,12 @@ $justify-content:
|
|||||||
space-between,
|
space-between,
|
||||||
space-evenly;
|
space-evenly;
|
||||||
|
|
||||||
|
$flex-direction:
|
||||||
|
row,
|
||||||
|
row-reverse,
|
||||||
|
column,
|
||||||
|
column-reverse;
|
||||||
|
|
||||||
$fractions: (
|
$fractions: (
|
||||||
1\/2: 50%,
|
1\/2: 50%,
|
||||||
1\/3: 33.333333%,
|
1\/3: 33.333333%,
|
||||||
|
@ -88,6 +88,13 @@ export const JUSTIFY_CONTENT = {
|
|||||||
SPACE_EVENLY: 'space-evenly',
|
SPACE_EVENLY: 'space-evenly',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const FLEX_DIRECTION = {
|
||||||
|
ROW: 'row',
|
||||||
|
ROW_REVERSE: 'row-reverse',
|
||||||
|
COLUMN: 'column',
|
||||||
|
COLUMN_REVERSE: 'column-reverse',
|
||||||
|
};
|
||||||
|
|
||||||
export const DISPLAY = {
|
export const DISPLAY = {
|
||||||
BLOCK: 'block',
|
BLOCK: 'block',
|
||||||
FLEX: 'flex',
|
FLEX: 'flex',
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
@import 'recovery-phrase/index';
|
@import 'recovery-phrase/index';
|
||||||
@import 'new-account/index';
|
@import 'new-account/index';
|
||||||
@import 'onboarding-app-header/index';
|
@import 'onboarding-app-header/index';
|
||||||
|
@import 'secure-your-wallet/index';
|
||||||
|
|
||||||
.onboarding-flow {
|
.onboarding-flow {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
ONBOARDING_CONFIRM_SRP_ROUTE,
|
ONBOARDING_CONFIRM_SRP_ROUTE,
|
||||||
ONBOARDING_UNLOCK_ROUTE,
|
ONBOARDING_UNLOCK_ROUTE,
|
||||||
DEFAULT_ROUTE,
|
DEFAULT_ROUTE,
|
||||||
|
ONBOARDING_SECURE_YOUR_WALLET_ROUTE,
|
||||||
} from '../../helpers/constants/routes';
|
} from '../../helpers/constants/routes';
|
||||||
import {
|
import {
|
||||||
getCompletedOnboarding,
|
getCompletedOnboarding,
|
||||||
@ -23,6 +24,7 @@ import { getFirstTimeFlowTypeRoute } from '../../selectors';
|
|||||||
import OnboardingFlowSwitch from './onboarding-flow-switch/onboarding-flow-switch';
|
import OnboardingFlowSwitch from './onboarding-flow-switch/onboarding-flow-switch';
|
||||||
import NewAccount from './new-account/new-account';
|
import NewAccount from './new-account/new-account';
|
||||||
import ReviewRecoveryPhrase from './recovery-phrase/review-recovery-phrase';
|
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';
|
import ConfirmRecoveryPhrase from './recovery-phrase/confirm-recovery-phrase';
|
||||||
|
|
||||||
export default function OnboardingFlow() {
|
export default function OnboardingFlow() {
|
||||||
@ -39,7 +41,7 @@ export default function OnboardingFlow() {
|
|||||||
// For ONBOARDING_V2 dev purposes,
|
// For ONBOARDING_V2 dev purposes,
|
||||||
// Remove when ONBOARDING_V2 dev complete
|
// Remove when ONBOARDING_V2 dev complete
|
||||||
if (process.env.ONBOARDING_V2) {
|
if (process.env.ONBOARDING_V2) {
|
||||||
history.push(ONBOARDING_REVIEW_SRP_ROUTE);
|
history.push(ONBOARDING_SECURE_YOUR_WALLET_ROUTE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +89,11 @@ export default function OnboardingFlow() {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path={ONBOARDING_SECURE_YOUR_WALLET_ROUTE}
|
||||||
|
component={SecureYourWallet}
|
||||||
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={ONBOARDING_REVIEW_SRP_ROUTE}
|
path={ONBOARDING_REVIEW_SRP_ROUTE}
|
||||||
render={() => <ReviewRecoveryPhrase seedPhrase={seedPhrase} />}
|
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,
|
CONFIRM_TRANSACTION_ROUTE,
|
||||||
CONNECT_ROUTE,
|
CONNECT_ROUTE,
|
||||||
DEFAULT_ROUTE,
|
DEFAULT_ROUTE,
|
||||||
INITIALIZE_ROUTE,
|
|
||||||
INITIALIZE_UNLOCK_ROUTE,
|
INITIALIZE_UNLOCK_ROUTE,
|
||||||
LOCK_ROUTE,
|
LOCK_ROUTE,
|
||||||
MOBILE_SYNC_ROUTE,
|
MOBILE_SYNC_ROUTE,
|
||||||
@ -54,6 +53,7 @@ import {
|
|||||||
BUILD_QUOTE_ROUTE,
|
BUILD_QUOTE_ROUTE,
|
||||||
CONFIRMATION_V_NEXT_ROUTE,
|
CONFIRMATION_V_NEXT_ROUTE,
|
||||||
CONFIRM_IMPORT_TOKEN_ROUTE,
|
CONFIRM_IMPORT_TOKEN_ROUTE,
|
||||||
|
INITIALIZE_ROUTE,
|
||||||
ONBOARDING_ROUTE,
|
ONBOARDING_ROUTE,
|
||||||
} from '../../helpers/constants/routes';
|
} from '../../helpers/constants/routes';
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user