Browse Source

Create new `ImportAccounts` modal

master
meriadec 7 years ago
parent
commit
3a29466b03
No known key found for this signature in database GPG Key ID: 1D2FC2305E2CB399
  1. 2
      src/components/SideBar/Item.js
  2. 72
      src/components/SideBar/index.js
  3. 145
      src/components/modals/ImportAccounts/index.js
  4. 22
      src/components/modals/ImportAccounts/steps/01-step-choose-currency.js
  5. 33
      src/components/modals/ImportAccounts/steps/02-step-connect-device.js
  6. 11
      src/components/modals/ImportAccounts/steps/03-step-in-progress.js
  7. 11
      src/components/modals/ImportAccounts/steps/04-step-finish.js
  8. 2
      src/components/modals/StepConnectDevice.js
  9. 2
      src/components/modals/index.js
  10. 2
      src/icons/Home.js
  11. 6
      static/i18n/en/importAccounts.yml

2
src/components/SideBar/Item.js

@ -34,7 +34,7 @@ const Container = styled(Tabbable).attrs({
horizontal: true,
pl: 3,
})`
cursor: pointer;
cursor: ${p => (p.isActive ? 'default' : 'pointer')};
color: ${p => p.theme.colors.dark};
background: ${p => (p.isActive ? p.theme.colors.lightGrey : '')};
height: ${p => (p.big ? 50 : 36)}px;

72
src/components/SideBar/index.js

@ -1,6 +1,6 @@
// @flow
import React, { PureComponent } from 'react'
import React, { PureComponent, Fragment } from 'react'
import { compose } from 'redux'
import { translate } from 'react-i18next'
import styled from 'styled-components'
@ -8,7 +8,7 @@ import { connect } from 'react-redux'
import { getCryptoCurrencyIcon } from '@ledgerhq/live-common/lib/react'
import type { Account } from '@ledgerhq/live-common/lib/types'
import { MODAL_SEND, MODAL_RECEIVE, MODAL_ADD_ACCOUNT } from 'config/constants'
import { MODAL_SEND, MODAL_RECEIVE } from 'config/constants'
import type { T } from 'types/common'
@ -56,7 +56,6 @@ const PlusBtn = styled(Tabbable).attrs({
type Props = {
t: T,
accounts: Account[],
openModal: Function,
updateStatus: UpdateStatus,
}
@ -72,7 +71,7 @@ const mapDispatchToProps: Object = {
class SideBar extends PureComponent<Props> {
render() {
const { t, accounts, openModal, updateStatus } = this.props
const { t, openModal, updateStatus } = this.props
return (
<Container bg="white">
@ -101,35 +100,13 @@ class SideBar extends PureComponent<Props> {
<CapsSubtitle horizontal alignItems="center">
<Box grow>{t('sidebar:accounts')}</Box>
<Tooltip render={() => t('addAccount:title')}>
<PlusBtn onClick={() => openModal(MODAL_ADD_ACCOUNT)}>
<PlusBtn onClick={() => openModal('importAccounts')}>
<IconPlus size={16} />
</PlusBtn>
</Tooltip>
</CapsSubtitle>
<GrowScroll pb={4} px={4} flow={2}>
{accounts.map(account => {
const Icon = getCryptoCurrencyIcon(account.currency)
return (
<Item
big
desc={
<FormattedVal
alwaysShowSign={false}
color="graphite"
unit={account.unit}
showCode
val={account.balance || 0}
/>
}
iconActiveColor={account.currency.color}
icon={Icon ? <Icon size={16} /> : null}
key={account.id}
linkTo={`/account/${account.id}`}
>
{account.name}
</Item>
)
})}
<AccountsList />
</GrowScroll>
</Box>
</Box>
@ -138,9 +115,36 @@ class SideBar extends PureComponent<Props> {
}
}
export default compose(
connect(mapStateToProps, mapDispatchToProps, null, {
pure: false,
}),
translate(),
)(SideBar)
const AccountsList = connect(state => ({
accounts: getVisibleAccounts(state),
}))(({ accounts }: { accounts: Account[] }) => (
<Fragment>
{accounts.map(account => {
const Icon = getCryptoCurrencyIcon(account.currency)
return (
<Item
big
desc={
<FormattedVal
alwaysShowSign={false}
color="graphite"
unit={account.unit}
showCode
val={account.balance || 0}
/>
}
iconActiveColor={account.currency.color}
icon={Icon ? <Icon size={16} /> : null}
key={account.id}
linkTo={`/account/${account.id}`}
>
{account.name}
</Item>
)
})}
</Fragment>
))
export default compose(connect(null, mapDispatchToProps, null, { pure: false }), translate())(
SideBar,
)

145
src/components/modals/ImportAccounts/index.js

@ -0,0 +1,145 @@
// @flow
import React, { PureComponent } from 'react'
import { compose } from 'redux'
import { connect } from 'react-redux'
import { translate } from 'react-i18next'
import type { Currency } from '@ledgerhq/live-common/lib/types'
import type { T, Device } from 'types/common'
import { getCurrentDevice } from 'reducers/devices'
import Modal, { ModalContent, ModalTitle, ModalFooter, ModalBody } from 'components/base/Modal'
import Box from 'components/base/Box'
import Breadcrumb from 'components/Breadcrumb'
import StepChooseCurrency, { StepChooseCurrencyFooter } from './steps/01-step-choose-currency'
import StepConnectDevice, { StepConnectDeviceFooter } from './steps/02-step-connect-device'
import StepInProgress from './steps/03-step-in-progress'
import StepFinish from './steps/04-step-finish'
const createSteps = ({ t }: { t: T }) => [
{
id: 'chooseCurrency',
label: t('importAccounts:breadcrumb.informations'),
component: StepChooseCurrency,
footer: StepChooseCurrencyFooter,
hideFooter: false,
},
{
id: 'connectDevice',
label: t('importAccounts:breadcrumb.connectDevice'),
component: StepConnectDevice,
footer: StepConnectDeviceFooter,
hideFooter: false,
},
{
id: 'import',
label: t('importAccounts:breadcrumb.import'),
component: StepInProgress,
footer: null,
hideFooter: true,
},
{
id: 'finish',
label: t('importAccounts:breadcrumb.finish'),
component: StepFinish,
hideFooter: false,
footer: StepChooseCurrencyFooter,
},
]
type Props = {
t: T,
currentDevice: ?Device,
}
type StepId = 'chooseCurrency' | 'connectDevice' | 'import' | 'finish'
export type StepProps = {
t: T,
currency: ?Currency,
currentDevice: ?Device,
isAppOpened: boolean,
transitionTo: StepId => void,
setState: any => void,
}
type State = {
stepId: StepId,
isAppOpened: boolean,
currency: ?Currency,
scannedAccounts: [],
}
const mapStateToProps = state => ({
currentDevice: getCurrentDevice(state),
})
const INITIAL_STATE = {
stepId: 'chooseCurrency',
isAppOpened: false,
currency: null,
scannedAccounts: [],
}
class ImportAccounts extends PureComponent<Props, State> {
state = INITIAL_STATE
STEPS = createSteps({
t: this.props.t,
})
transitionTo = stepId => {
this.setState({ stepId })
}
render() {
const { t, currentDevice } = this.props
const { stepId, currency, isAppOpened } = this.state
const stepIndex = this.STEPS.findIndex(s => s.id === stepId)
const step = this.STEPS[stepIndex]
if (!step) {
throw new Error(`ImportAccountsModal: step ${stepId} doesn't exists`)
}
const { component: StepComponent, footer: StepFooter, hideFooter } = step
const stepProps: StepProps = {
t,
currency,
currentDevice,
isAppOpened,
transitionTo: this.transitionTo,
setState: (...args) => this.setState(...args),
}
return (
<Modal
name="importAccounts"
preventBackdropClick
onHide={() => this.setState({ ...INITIAL_STATE })}
render={({ onClose }) => (
<ModalBody onClose={onClose}>
<ModalTitle>{t('importAccounts:title')}</ModalTitle>
<ModalContent>
<Breadcrumb mb={6} currentStep={stepIndex} items={this.STEPS} />
<StepComponent {...stepProps} />
</ModalContent>
{!hideFooter && (
<ModalFooter>
<Box horizontal alignItems="center" justifyContent="flex-end">
{StepFooter ? <StepFooter {...stepProps} /> : <Box>footer</Box>}
</Box>
</ModalFooter>
)}
</ModalBody>
)}
/>
)
}
}
export default compose(connect(mapStateToProps), translate())(ImportAccounts)

