Browse Source

adding device type distinguishing, reusing radio group for buttons, updating icons, wording

master
NastiaS 7 years ago
parent
commit
d7f57c9fd9
  1. 10
      src/components/Onboarding/index.js
  2. 154
      src/components/Onboarding/steps/GenuineCheck.js
  3. 98
      src/components/Onboarding/steps/SelectDevice.js
  4. 74
      src/components/Onboarding/steps/SelectPIN.js
  5. 47
      src/icons/onboarding/LedgerBlueError.js
  6. 47
      src/icons/onboarding/LedgerBlueSelectPIN.js
  7. 30
      src/icons/onboarding/LedgerNano.js
  8. 0
      src/icons/onboarding/LedgerNanoSelectPIN.js
  9. 206
      src/icons/onboarding/WriteSeed.js
  10. 7
      src/reducers/onboarding.js
  11. 29
      static/i18n/en/onboarding.yml

10
src/components/Onboarding/index.js

@ -10,7 +10,13 @@ import type { T } from 'types/common'
import type { OnboardingState } from 'reducers/onboarding'
import { saveSettings } from 'actions/settings'
import { nextStep, prevStep, jumpStep, setGenuineCheckFail } from 'reducers/onboarding'
import {
nextStep,
prevStep,
jumpStep,
setGenuineCheckFail,
isLedgerNano,
} from 'reducers/onboarding'
import { getCurrentDevice } from 'reducers/devices'
// TODO: re-write it without auto lock, fixed width of the password modal, not dynamic titles
@ -77,6 +83,7 @@ export type StepProps = {
savePassword: Function,
getDeviceInfo: Function,
setGenuineCheckFail: Function,
isLedgerNano: Function,
}
class Onboarding extends PureComponent<Props> {
@ -110,6 +117,7 @@ class Onboarding extends PureComponent<Props> {
t,
onboarding,
setGenuineCheckFail,
isLedgerNano,
prevStep,
nextStep,
jumpStep,

154
src/components/Onboarding/steps/GenuineCheck.js

@ -1,9 +1,9 @@
// @flow
import React, { PureComponent } from 'react'
import React, { PureComponent, Fragment } from 'react'
import { connect } from 'react-redux'
import styled from 'styled-components'
import { radii, colors } from 'styles/theme'
import { radii } from 'styles/theme'
import type { T } from 'types/common'
@ -11,8 +11,9 @@ import { setGenuineCheckFail } from 'reducers/onboarding'
import Box, { Card } from 'components/base/Box'
import Button from 'components/base/Button'
import IconCheck from 'icons/Check'
import RadioGroup from 'components/base/RadioGroup'
import IconLedgerNanoError from 'icons/onboarding/LedgerNanoError'
import IconLedgerBlueError from 'icons/onboarding/LedgerBlueError'
import { Title, Description, IconOptionRow } from '../helperComponents'
@ -24,18 +25,43 @@ const mapDispatchToProps = { setGenuineCheckFail }
type State = {
pinStepPass: boolean | null,
phraseStepPass: boolean | null,
cachedPinStepButton: string,
cachedPhraseStepButton: string,
}
class GenuineCheck extends PureComponent<StepProps, State> {
state = {
pinStepPass: null,
phraseStepPass: null,
cachedPinStepButton: '',
cachedPhraseStepButton: '',
}
handleStepPass = (step: string, pass: boolean | null) => {
this.setState({ [`${step}`]: pass })
getButtonLabel() {
const { t } = this.props
return [
{
label: t('common:yes'),
key: 'yes',
pass: true,
},
{
label: t('common:no'),
key: 'no',
pass: false,
},
]
}
handleButtonPass = (item: Object, step: string) => {
this.setState({ [`${step}`]: item.pass })
if (step === 'pinStepPass') {
this.setState({ cachedPinStepButton: item.key })
} else {
this.setState({ cachedPhraseStepButton: item.key })
}
if (typeof pass === 'boolean' && !pass) {
if (!item.pass) {
this.props.setGenuineCheckFail(true)
}
}
@ -51,12 +77,13 @@ class GenuineCheck extends PureComponent<StepProps, State> {
redoGenuineCheck={this.redoGenuineCheck}
contactSupport={this.contactSupport}
t={this.props.t}
isLedgerNano={this.props.onboarding.isLedgerNano}
/>
)
render() {
const { nextStep, prevStep, t, onboarding } = this.props
const { pinStepPass, phraseStepPass } = this.state
const { pinStepPass, phraseStepPass, cachedPinStepButton, cachedPhraseStepButton } = this.state
if (onboarding.isGenuineFail) {
return this.renderGenuineFail()
@ -66,7 +93,7 @@ class GenuineCheck extends PureComponent<StepProps, State> {
<Box sticky pt={150}>
<Box grow alignItems="center">
<Title>{t('onboarding:genuineCheck.title')}</Title>
<Description>{t('onboarding:genuineCheck.desc')}</Description>
<Description style={{ maxWidth: 536 }}>{t('onboarding:genuineCheck.desc')}</Description>
<Box mt={5}>
<CardWrapper>
<Box justify="center">
@ -76,22 +103,16 @@ class GenuineCheck extends PureComponent<StepProps, State> {
</Box>
<CardDescription>{t('onboarding:genuineCheck.steps.step2.desc')}</CardDescription>
</Box>
{!pinStepPass ? (
<ButtonCombo
handleStepPass={this.handleStepPass}
step="pinStepPass"
disabled={false}
t={this.props.t}
/>
) : (
<Box justify="center" color={colors.wallet} ml={8}>
<IconCheck size={16} />
</Box>
)}
<RadioGroup
style={{ margin: '0 30px' }}
items={this.getButtonLabel()}
activeKey={cachedPinStepButton}
onChange={item => this.handleButtonPass(item, 'pinStepPass')}
/>
</CardWrapper>
</Box>
<Box mt={5}>
<CardWrapper disabled={!pinStepPass}>
<CardWrapper isDisabled={!pinStepPass}>
<Box justify="center">
<Box horizontal>
<IconOptionRow>2.</IconOptionRow>
@ -99,22 +120,16 @@ class GenuineCheck extends PureComponent<StepProps, State> {
</Box>
<CardDescription>{t('onboarding:genuineCheck.steps.step2.desc')}</CardDescription>
</Box>
{!phraseStepPass ? (
<ButtonCombo
handleStepPass={this.handleStepPass}
step="phraseStepPass"
disabled={!pinStepPass}
t={this.props.t}
/>
) : (
<Box justify="center" color={colors.wallet} ml={8}>
<IconCheck size={16} />
</Box>
)}
<RadioGroup
style={{ margin: '0 30px' }}
items={this.getButtonLabel()}
activeKey={cachedPhraseStepButton}
onChange={item => this.handleButtonPass(item, 'phraseStepPass')}
/>
</CardWrapper>
</Box>
<Box mt={5}>
<CardWrapper disabled={!phraseStepPass}>
<CardWrapper isDisabled={!phraseStepPass}>
<Box justify="center">
<Box horizontal>
<IconOptionRow>3.</IconOptionRow>
@ -145,58 +160,42 @@ class GenuineCheck extends PureComponent<StepProps, State> {
export default connect(null, mapDispatchToProps)(GenuineCheck)
export function ButtonCombo({
handleStepPass,
step,
disabled,
t,
}: {
handleStepPass: any,
step: string,
disabled: boolean,
t: T,
}) {
return (
<Box justify="center" horizontal style={{ margin: '0 20px' }}>
<Button
disabled={disabled}
style={{ padding: '0 20px' }}
outline
onClick={() => handleStepPass(step, true)}
>
{t('common:yes')}
</Button>
<Button
disabled={disabled}
style={{ padding: '0 20px' }}
outline
onClick={() => handleStepPass(step, false)}
>
{t('common:no')}
</Button>
</Box>
)
}
// TODO extract to a separate file
export function GenuineCheckFail({
redoGenuineCheck,
contactSupport,
isLedgerNano,
t,
}: {
redoGenuineCheck: () => void,
contactSupport: () => void,
isLedgerNano: boolean,
t: T,
}) {
return (
<Box sticky pt={150}>
<Box sticky pt={250}>
<Box grow alignItems="center">
<Title>{t('onboarding:genuineCheck.errorPage.ledgerNano.title')}</Title>
<Description style={{ maxWidth: 527 }}>
{t('onboarding:genuineCheck.errorPage.ledgerNano.desc')}
</Description>
<Box style={{ minWidth: 527 }}>
<IconLedgerNanoError />
</Box>
{isLedgerNano ? (
<Fragment>
<Title>{t('onboarding:genuineCheck.errorPage.ledgerNano.title')}</Title>
<Description style={{ maxWidth: 527 }}>
{t('onboarding:genuineCheck.errorPage.ledgerNano.desc')}
</Description>
<Box style={{ minWidth: 527 }}>
<IconLedgerNanoError />
</Box>
</Fragment>
) : (
<Fragment>
<Title>{t('onboarding:genuineCheck.errorPage.ledgerBlue.title')}</Title>
<Description style={{ maxWidth: 527 }}>
{t('onboarding:genuineCheck.errorPage.ledgerBlue.desc')}
</Description>
<Box style={{ minWidth: 527, alignItems: 'center' }}>
<IconLedgerBlueError />
</Box>
</Fragment>
)}
</Box>
<Wrapper horizontal>
<Button
@ -249,9 +248,10 @@ const CardWrapper = styled(Card).attrs({
horizontal: true,
p: 5,
})`
border: ${props => (props.disabled ? '1px dashed #d8d8d8' : '1px solid #d8d8d8')};
max-height: 97px;
min-width: 620px;
background-color: ${props => (props.disabled ? colors.lightGrey : colors.white)};
opacity: ${props => (props.disabled ? 0.7 : 1)};
border: ${p => `1px ${p.isDisabled ? 'dashed' : 'solid'} ${p.theme.colors.fog}`};
pointer-events: ${p => (p.isDisabled ? 'none' : 'auto')};
background-color: ${p => (p.isDisabled ? p.theme.colors.lightGrey : p.theme.colors.white)};
opacity: ${p => (p.isDisabled ? 0.7 : 1)};
`

98
src/components/Onboarding/steps/SelectDevice.js

@ -1,57 +1,78 @@
// @flow
import React from 'react'
import React, { PureComponent } from 'react'
import styled from 'styled-components'
import { connect } from 'react-redux'
import { isLedgerNano } from 'reducers/onboarding'
import Box from 'components/base/Box'
import IconCheckCirle from 'icons/CheckCircle'
import IconLedgerNano from 'icons/onboarding/LedgerNano'
import IconLedgerBlue from 'icons/onboarding/LedgerBlue'
import { Title, Description, Inner } from '../helperComponents'
import type { StepProps } from '..'
export default (props: StepProps) => {
const { nextStep, t } = props
const mapDispatchToProps = { isLedgerNano }
return (
<Box sticky pt={150}>
<Box grow alignItems="center">
<Title>{t('onboarding:selectDevice.title')}</Title>
<Description style={{ maxWidth: 714 }}>{t('onboarding:selectDevice.desc')}</Description>
<Box>
<Inner>
<DeviceContainer onClick={() => nextStep()}>
<DeviceIcon>
<IconLedgerNano />
</DeviceIcon>
<BlockTitle pb={3}>{t('onboarding:selectDevice.ledgerNanoCard.title')}</BlockTitle>
<BlockDescription>
{t('onboarding:selectDevice.ledgerNanoCard.desc')}
</BlockDescription>
</DeviceContainer>
<DeviceContainer>
<DeviceIcon>
<IconLedgerBlue />
</DeviceIcon>
<BlockTitle pb={3}>{t('onboarding:selectDevice.ledgerBlueCard.title')}</BlockTitle>
<BlockDescription>
{t('onboarding:selectDevice.ledgerBlueCard.desc')}
</BlockDescription>
</DeviceContainer>
</Inner>
class SelectDevice extends PureComponent<StepProps, {}> {
handleIsLedgerNano = (isLedgerNano: boolean) => {
this.props.isLedgerNano(isLedgerNano)
this.props.nextStep()
}
render() {
const { t, onboarding } = this.props
return (
<Box sticky pt={150}>
<Box grow alignItems="center">
<Title>{t('onboarding:selectDevice.title')}</Title>
<Description style={{ maxWidth: 536 }}>{t('onboarding:selectDevice.desc')}</Description>
<Box>
<Inner>
<DeviceContainer
onClick={() => this.handleIsLedgerNano(true)}
style={{
position: 'relative',
}}
>
{onboarding.isLedgerNano && <DeviceSelected />}
<DeviceIcon>
<IconLedgerNano />
</DeviceIcon>
<BlockTitle pb={3}>{t('onboarding:selectDevice.ledgerNanoCard.title')}</BlockTitle>
</DeviceContainer>
<DeviceContainer
onClick={() => this.handleIsLedgerNano(false)}
style={{
position: 'relative',
}}
>
{!onboarding.isLedgerNano && <DeviceSelected />}
<DeviceIcon>
<IconLedgerBlue />
</DeviceIcon>
<BlockTitle pb={3}>{t('onboarding:selectDevice.ledgerBlueCard.title')}</BlockTitle>
</DeviceContainer>
</Inner>
</Box>
</Box>
</Box>
</Box>
)
)
}
}
export default connect(null, mapDispatchToProps)(SelectDevice)
const DeviceContainer = styled(Box).attrs({
alignItems: 'center',
justifyContent: 'center',
position: 'relative',
})`
width: 218px;
height: 204px;
border: 1px solid #d8d8d8;
border: ${props => `1px solid ${props.theme.colors.fog}`};
&:hover,
&:focus {
opacity: 0.5;
@ -77,3 +98,16 @@ export const BlockTitle = styled(Box).attrs({
fontSize: 4,
textAlign: 'center',
})``
export function DeviceSelected() {
return (
<Box
style={{
position: 'absolute',
top: '10px',
right: '10px',
}}
>
<IconCheckCirle size={12} />
</Box>
)
}

74
src/components/Onboarding/steps/SelectPIN.js

@ -1,12 +1,14 @@
// @flow
import React from 'react'
import React, { Fragment } from 'react'
import Box from 'components/base/Box'
import { colors } from 'styles/theme'
import IconSelectPIN from 'icons/onboarding/SelectPIN'
import IconLedgerNanoSelectPIN from 'icons/onboarding/LedgerNanoSelectPIN'
import IconLedgerBlueSelectPIN from 'icons/onboarding/LedgerBlueSelectPIN'
import IconChevronRight from 'icons/ChevronRight'
import IconLedgerBlue from 'icons/onboarding/LedgerBlue'
import {
Title,
@ -21,27 +23,45 @@ import OnboardingFooter from '../OnboardingFooter'
import type { StepProps } from '..'
export default (props: StepProps) => {
const { nextStep, prevStep, t } = props
const steps = [
const { nextStep, prevStep, t, onboarding } = props
const stepsLedgerNano = [
{
key: 'step1',
icon: <IconOptionRow>1.</IconOptionRow>,
desc: t('onboarding:selectPIN.instructions.step1'),
desc: t('onboarding:selectPIN.instructions.ledgerNano.step1'),
},
{
key: 'step2',
icon: <IconOptionRow>2.</IconOptionRow>,
desc: t('onboarding:selectPIN.instructions.step2'),
desc: t('onboarding:selectPIN.instructions.ledgerNano.step2'),
},
{
key: 'step3',
icon: <IconOptionRow>3.</IconOptionRow>,
desc: t('onboarding:selectPIN.instructions.step3'),
desc: t('onboarding:selectPIN.instructions.ledgerNano.step3'),
},
{
key: 'step4',
icon: <IconOptionRow>4.</IconOptionRow>,
desc: t('onboarding:selectPIN.instructions.step4'),
desc: t('onboarding:selectPIN.instructions.ledgerNano.step4'),
},
]
const stepsLedgerBlue = [
{
key: 'step1',
icon: <IconOptionRow>1.</IconOptionRow>,
desc: t('onboarding:selectPIN.instructions.ledgerBlue.step1'),
},
{
key: 'step2',
icon: <IconOptionRow>2.</IconOptionRow>,
desc: t('onboarding:selectPIN.instructions.ledgerBlue.step2'),
},
{
key: 'step3',
icon: <IconOptionRow>3.</IconOptionRow>,
desc: t('onboarding:selectPIN.instructions.ledgerBlue.step3'),
},
]
const disclaimerNotes = [
@ -66,18 +86,36 @@ export default (props: StepProps) => {
<Box grow alignItems="center">
<Box align="center" mb={5}>
<Title>{t('onboarding:selectPIN.title')}</Title>
<Description style={{ maxWidth: 527 }}>{t('onboarding:selectPIN.desc')}</Description>
</Box>
<Box align="center">
<Inner style={{ width: 760 }}>
<Box style={{ width: 260 }} mt={5}>
<IconSelectPIN />
</Box>
<Box align="center" mt={5}>
{onboarding.isLedgerNano ? (
<Fragment>
{' '}
<Inner style={{ width: 680 }}>
<Box style={{ width: 260 }} mt={5}>
<IconLedgerNanoSelectPIN />
</Box>
<Box shrink grow flow={4}>
{stepsLedgerNano.map(step => <OptionRow key={step.key} step={step} />)}
</Box>
</Inner>
</Fragment>
) : (
<Fragment>
{' '}
<Inner style={{ width: 680 }}>
<Box style={{ width: 260, alignItems: 'center' }}>
<IconLedgerBlueSelectPIN />
</Box>
<Box shrink grow flow={4}>
{stepsLedgerBlue.map(step => <OptionRow key={step.key} step={step} />)}
</Box>
</Inner>
</Fragment>
)}
<Box shrink grow flow={4}>
{steps.map(step => <OptionRow key={step.key} step={step} />)}
</Box>
</Inner>
<DisclaimerBox mt={6} disclaimerNotes={disclaimerNotes} />
</Box>
</Box>

47
src/icons/onboarding/LedgerBlueError.js

@ -0,0 +1,47 @@
// @flow
import React from 'react'
export default () => (
<svg width="92" height="188">
<defs>
<linearGradient id="a" x1="50%" x2="50%" y1="0%" y2="100%">
<stop offset="0%" />
<stop offset="100%" stopColor="#FFF" />
</linearGradient>
</defs>
<g fill="none" fillRule="evenodd">
<path
stroke="#1D2027"
strokeWidth="2"
d="M37 120.644a1 1 0 0 0-1 1v26.225a5 5 0 0 0 5 5h8.486a5 5 0 0 0 5-5v-26.225a1 1 0 0 0-1-1H37z"
/>
<path stroke="#142533" strokeWidth="2" d="M42.208 153.253v10.929h6.436v-10.93h-6.436z" />
<path
stroke="#1D2027"
strokeWidth="2"
d="M39.713 120.577h11.255l-.082-6.977a1 1 0 0 0-1-.988h-9.267a1 1 0 0 0-.988 1.012l.082 6.953z"
/>
<path
fill="url(#a)"
d="M6.836 53.925h1.616v22.65H6.836v-22.65zm5.657 0h1.616v22.65h-1.616v-22.65z"
transform="translate(35 111)"
/>
<path
fill="#1D2028"
d="M88.556 17.556c0-1.105.671-2 1.5-2 .828 0 1.5.895 1.5 2v6c0 1.104-.672 2-1.5 2-.829 0-1.5-.896-1.5-2"
/>
<rect
width="88"
height="118.635"
x="1"
y="1"
fill="#FCEAEC"
stroke="#1D2027"
strokeWidth="2"
rx="5.44"
/>
<rect width="59" height="88.615" x="15.5" y="16.5" fill="#FFF" stroke="#EA2E49" rx="4.08" />
</g>
</svg>
)

47
src/icons/onboarding/LedgerBlueSelectPIN.js

@ -0,0 +1,47 @@
// @flow
import React from 'react'
export default () => (
<svg width="92" height="188">
<defs>
<linearGradient id="a" x1="50%" x2="50%" y1="0%" y2="100%">
<stop offset="0%" />
<stop offset="100%" stopColor="#FFF" />
</linearGradient>
</defs>
<g fill="none" fillRule="evenodd">
<path
stroke="#1D2027"
strokeWidth="2"
d="M37 120.644a1 1 0 0 0-1 1v26.225a5 5 0 0 0 5 5h8.486a5 5 0 0 0 5-5v-26.225a1 1 0 0 0-1-1H37z"
/>
<path stroke="#142533" strokeWidth="2" d="M42.208 153.253v10.929h6.436v-10.93h-6.436z" />
<path
stroke="#1D2027"
strokeWidth="2"
d="M39.713 120.577h11.255l-.082-6.977a1 1 0 0 0-1-.988h-9.267a1 1 0 0 0-.988 1.012l.082 6.953z"
/>
<path
fill="url(#a)"
d="M6.836 53.925h1.616v22.65H6.836v-22.65zm5.657 0h1.616v22.65h-1.616v-22.65z"
transform="translate(35 111)"
/>
<path
fill="#1D2028"
d="M88.556 17.556c0-1.105.671-2 1.5-2 .828 0 1.5.895 1.5 2v6c0 1.104-.672 2-1.5 2-.829 0-1.5-.896-1.5-2"
/>
<rect
width="88"
height="118.635"
x="1"
y="1"
fill="#EFF3FD"
stroke="#1D2027"
strokeWidth="2"
rx="5.44"
/>
<rect width="59" height="88.615" x="15.5" y="16.5" fill="#FFF" stroke="#6490F1" rx="4.08" />
</g>
</svg>
)

30
src/icons/onboarding/LedgerNano.js

@ -3,22 +3,22 @@
import React from 'react'
export default () => (
<svg width="112" height="20">
<g fill="none" fillRule="evenodd" transform="rotate(-90 10 10)">
<rect width="1.6" height="6.4" x="18.4" y="6.4" fill="#1D2028" rx=".8" />
<rect width="1.6" height="6.4" x="18.4" y="27.2" fill="#1D2028" rx=".8" />
<svg width="13" height="72">
<g fill="none" fillRule="evenodd">
<rect width="1.04" height="4.114" x="11.96" y="4.114" fill="#1D2028" rx=".52" />
<rect width="1.04" height="4.114" x="11.96" y="17.486" fill="#1D2028" rx=".52" />
<path
fill="#6490F1"
fillOpacity=".1"
stroke="#1D2028"
strokeWidth="1.5"
d="M1.6.75a.85.85 0 0 0-.85.85v108.8c0 .47.38.85.85.85h16c.47 0 .85-.38.85-.85V1.6a.85.85 0 0 0-.85-.85h-16z"
d="M1.6.75a.85.85 0 0 0-.85.85v68.8c0 .47.38.85.85.85h9.28c.47 0 .85-.38.85-.85V1.6a.85.85 0 0 0-.85-.85H1.6z"
/>
<rect
width="9.1"
height="31.5"
x="5.081"
y="8.275"
width="5.74"
height="20.071"
x="3.39"
y="5.409"
fill="#FFF"
stroke="#6490F1"
strokeWidth=".5"
@ -28,9 +28,17 @@ export default () => (
fill="#FFF"
stroke="#1D2028"
strokeWidth="1.5"
d="M9.6 48.75A8.85 8.85 0 0 0 .75 57.6v52.8c0 .47.38.85.85.85h16c.47 0 .85-.38.85-.85V57.6a8.85 8.85 0 0 0-8.85-8.85z"
d="M6.24 31.607a5.49 5.49 0 0 0-5.49 5.49V70.4c0 .47.38.85.85.85h9.28c.47 0 .85-.38.85-.85V37.097a5.49 5.49 0 0 0-5.49-5.49z"
/>
<ellipse
cx="6.24"
cy="37.029"
fill="#FFF"
stroke="#6490F1"
strokeWidth=".5"
rx="2.87"
ry="2.836"
/>
<circle cx="9.6" cy="57.6" r="4.55" fill="#FFF" stroke="#6490F1" strokeWidth=".5" />
</g>
</svg>
)

0
src/icons/onboarding/SelectPIN.js → src/icons/onboarding/LedgerNanoSelectPIN.js

206
src/icons/onboarding/WriteSeed.js

@ -3,195 +3,43 @@
import React from 'react'
export default () => (
<svg width="157" height="144">
<defs>
<rect id="b" width="42" height="10" y="45" rx="2" />
<filter
id="a"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="d" width="42" height="10" x="67" y="35" rx="2" />
<filter
id="c"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="f" width="42" height="10" x="31" y="11" rx="2" />
<filter
id="e"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="h" width="42" height="10" x="103" rx="2" />
<filter
id="g"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="j" width="42" height="10" x="104" y="55" rx="2" />
<filter
id="i"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="l" width="42" height="10" x="31" y="67" rx="2" />
<filter
id="k"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="n" width="42" height="10" x="11" y="96" rx="2" />
<filter
id="m"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="p" width="42" height="10" x="109" y="103" rx="2" />
<filter
id="o"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
<rect id="r" width="42" height="10" x="78" y="83" rx="2" />
<filter
id="q"
width="123.8%"
height="200%"
x="-11.9%"
y="-40%"
filterUnits="objectBoundingBox"
>
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1" />
<feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="1.5" />
<feColorMatrix
in="shadowBlurOuter1"
values="0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 0 0.847058824 0 0 0 1 0"
/>
</filter>
</defs>
<g fill="none" fillRule="evenodd" transform="translate(3 2)">
<circle
cx="79"
cy="72"
r="57"
<svg width="145" height="126">
<g fill="none" fillRule="evenodd" transform="translate(-1)">
<path
fill="#6490F1"
fillOpacity=".1"
stroke="#142533"
strokeWidth="2"
strokeWidth="1.8"
d="M29.105 103.014l19.87-84.34L4.123 34.999a2.7 2.7 0 0 0-1.573 3.566l26.556 64.449zm89.265 1.336L97.73 33.29l44.752 16.288a2.7 2.7 0 0 1 1.49 3.748L118.37 104.35z"
/>
<rect
width="88.2"
height="106.2"
x="29.9"
y=".9"
fill="#FFF"
stroke="#142533"
strokeWidth="1.8"
rx="3.6"
/>
<path
fill="#6490F1"
fillRule="nonzero"
stroke="#142533"
d="M88.63 118.285h-1.07v-6.596c0-4.791-3.846-8.689-8.574-8.689s-8.574 3.898-8.574 8.69v6.595H69.34c-1.844 0-3.339 1.515-3.339 3.384v15.695c0 1.869 1.495 3.384 3.339 3.384h19.292c1.843 0 3.339-1.515 3.339-3.384V121.67c0-1.87-1.495-3.384-3.34-3.384zm-15.22-6.596c0-3.115 2.502-5.649 5.576-5.649 3.072 0 5.573 2.534 5.573 5.65v6.595H73.41v-6.596z"
d="M82.969 92.378h23.22a1.81 1.81 0 0 1 0 3.622H82.97a1.81 1.81 0 0 1 0-3.622zm-41.158 0h23.22a1.81 1.81 0 0 1 0 3.622h-23.22a1.81 1.81 0 1 1 0-3.622zm41.158-12.675h23.22a1.81 1.81 0 0 1 0 3.621H82.97a1.81 1.81 0 0 1 0-3.621zm-41.158 0h23.22a1.81 1.81 0 0 1 0 3.621h-23.22a1.81 1.81 0 1 1 0-3.621zm41.158-12.676h23.22a1.81 1.81 0 0 1 0 3.622H82.97a1.81 1.81 0 0 1 0-3.622zm-41.158 0h23.22a1.81 1.81 0 0 1 0 3.622h-23.22a1.81 1.81 0 1 1 0-3.622zm41.158-12.676h23.22a1.81 1.81 0 0 1 0 3.622H82.97a1.81 1.81 0 0 1 0-3.622zm-41.158 0h23.22a1.81 1.81 0 0 1 0 3.622h-23.22a1.81 1.81 0 1 1 0-3.622zm41.158-12.675h23.22a1.81 1.81 0 0 1 0 3.621H82.97a1.81 1.81 0 0 1 0-3.621zm-41.158 0h23.22a1.81 1.81 0 0 1 0 3.621h-23.22a1.81 1.81 0 1 1 0-3.621zM82.969 29h23.22a1.81 1.81 0 0 1 0 3.622H82.97a1.81 1.81 0 0 1 0-3.622zM41.81 29h23.22a1.81 1.81 0 0 1 0 3.622H41.81a1.81 1.81 0 1 1 0-3.622z"
opacity=".5"
/>
<path
fill="#FFF"
d="M80.694 129.345v4.225a1.72 1.72 0 0 1-1.709 1.73 1.72 1.72 0 0 1-1.708-1.73v-4.225a3.08 3.08 0 0 1-1.325-2.54c0-1.698 1.358-3.074 3.033-3.074 1.675 0 3.033 1.377 3.033 3.075a3.083 3.083 0 0 1-1.325 2.54z"
fillRule="nonzero"
stroke="#6490F1"
strokeWidth="2"
d="M85.623 57.047a17.987 17.987 0 0 1 6.194 13.596c0 9.92-8.032 17.99-17.909 17.99-9.876 0-17.908-8.07-17.908-17.99a17.986 17.986 0 0 1 6.194-13.596v-3.281C62.194 47.278 67.447 42 73.908 42c6.462 0 11.715 5.278 11.715 11.766v3.28zM73.809 74.193zm.003-.018v4.55a.1.1 0 0 0 .096.102.1.1 0 0 0 .097-.102v-4.55a3.149 3.149 0 0 1-.006-.054l-.088-.899.885-.179a4.505 4.505 0 0 0 3.596-4.42c0-2.493-2.008-4.51-4.484-4.51-2.475 0-4.483 2.018-4.483 4.51a4.505 4.505 0 0 0 3.596 4.42l.885.18-.088.898a3.149 3.149 0 0 1-.006.054zm.196.018a.1.1 0 0 0 0 .004v-.004zm0 .004v-.002zm-7.62-19.876a17.719 17.719 0 0 1 7.52-1.668c2.633 0 5.186.577 7.521 1.668v-.555c0-4.17-3.375-7.562-7.52-7.562-4.146 0-7.521 3.392-7.521 7.562v.555z"
/>
<use fill="#000" filter="url(#a)" xlinkHref="#b" />
<use fill="#FFF" xlinkHref="#b" />
<use fill="#000" filter="url(#c)" xlinkHref="#d" />
<use fill="#FFF" xlinkHref="#d" />
<use fill="#000" filter="url(#e)" xlinkHref="#f" />
<use fill="#FFF" xlinkHref="#f" />
<use fill="#000" filter="url(#g)" xlinkHref="#h" />
<use fill="#FFF" xlinkHref="#h" />
<use fill="#000" filter="url(#i)" xlinkHref="#j" />
<use fill="#FFF" xlinkHref="#j" />
<use fill="#000" filter="url(#k)" xlinkHref="#l" />
<use fill="#FFF" xlinkHref="#l" />
<use fill="#000" filter="url(#m)" xlinkHref="#n" />
<use fill="#FFF" xlinkHref="#n" />
<g>
<use fill="#000" filter="url(#o)" xlinkHref="#p" />
<use fill="#FFF" xlinkHref="#p" />
</g>
<g>
<use fill="#000" filter="url(#q)" xlinkHref="#r" />
<use fill="#FFF" xlinkHref="#r" />
</g>
{/* <text fill="#142533" fontFamily="MuseoSans-700, Museo Sans" fontSize="5" fontWeight="500">
<tspan x="41" y="17">
RECOVERY PHRASE
</tspan>
</text> */}
<ellipse cx="75" cy="122.5" fill="#EEE" rx="48" ry="3.5" />
</g>
</svg>
)

7
src/reducers/onboarding.js

@ -18,12 +18,14 @@ export type OnboardingState = {
stepName: string, // TODO: specify that the string comes from Steps type
steps: Step[],
isGenuineFail: boolean,
isLedgerNano: boolean,
}
const state: OnboardingState = {
stepIndex: 0,
stepName: 'start',
isGenuineFail: false,
isLedgerNano: true,
steps: [
{
name: 'start',
@ -144,6 +146,10 @@ const handlers = {
...state,
isGenuineFail,
}),
ONBOARDING_SET_DEVICE_TYPE: (state, { payload: isLedgerNano }) => ({
...state,
isLedgerNano,
}),
}
export default handleActions(handlers, state)
@ -152,3 +158,4 @@ export const nextStep = createAction('ONBOARDING_NEXT_STEP')
export const prevStep = createAction('ONBOARDING_PREV_STEP')
export const jumpStep = createAction('ONBOARDING_JUMP_STEP')
export const setGenuineCheckFail = createAction('ONBOARDING_SET_GENUINE_CHECK_FAIL')
export const isLedgerNano = createAction('ONBOARDING_SET_DEVICE_TYPE')

29
static/i18n/en/onboarding.yml

@ -25,13 +25,17 @@ selectDevice:
title: Ledger Blue
desc: Please replace it with the final wording once it’s done.
selectPIN:
title: Choose your PIN code
desc: This is a long text, please replace it with the final wording once it’s done. Lorem ipsum dolor amet ledger lorem dolor ipsum amet
title: Start initialization & choose your PIN code
instructions:
step1: Connect the Ledger Nano S to your computer.
step2: Press both buttons simultaneously as instructed on the screen.
step3: Press the right button to select Configure as new device.
step4: Choose a PIN code between 4 and 8 digits long.
ledgerNano:
step1: Connect the Ledger Nano S to your computer.
step2: Press both buttons simultaneously as instructed on the screen.
step3: Press the right button to select Configure as new device.
step4: Choose a PIN code between 4 and 8 digits long.
ledgerBlue:
step1: Connect the Ledger Blue to your computer.
step2: Tap on Configure as new device.
step3: Choose a PIN code between 4 and 8 digits long.
disclaimer:
note1: Choose your own PIN code. This code unlocks your device.
note2: An 8-digit PIN code offers an optimum level of security.
@ -49,17 +53,17 @@ writeSeed:
note3: Make sure you are the sole holder of the 24-word recovery phrase.
note4: Never use a device supplied with a recovery phrase and/or a PIN code.
genuineCheck:
title: Check PIN / Seed / Authenticity
title: Final security check
desc: Your Ledger Nano S should now display Your device is now ready. Before getting started, please confirm that
steps:
step1:
title: You alone have chosen your PIN code
title: Did you choose your PIN code by yourself?
desc: This is a long text, please replace it with the final wording once it’s done. Lorem ipsum dolor amet ledger lorem dolor
step2:
title: You alone have initialized your recovery phrase
title: Did you save your recovery phrase by yourself?
desc: This is a long text, please replace it with the final wording once it’s done. Lorem ipsum dolor amet ledger lorem dolor
step3:
title: Your device is a genuine Ledger device
title: Check if your Ledger device is genuine
desc: This is a long text, please replace it with the final wording once it’s done. Lorem ipsum dolor amet ledger lorem dolor
buttons:
genuineCheck: Genuine check
@ -67,7 +71,10 @@ genuineCheck:
errorPage:
ledgerNano:
title: Something is wrong with your Ledger Nano S
desc: Your Ledger Nano S should now display Your device is now ready. Before getting started, please confirm that
desc: A problem occurred with your Ledger Nano S. Contact Ledger Support to get assistance or go back to the security check.
ledgerBlue:
title: Something is wrong with your Ledger Blue
desc: A problem occurred with your Ledger Blue. Contact Ledger Support to get assistance or go back to the security check.
setPassword:
title: This is the title of the screen. 1 line is the maximum
desc: This is a long text, please replace it with the final wording once it’s done. Lorem ipsum dolor amet ledger lorem dolor ipsum amet

Loading…
Cancel
Save