Meriadec Pillet
7 years ago
committed by
GitHub
16 changed files with 846 additions and 83 deletions
@ -0,0 +1,32 @@ |
|||
// @flow
|
|||
|
|||
import React from 'react' |
|||
import { connect } from 'react-redux' |
|||
import findIndex from 'lodash/findIndex' |
|||
|
|||
import type { OnboardingState } from 'reducers/onboarding' |
|||
|
|||
import Breadcrumb from 'components/Breadcrumb' |
|||
|
|||
const mapStateToProps = state => ({ |
|||
onboarding: state.onboarding, |
|||
}) |
|||
|
|||
type Props = { |
|||
onboarding: OnboardingState, |
|||
} |
|||
|
|||
function OnboardingBreadcrumb(props: Props) { |
|||
const { onboarding } = props |
|||
const { stepName } = onboarding |
|||
|
|||
const filteredSteps = onboarding.steps |
|||
.filter(step => !step.external) |
|||
.map(step => ({ ...step, label: step.label })) // TODO: translate
|
|||
|
|||
const stepIndex = findIndex(filteredSteps, s => s.name === stepName) |
|||
|
|||
return <Breadcrumb currentStep={stepIndex} items={filteredSteps} /> |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(OnboardingBreadcrumb) |
@ -0,0 +1,15 @@ |
|||
// @flow
|
|||
|
|||
import styled from 'styled-components' |
|||
import { radii } from 'styles/theme' |
|||
|
|||
import Box from 'components/base/Box' |
|||
|
|||
export const OnboardingFooter = styled(Box).attrs({ |
|||
px: 5, |
|||
py: 3, |
|||
})` |
|||
border-top: 2px solid ${p => p.theme.colors.lightGrey}; |
|||
border-bottom-left-radius: ${radii[1]}px; |
|||
border-bottom-right-radius: ${radii[1]}px; |
|||
` |
@ -0,0 +1,38 @@ |
|||
// @flow
|
|||
import styled from 'styled-components' |
|||
import { radii } from 'styles/theme' |
|||
|
|||
import Box from 'components/base/Box' |
|||
|
|||
export const Title = styled(Box).attrs({ |
|||
width: 152, |
|||
height: 27, |
|||
ff: 'Museo Sans|Regular', |
|||
fontSize: 7, |
|||
color: 'dark', |
|||
})`` |
|||
|
|||
export const Description = styled(Box).attrs({ |
|||
width: 340, |
|||
height: 36, |
|||
ff: 'Open Sans|Regular', |
|||
fontSize: 4, |
|||
textAlign: 'center', |
|||
color: 'smoke', |
|||
})` |
|||
margin: 10px auto 25px; |
|||
` |
|||
export const Inner = styled(Box).attrs({ |
|||
horizontal: true, |
|||
grow: true, |
|||
flow: 4, |
|||
})`` |
|||
|
|||
export const OnboardingFooter = styled(Box).attrs({ |
|||
px: 5, |
|||
py: 3, |
|||
})` |
|||
border-top: 2px solid ${p => p.theme.colors.lightGrey}; |
|||
border-bottom-left-radius: ${radii[1]}px; |
|||
border-bottom-right-radius: ${radii[1]}px; |
|||
` |
@ -0,0 +1,72 @@ |
|||
// @flow
|
|||
|
|||
import React from 'react' |
|||
import styled from 'styled-components' |
|||
|
|||
import Box from 'components/base/Box' |
|||
import Button from 'components/base/Button' |
|||
import IconAnalytics from 'icons/LockScreen' |
|||
import CheckBox from 'components/base/CheckBox' |
|||
import { Title, Description, OnboardingFooter } from '../helperComponents' |
|||
|
|||
import type { StepProps } from '..' |
|||
|
|||
export default (props: StepProps) => { |
|||
const { nextStep, prevStep } = props |
|||
return ( |
|||
<Box sticky alignItems="center" justifyContent="center"> |
|||
<Box align="center"> |
|||
<Title>This is ANALYTICS screen. 1 line is the maximum</Title> |
|||
<Description> |
|||
This is a long text, please replace it with the final wording once it’s done. |
|||
<br /> |
|||
Lorem ipsum dolor amet ledger lorem dolor ipsum amet |
|||
</Description> |
|||
<DeviceIcon> |
|||
<IconAnalytics size={136} /> |
|||
</DeviceIcon> |
|||
<Box horizontal flow={2} align="center"> |
|||
<CheckBox isChecked /> |
|||
<AnalyticsText> |
|||
This is a long text, please replace it with the final wording once it’s done. |
|||
<br /> |
|||
Lorem ipsum dolor amet ledger lorem dolor ipsum amet |
|||
</AnalyticsText> |
|||
</Box> |
|||
<Box horizontal flow={2} align="center"> |
|||
<CheckBox isChecked={false} /> |
|||
<AnalyticsText> |
|||
This is a long text, please replace it with the final wording once it’s done. |
|||
<br /> |
|||
Lorem ipsum dolor amet ledger lorem dolor ipsum amet |
|||
</AnalyticsText> |
|||
</Box> |
|||
</Box> |
|||
<OnboardingFooter horizontal align="center" justify="flex-end" flow={2}> |
|||
<Button small outline onClick={() => prevStep()}> |
|||
Go Back |
|||
</Button> |
|||
<Button small primary onClick={() => nextStep()}> |
|||
Continue |
|||
</Button> |
|||
</OnboardingFooter> |
|||
</Box> |
|||
) |
|||
} |
|||
|
|||
export const AnalyticsText = styled(Box).attrs({ |
|||
ff: 'Open Sans|Regular', |
|||
fontSize: 4, |
|||
textAlign: 'left', |
|||
color: 'smoke', |
|||
})` |
|||
margin: 10px auto 25px; |
|||
padding-left: 10px; |
|||
` |
|||
const DeviceIcon = styled(Box).attrs({ |
|||
alignItems: 'center', |
|||
justifyContent: 'center', |
|||
color: 'graphite', |
|||
})` |
|||
width: 55px; |
|||
` |
@ -0,0 +1,62 @@ |
|||
// @flow
|
|||
|
|||
import React from 'react' |
|||
import styled from 'styled-components' |
|||
|
|||
import Box from 'components/base/Box' |
|||
import IconNanoS from 'icons/device/NanoS' |
|||
import IconBlue from 'icons/device/Blue' |
|||
import { Title, Description, Inner } from '../helperComponents' |
|||
|
|||
import type { StepProps } from '..' |
|||
|
|||
export default (props: StepProps) => { |
|||
const { nextStep } = props |
|||
|
|||
return ( |
|||
<Box sticky alignItems="center" justifyContent="center"> |
|||
<Box align="center"> |
|||
<Title>This is the title of the screen. 1 line is the maximum</Title> |
|||
<Description> |
|||
This is a long text, please replace it with the final wording once it’s done. |
|||
<br /> |
|||
Lorem ipsum dolor amet ledger lorem dolor ipsum amet |
|||
</Description> |
|||
<Box> |
|||
<Inner> |
|||
<DeviceContainer onClick={() => nextStep()}> |
|||
<DeviceIcon> |
|||
<IconNanoS size={46} /> |
|||
</DeviceIcon> |
|||
<Title>Ledger Nano S</Title> |
|||
<Description>Please replace it with the final wording once it’s done.</Description> |
|||
</DeviceContainer> |
|||
<DeviceContainer> |
|||
<DeviceIcon> |
|||
<IconBlue size={46} /> |
|||
</DeviceIcon> |
|||
<Title>Ledger Blue</Title> |
|||
<Description>Please replace it with the final wording once it’s done.</Description> |
|||
</DeviceContainer> |
|||
</Inner> |
|||
</Box> |
|||
</Box> |
|||
</Box> |
|||
) |
|||
} |
|||
|
|||
const DeviceContainer = styled(Box).attrs({ |
|||
alignItems: 'center', |
|||
justifyContent: 'center', |
|||
})` |
|||
width: 218px; |
|||
height: 204px; |
|||
border: 1px solid #d8d8d8; |
|||
` |
|||
const DeviceIcon = styled(Box).attrs({ |
|||
alignItems: 'center', |
|||
justifyContent: 'center', |
|||
color: 'graphite', |
|||
})` |
|||
width: 55px; |
|||
` |
@ -0,0 +1,33 @@ |
|||
// @flow
|
|||
|
|||
import React from 'react' |
|||
|
|||
import Box from 'components/base/Box' |
|||
import Button from 'components/base/Button' |
|||
import { Title, Description, OnboardingFooter } from '../helperComponents' |
|||
|
|||
import type { StepProps } from '..' |
|||
|
|||
export default (props: StepProps) => { |
|||
const { nextStep, prevStep } = props |
|||
return ( |
|||
<Box sticky alignItems="center" justifyContent="center"> |
|||
<Box align="center"> |
|||
<Title>This is CHOOSE PIN screen. 1 line is the maximum</Title> |
|||
<Description> |
|||
This is a long text, please replace it with the final wording once it’s done. |
|||
<br /> |
|||
Lorem ipsum dolor amet ledger lorem dolor ipsum amet |
|||
</Description> |
|||
</Box> |
|||
<OnboardingFooter horizontal align="center" justify="flex-end" flow={2}> |
|||
<Button small outline onClick={() => prevStep()}> |
|||
Go Back |
|||
</Button> |
|||
<Button small primary onClick={() => nextStep()}> |
|||
Continue |
|||
</Button> |
|||
</OnboardingFooter> |
|||
</Box> |
|||
) |
|||
} |
@ -0,0 +1,34 @@ |
|||
// @flow
|
|||
|
|||
import React from 'react' |
|||
|
|||
import Box from 'components/base/Box' |
|||
import Button from 'components/base/Button' |
|||
import Text from 'components/base/Text' |
|||
|
|||
import IconFinishOnboarding from 'icons/LockScreen' |
|||
import type { StepProps } from '..' |
|||
import { Title, Description } from '../helperComponents' |
|||
|
|||
export default (props: StepProps) => { |
|||
const { finish, jumpStep } = props |
|||
return ( |
|||
<Box sticky alignItems="center" justifyContent="center"> |
|||
<Box align="center"> |
|||
<Title>This is ENJOY THE APP screen. 1 line is the maximum</Title> |
|||
<Description> |
|||
This is a long text, please replace it with the final wording once it’s done. |
|||
<br /> |
|||
Lorem ipsum dolor amet ledger lorem dolor ipsum amet |
|||
</Description> |
|||
<IconFinishOnboarding size={136} /> |
|||
<Button small primary onClick={() => finish()}> |
|||
Open App |
|||
</Button> |
|||
<Box onClick={() => jumpStep('start')} style={{ padding: 15 }}> |
|||
<Text color="smoke">I want to go back to Onboarding</Text> |
|||
</Box> |
|||
</Box> |
|||
</Box> |
|||
) |
|||
} |
@ -0,0 +1,85 @@ |
|||
// @flow
|
|||
|
|||
import React, { PureComponent } from 'react' |
|||
|
|||
import Box from 'components/base/Box' |
|||
import Button from 'components/base/Button' |
|||
|
|||
import { Title, Description, OnboardingFooter } from '../helperComponents' |
|||
|
|||
import type { StepProps } from '..' |
|||
|
|||
type State = { |
|||
currentDevice: { |
|||
manufacturer: string, |
|||
release: number, |
|||
}, |
|||
showDeviceInfo: boolean, |
|||
showError: boolean, |
|||
} |
|||
|
|||
// temp checking the release version of the device if connected
|
|||
|
|||
class GenuineCheck extends PureComponent<StepProps, State> { |
|||
state = { |
|||
showDeviceInfo: false, |
|||
currentDevice: { manufacturer: 'Unknown', release: 0 }, |
|||
showError: false, |
|||
} |
|||
|
|||
handleCheckDevice = () => { |
|||
const currentDeviceInfo = this.props.getDeviceInfo() |
|||
if (currentDeviceInfo) { |
|||
this.setState({ showError: false, currentDevice: currentDeviceInfo, showDeviceInfo: true }) |
|||
} else { |
|||
this.setState({ showError: true }) |
|||
} |
|||
} |
|||
|
|||
render() { |
|||
const { nextStep, prevStep, jumpStep } = this.props |
|||
const { showDeviceInfo, currentDevice, showError } = this.state |
|||
|
|||
return ( |
|||
<Box sticky alignItems="center" justifyContent="center"> |
|||
<Box align="center"> |
|||
<Title>This is GENUINE CHECK screen. 1 line is the maximum</Title> |
|||
<Description> |
|||
This is a long text, please replace it with the final wording once it’s done. |
|||
<br /> |
|||
Lorem ipsum dolor amet ledger lorem dolor ipsum amet |
|||
</Description> |
|||
</Box> |
|||
<Button big primary onClick={() => this.handleCheckDevice()}> |
|||
Check your device! |
|||
</Button> |
|||
{showDeviceInfo && ( |
|||
<Box> |
|||
<Description> |
|||
The manufacturer is <b>{currentDevice.manufacturer}</b> |
|||
The release number is <b>{currentDevice.release}</b> |
|||
</Description> |
|||
</Box> |
|||
)} |
|||
{showError && ( |
|||
<Box> |
|||
<Description color="red">Connect your device please</Description> |
|||
</Box> |
|||
)} |
|||
<OnboardingFooter horizontal align="center" justify="flex-end" flow={2}> |
|||
<Button small outline onClick={() => prevStep()}> |
|||
Go Back |
|||
</Button> |
|||
<Button big danger onClick={() => jumpStep('init')}> |
|||
Test JUMP! |
|||
</Button> |
|||
<Button small primary onClick={() => nextStep()}> |
|||
Continue |
|||
</Button> |
|||
</OnboardingFooter> |
|||
</Box> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default GenuineCheck |
@ -0,0 +1,90 @@ |
|||
// @flow
|
|||
|
|||
import React from 'react' |
|||
import styled from 'styled-components' |
|||
import { shell } from 'electron' |
|||
|
|||
import Box from 'components/base/Box' |
|||
import IconUser from 'icons/User' |
|||
import { Title, Description, Inner } from '../helperComponents' |
|||
|
|||
import type { StepProps } from '..' |
|||
|
|||
export default (props: StepProps) => { |
|||
const { nextStep, jumpStep } = props |
|||
const handleOpenLink = (url: string) => () => shell.openExternal(url) |
|||
/* TODO: all titles, descriptions to be wrapped in a translation tag once defined */ |
|||
return ( |
|||
<Box sticky alignItems="center" justifyContent="center"> |
|||
<Box align="center"> |
|||
<Title>This is the title of the screen. 1 line is the maximum</Title> |
|||
<Description> |
|||
This is a long text, please replace it with the final wording once it’s done. |
|||
<br /> |
|||
Lorem ipsum dolor amet ledger lorem dolor ipsum amet |
|||
</Description> |
|||
<Box style={{ paddingBottom: 10 }}> |
|||
<Inner> |
|||
<DeviceContainer onClick={() => nextStep()}> |
|||
{/* colors are temp, we don't have icons now */} |
|||
<DeviceIcon style={{ color: '#66be54' }}> |
|||
<IconUser size={24} /> |
|||
</DeviceIcon> |
|||
<TrackChoiceTitle>Clean Nano S setup</TrackChoiceTitle> |
|||
<Description>Please replace it with the final wording once it’s done.</Description> |
|||
</DeviceContainer> |
|||
<DeviceContainer onClick={() => jumpStep('choosePIN')}> |
|||
<DeviceIcon style={{ color: '#66be54' }}> |
|||
<IconUser size={24} /> |
|||
</DeviceIcon> |
|||
<TrackChoiceTitle>Existing seed + Clean setup</TrackChoiceTitle> |
|||
<Description>Please replace it with the final wording once it’s done.</Description> |
|||
</DeviceContainer> |
|||
</Inner> |
|||
</Box> |
|||
<Box> |
|||
<Inner> |
|||
<DeviceContainer onClick={() => nextStep()}> |
|||
<DeviceIcon style={{ color: '#6490f1' }}> |
|||
<IconUser size={24} /> |
|||
</DeviceIcon> |
|||
<TrackChoiceTitle>Migrate accounts</TrackChoiceTitle> |
|||
<Description>Please replace it with the final wording once it’s done.</Description> |
|||
</DeviceContainer> |
|||
<DeviceContainer onClick={handleOpenLink('https://www.ledger.fr/')}> |
|||
<DeviceIcon style={{ color: '#ea2e41' }}> |
|||
<IconUser size={24} /> |
|||
</DeviceIcon> |
|||
<TrackChoiceTitle>Not a user, but would love to</TrackChoiceTitle> |
|||
<Description>Please replace it with the final wording once it’s done.</Description> |
|||
</DeviceContainer> |
|||
</Inner> |
|||
</Box> |
|||
</Box> |
|||
</Box> |
|||
) |
|||
} |
|||
|
|||
const DeviceContainer = styled(Box).attrs({ |
|||
alignItems: 'center', |
|||
justifyContent: 'center', |
|||
})` |
|||
width: 218px; |
|||
height: 204px; |
|||
border: 1px solid #d8d8d8; |
|||
` |
|||
const DeviceIcon = styled(Box).attrs({ |
|||
alignItems: 'center', |
|||
justifyContent: 'center', |
|||
color: 'graphite', |
|||
})` |
|||
width: 55px; |
|||
padding: 10px; |
|||
` |
|||
export const TrackChoiceTitle = styled(Box).attrs({ |
|||
width: 152, |
|||
height: 27, |
|||
ff: 'Museo Sans|Regular', |
|||
fontSize: 5, |
|||
color: 'dark', |
|||
})`` |
@ -0,0 +1,93 @@ |
|||
// @flow
|
|||
|
|||
import React, { PureComponent } from 'react' |
|||
import bcrypt from 'bcryptjs' |
|||
|
|||
import { setEncryptionKey } from 'helpers/db' |
|||
|
|||
import Box from 'components/base/Box' |
|||
import Button from 'components/base/Button' |
|||
import Text from 'components/base/Text' |
|||
|
|||
import IconSetPassword from 'icons/LockScreen' |
|||
import PasswordModal from 'components/SettingsPage/PasswordModal' |
|||
|
|||
import type { StepProps } from '..' |
|||
|
|||
import { Title, Description, OnboardingFooter } from '../helperComponents' |
|||
|
|||
type State = { |
|||
isPasswordModalOpened: boolean, |
|||
isPasswordEnabled: boolean, |
|||
} |
|||
|
|||
class SetPassword extends PureComponent<StepProps, State> { |
|||
state = { |
|||
isPasswordModalOpened: false, |
|||
isPasswordEnabled: false, |
|||
} |
|||
|
|||
handleOpenPasswordModal = () => { |
|||
this.setState({ isPasswordModalOpened: true }) |
|||
} |
|||
handleClosePasswordModal = () => { |
|||
this.setState({ isPasswordModalOpened: false }) |
|||
} |
|||
handleChangePassword = (password: string) => { |
|||
window.requestIdleCallback(() => { |
|||
setEncryptionKey('accounts', password) |
|||
const hash = password ? bcrypt.hashSync(password, 8) : undefined |
|||
this.props.savePassword(hash) |
|||
}) |
|||
} |
|||
|
|||
handleInputChange = (key: string) => (value: string) => { |
|||
this.setState({ [key]: value }) |
|||
} |
|||
|
|||
render() { |
|||
const { nextStep, prevStep, t } = this.props |
|||
const { isPasswordModalOpened, isPasswordEnabled } = this.state |
|||
return ( |
|||
<Box sticky alignItems="center" justifyContent="center"> |
|||
<Box align="center"> |
|||
<Title>This is SET PASSWORD screen. 1 line is the maximum</Title> |
|||
<Description> |
|||
This is a long text, please replace it with the final wording once it’s done. |
|||
<br /> |
|||
Lorem ipsum dolor amet ledger lorem dolor ipsum amet |
|||
</Description> |
|||
<IconSetPassword size={136} /> |
|||
<Button small primary onClick={() => this.handleOpenPasswordModal()}> |
|||
Set Password |
|||
</Button> |
|||
{/* we might not be able to re-use what we have currently without modifications |
|||
the title and descriptions are not dynamic, we might need deffirent size as well */} |
|||
{isPasswordModalOpened && ( |
|||
<PasswordModal |
|||
t={t} |
|||
isOpened={isPasswordModalOpened} |
|||
onClose={this.handleClosePasswordModal} |
|||
onChangePassword={this.handleChangePassword} |
|||
isPasswordEnabled={isPasswordEnabled} |
|||
currentPasswordHash="" |
|||
/> |
|||
)} |
|||
<Box onClick={() => nextStep()} style={{ padding: 15 }}> |
|||
<Text color="smoke">I do not want to set it up</Text> |
|||
</Box> |
|||
</Box> |
|||
<OnboardingFooter horizontal flow={2}> |
|||
<Button small outline onClick={() => prevStep()}> |
|||
Go Back |
|||
</Button> |
|||
<Button small primary onClick={() => nextStep()}> |
|||
Continue |
|||
</Button> |
|||
</OnboardingFooter> |
|||
</Box> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default SetPassword |
@ -0,0 +1,27 @@ |
|||
// @flow
|
|||
|
|||
import React from 'react' |
|||
|
|||
import Box from 'components/base/Box' |
|||
import Button from 'components/base/Button' |
|||
|
|||
import LedgerLogo from 'icons/LockScreen' |
|||
import type { StepProps } from '..' |
|||
import { Title, Description } from '../helperComponents' |
|||
|
|||
export default (props: StepProps) => { |
|||
const { jumpStep } = props |
|||
return ( |
|||
<Box sticky alignItems="center" justifyContent="center"> |
|||
<Box align="center" alignItems="center"> |
|||
<LedgerLogo size={136} /> |
|||
<Title>Ledger Live</Title> |
|||
<Title>Welcome to the new Ledger Live Desktop app.</Title> |
|||
<Description>Let’s get started!</Description> |
|||
<Button small primary onClick={() => jumpStep('init')}> |
|||
Get Started |
|||
</Button> |
|||
</Box> |
|||
</Box> |
|||
) |
|||
} |
@ -0,0 +1,33 @@ |
|||
// @flow
|
|||
|
|||
import React from 'react' |
|||
|
|||
import Box from 'components/base/Box' |
|||
import Button from 'components/base/Button' |
|||
import { Title, Description, OnboardingFooter } from '../helperComponents' |
|||
|
|||
import type { StepProps } from '..' |
|||
|
|||
export default (props: StepProps) => { |
|||
const { nextStep, prevStep } = props |
|||
return ( |
|||
<Box sticky alignItems="center" justifyContent="center"> |
|||
<Box align="center"> |
|||
<Title>This is WRITE SEED screen. 1 line is the maximum</Title> |
|||
<Description> |
|||
This is a long text, please replace it with the final wording once it’s done. |
|||
<br /> |
|||
Lorem ipsum dolor amet ledger lorem dolor ipsum amet |
|||
</Description> |
|||
</Box> |
|||
<OnboardingFooter horizontal align="center" justify="flex-end" flow={2}> |
|||
<Button small outline onClick={() => prevStep()}> |
|||
Go Back |
|||
</Button> |
|||
<Button small primary onClick={() => nextStep()}> |
|||
Continue |
|||
</Button> |
|||
</OnboardingFooter> |
|||
</Box> |
|||
) |
|||
} |
@ -0,0 +1,147 @@ |
|||
// @flow
|
|||
|
|||
import { handleActions, createAction } from 'redux-actions' |
|||
|
|||
type Step = { |
|||
name: string, |
|||
external?: boolean, |
|||
label?: string, |
|||
options: { |
|||
showFooter: boolean, |
|||
showBackground: boolean, |
|||
showBreadcrumb: boolean, |
|||
}, |
|||
} |
|||
|
|||
export type OnboardingState = { |
|||
stepIndex: number, |
|||
stepName: string, // TODO: specify that the string comes from Steps type
|
|||
steps: Step[], |
|||
} |
|||
|
|||
const state: OnboardingState = { |
|||
stepIndex: 0, |
|||
stepName: 'start', |
|||
steps: [ |
|||
{ |
|||
name: 'start', |
|||
external: true, |
|||
options: { |
|||
showFooter: false, |
|||
showBackground: true, |
|||
showBreadcrumb: false, |
|||
}, |
|||
}, |
|||
{ |
|||
name: 'init', |
|||
external: true, |
|||
options: { |
|||
showFooter: false, |
|||
showBackground: true, |
|||
showBreadcrumb: false, |
|||
}, |
|||
}, |
|||
{ |
|||
name: 'chooseDevice', |
|||
label: 'chooseDevice:translated', |
|||
options: { |
|||
showFooter: false, |
|||
showBackground: true, |
|||
showBreadcrumb: true, |
|||
}, |
|||
}, |
|||
{ |
|||
name: 'choosePIN', |
|||
label: 'choosePIN:translated', |
|||
options: { |
|||
showFooter: false, |
|||
showBackground: true, |
|||
showBreadcrumb: true, |
|||
}, |
|||
}, |
|||
{ |
|||
name: 'writeSeed', |
|||
label: 'writeSeed:translated', |
|||
options: { |
|||
showFooter: false, |
|||
showBackground: true, |
|||
showBreadcrumb: true, |
|||
}, |
|||
}, |
|||
{ |
|||
name: 'genuineCheck', |
|||
label: 'genuineCheck:translated', |
|||
options: { |
|||
showFooter: false, |
|||
showBackground: true, |
|||
showBreadcrumb: true, |
|||
}, |
|||
}, |
|||
{ |
|||
name: 'setPassword', |
|||
label: 'Password:translated', |
|||
options: { |
|||
showFooter: false, |
|||
showBackground: true, |
|||
showBreadcrumb: true, |
|||
}, |
|||
}, |
|||
{ |
|||
name: 'analytics', |
|||
label: 'Analytics & Bug report:translated', |
|||
options: { |
|||
showFooter: false, |
|||
showBackground: true, |
|||
showBreadcrumb: true, |
|||
}, |
|||
}, |
|||
{ |
|||
name: 'finish', |
|||
external: true, |
|||
options: { |
|||
showFooter: false, |
|||
showBackground: true, |
|||
showBreadcrumb: false, |
|||
}, |
|||
}, |
|||
], |
|||
} |
|||
|
|||
const handlers = { |
|||
ONBOARDING_NEXT_STEP: state => { |
|||
const step = state.steps.find(step => step.name === state.stepName) |
|||
if (!step) { |
|||
return state |
|||
} |
|||
const index = state.steps.indexOf(step) |
|||
if (index > state.steps.length - 2) { |
|||
return state |
|||
} |
|||
return { ...state, stepName: state.steps[index + 1].name, stepIndex: index + 1 } |
|||
}, |
|||
ONBOARDING_PREV_STEP: state => { |
|||
const step = state.steps.find(step => step.name === state.stepName) |
|||
if (!step) { |
|||
return state |
|||
} |
|||
const index = state.steps.indexOf(step) |
|||
if (index < 1) { |
|||
return state |
|||
} |
|||
return { ...state, stepName: state.steps[index - 1].name, stepIndex: index - 1 } |
|||
}, |
|||
ONBOARDING_JUMP_STEP: (state, { payload: stepName }) => { |
|||
const step = state.steps.find(step => step.name === stepName) |
|||
if (!step) { |
|||
return state |
|||
} |
|||
const index = state.steps.indexOf(step) |
|||
return { ...state, stepName: step.name, stepIndex: index } |
|||
}, |
|||
} |
|||
|
|||
export default handleActions(handlers, state) |
|||
|
|||
export const nextStep = createAction('ONBOARDING_NEXT_STEP') |
|||
export const prevStep = createAction('ONBOARDING_PREV_STEP') |
|||
export const jumpStep = createAction('ONBOARDING_JUMP_STEP') |
Loading…
Reference in new issue