22
src/components/modals/ImportAccounts/steps/01-step-choose-currency.js

@ -0,0 +1,22 @@
// @flow
import React from 'react'
import SelectCurrency from 'components/SelectCurrency'
import Button from 'components/base/Button'
import type { StepProps } from '../index'
function StepChooseCurrency({ currency, setState }: StepProps) {
return <SelectCurrency onChange={currency => setState({ currency })} value={currency} />
}
export function StepChooseCurrencyFooter({ transitionTo, currency, t }: StepProps) {
return (
<Button primary disabled={!currency} onClick={() => transitionTo('connectDevice')}>
{t('common:next')}
</Button>
)
}
export default StepChooseCurrency

33
src/components/modals/ImportAccounts/steps/02-step-connect-device.js

@ -0,0 +1,33 @@
// @flow
import React from 'react'
import Button from 'components/base/Button'
import ConnectDevice from 'components/modals/StepConnectDevice'
import type { StepProps } from '../index'
function StepConnectDevice({ t, currency, currentDevice, setState }: StepProps) {
return (
<ConnectDevice
t={t}
deviceSelected={currentDevice}
currency={currency}
onStatusChange={s => {
if (s === 'connected') {
setState({ isAppOpened: true })
}
}}
/>
)
}
export function StepConnectDeviceFooter({ t, transitionTo, isAppOpened }: StepProps) {
return (
<Button primary disabled={!isAppOpened} onClick={() => transitionTo('import')}>
{t('common:next')}
</Button>
)
}
export default StepConnectDevice

11
src/components/modals/ImportAccounts/steps/03-step-in-progress.js

@ -0,0 +1,11 @@
// @flow
import React from 'react'
import Box from 'components/base/Box'
function StepInProgress() {
return <Box>{'StepInProgress'}</Box>
}
export default StepInProgress

11
src/components/modals/ImportAccounts/steps/04-step-finish.js

@ -0,0 +1,11 @@
// @flow
import React from 'react'
import Box from 'components/base/Box'
function StepFinish() {
return <Box>{'StepFinish'}</Box>
}
export default StepFinish

2
src/components/modals/StepConnectDevice.js

@ -13,7 +13,7 @@ type Props = {
account?: ?Account,
currency?: ?CryptoCurrency,
deviceSelected?: ?Device,
onChangeDevice: Device => void,
onChangeDevice?: Device => void,
onStatusChange: string => void,
}

2
src/components/modals/index.js

@ -1,5 +1,5 @@
export Debug from './Debug'
export AddAccount from './AddAccount'
export ImportAccounts from './ImportAccounts'
export OperationDetails from './OperationDetails'
export Receive from './Receive'
export Send from './Send'

2
src/icons/Home.js

@ -3,7 +3,7 @@
import React from 'react'
const path = (
<path d="m8.261 2.252a1.11 1.11 0 0 0-1.408 0l-6.772 5.545a0.224 0.224 0 0 0-0.03 0.313l0.563 0.69a0.224 0.224 0 0 0 0.314 0.03l0.408-0.333v5.502c0 0.245 0.2 0.445 0.445 0.445h4.667c0.122 0 0.222-0.1 0.222-0.222v-3.556h1.778v3.556c0 0.122 0.1 0.222 0.222 0.222h4.666c0.245 0 0.445-0.2 0.445-0.445v-5.505l0.408 0.333a0.224 0.224 0 0 0 0.314-0.03l0.564-0.69a0.227 0.227 0 0 0-0.036-0.31l-6.771-5.545zm4.184 10.858h-2.667v-3.555c0-0.122-0.1-0.222-0.222-0.222h-4c-0.122 0-0.222 0.1-0.222 0.222v3.555h-2.667v-5.708l4.747-3.889c0.08-0.066 0.2-0.066 0.28 0l4.748 3.89v5.707z"/>
<path d="m8.261 2.252a1.11 1.11 0 0 0-1.408 0l-6.772 5.545a0.224 0.224 0 0 0-0.03 0.313l0.563 0.69a0.224 0.224 0 0 0 0.314 0.03l0.408-0.333v5.502c0 0.245 0.2 0.445 0.445 0.445h4.667c0.122 0 0.222-0.1 0.222-0.222v-3.556h1.778v3.556c0 0.122 0.1 0.222 0.222 0.222h4.666c0.245 0 0.445-0.2 0.445-0.445v-5.505l0.408 0.333a0.224 0.224 0 0 0 0.314-0.03l0.564-0.69a0.227 0.227 0 0 0-0.036-0.31l-6.771-5.545zm4.184 10.858h-2.667v-3.555c0-0.122-0.1-0.222-0.222-0.222h-4c-0.122 0-0.222 0.1-0.222 0.222v3.555h-2.667v-5.708l4.747-3.889c0.08-0.066 0.2-0.066 0.28 0l4.748 3.89v5.707z" />
)
export default ({ size, ...p }: { size: number }) => (

6
static/i18n/en/importAccounts.yml

@ -0,0 +1,6 @@
title: Import accounts
breadcrumb:
informations: Informations
connectDevice: Connect device
import: Import accounts
finish: Confirm
Loading…
Cancel
Save