Browse Source

Use react-router for switch tab in SettingsPage

master
Loëck Vézien 7 years ago
committed by meriadec
parent
commit
88862249ce
No known key found for this signature in database GPG Key ID: 1D2FC2305E2CB399
  1. 3
      src/components/SelectAccount/index.js
  2. 60
      src/components/SelectCurrency/index.js
  3. 31
      src/components/SelectCurrency/stories.js
  4. 31
      src/components/SettingsPage/SettingsSection.js
  5. 82
      src/components/SettingsPage/index.js
  6. 21
      src/components/SettingsPage/sections/Currencies.js
  7. 10
      src/components/SideBar/Item.js
  8. 10
      src/components/TopBar.js
  9. 19
      src/components/base/Button/index.js
  10. 1
      src/components/base/CheckBox/index.js
  11. 1
      src/components/layout/Default.js
  12. 1
      static/i18n/en/common.yml

3
src/components/SelectAccount/index.js

@ -3,9 +3,10 @@
import React from 'react'
import { connect } from 'react-redux'
import { translate } from 'react-i18next'
import noop from 'lodash/noop'
import { getIconByCoinType } from '@ledgerhq/currencies/react'
import noop from 'lodash/noop'
import type { Account } from '@ledgerhq/wallet-common/lib/types'
import type { T } from 'types/common'

60
src/components/SelectCurrency/index.js

@ -0,0 +1,60 @@
// @flow
import React from 'react'
import { translate } from 'react-i18next'
import { getIconByCoinType } from '@ledgerhq/currencies/react'
import { listCurrencies } from '@ledgerhq/currencies'
import noop from 'lodash/noop'
import type { Currency } from '@ledgerhq/currencies'
import type { T } from 'types/common'
import Select from 'components/base/Select'
import Box from 'components/base/Box'
const renderItem = a => {
const { color, name, coinType } = a
const Icon = getIconByCoinType(coinType)
return (
<Box grow horizontal alignItems="center" flow={2}>
{Icon && (
<Box style={{ width: 16, height: 16, color }}>
<Icon size={16} />
</Box>
)}
<Box grow ff="Open Sans|SemiBold" color="dark" fontSize={4}>
{name}
</Box>
</Box>
)
}
const currencies = listCurrencies()
type Props = {
onChange: Function,
value?: Currency,
t: T,
}
const SelectCurrency = ({ onChange, value, t, ...props }: Props) => (
<Select
{...props}
value={value}
renderSelected={renderItem}
renderItem={renderItem}
keyProp="coinType"
items={currencies.sort((a, b) => (a.name < b.name ? -1 : 1))}
placeholder={t('common:selectCurrency')}
fontSize={4}
onChange={onChange}
/>
)
SelectCurrency.defaultProps = {
onChange: noop,
value: undefined,
}
export default translate()(SelectCurrency)

31
src/components/SelectCurrency/stories.js

@ -0,0 +1,31 @@
// @flow
import React, { Component } from 'react'
import { storiesOf } from '@storybook/react'
import { action } from '@storybook/addon-actions'
import SelectCurrency from 'components/SelectCurrency'
const stories = storiesOf('Components', module)
class Wrapper extends Component<any, any> {
state = {
value: '',
}
handleChange = item => {
this.setState({ value: item })
action('onChange')(item)
}
render() {
const { render } = this.props
const { value } = this.state
return render({ onChange: this.handleChange, value })
}
}
stories.add('SelectCurrency', () => (
<Wrapper render={({ onChange, value }) => <SelectCurrency onChange={onChange} value={value} />} />
))

31
src/components/SettingsPage/SettingsSection.js

@ -31,7 +31,16 @@ const RoundIconContainer = styled(Box).attrs({
export const SettingsSectionBody = styled(Box)`
> * + * {
border-top: 1px solid ${p => p.theme.colors.lightFog};
&:after {
background: ${p => p.theme.colors.lightFog};
content: '';
display: block;
height: 1px;
left: ${p => p.theme.space[4]}px;
position: absolute;
right: ${p => p.theme.space[4]}px;
top: 0;
}
}
`
@ -39,15 +48,17 @@ export function SettingsSectionHeader({
title,
desc,
icon,
renderRight,
}: {
title: string,
desc: string,
icon: any,
renderRight?: any,
}) {
return (
<SettingsSectionHeaderContainer>
<RoundIconContainer mr={3}>{icon}</RoundIconContainer>
<Box>
<Box grow>
<Box ff="Museo Sans|Regular" color="dark">
{title}
</Box>
@ -55,11 +66,25 @@ export function SettingsSectionHeader({
{desc}
</Box>
</Box>
{renderRight && (
<Box alignItems="center" justifyContent="flex-end">
{renderRight}
</Box>
)}
</SettingsSectionHeaderContainer>
)
}
const SettingsSectionRowContainer = styled(Box).attrs({ p: 4, horizontal: true, align: 'center' })`
SettingsSectionHeader.defaultProps = {
renderRight: undefined,
}
const SettingsSectionRowContainer = styled(Box).attrs({
p: 4,
horizontal: true,
align: 'center',
relative: true,
})`
cursor: ${p => (p.onClick ? 'pointer' : '')};
`

82
src/components/SettingsPage/index.js

@ -4,7 +4,9 @@ import React, { PureComponent } from 'react'
import { compose } from 'redux'
import { connect } from 'react-redux'
import { translate } from 'react-i18next'
import { Switch, Route } from 'react-router'
import type { RouterHistory, Match } from 'react-router'
import type { Settings, T } from 'types/common'
import type { SaveSettings } from 'actions/settings'
import type { FetchCounterValues } from 'actions/counterValues'
@ -30,27 +32,57 @@ const mapDispatchToProps = {
}
type Props = {
fetchCounterValues: FetchCounterValues,
history: RouterHistory,
i18n: Object,
match: Match,
saveSettings: SaveSettings,
settings: Settings,
fetchCounterValues: FetchCounterValues,
t: T,
}
type State = {
tab: number,
tab: Object,
}
class SettingsPage extends PureComponent<Props, State> {
state = {
tab: 0,
constructor(props) {
super(props)
this._items = [
{
key: 'display',
label: props.t('settings:tabs.display'),
value: p => () => <SectionDisplay {...p} />,
},
{
key: 'currencies',
label: props.t('settings:tabs.currencies'),
value: p => () => <SectionCurrencies {...p} />,
},
{
key: 'profile',
label: props.t('settings:tabs.profile'),
value: p => () => <SectionProfile {...p} />,
},
{
key: 'about',
label: props.t('settings:tabs.about'),
value: p => () => <SectionAbout {...p} />,
},
]
this.state = {
tab: this._items[0],
}
}
_items = []
handleChangeTab = (item: any) => {
const tab = this._items.indexOf(item)
this.setState({ tab })
const { match, history } = this.props
history.push(`${match.url}/${item.key}`)
this.setState({ tab: item })
}
handleSaveSettings = newSettings => {
@ -64,47 +96,29 @@ class SettingsPage extends PureComponent<Props, State> {
}
render() {
const { settings, t, i18n, saveSettings } = this.props
const { match, settings, t, i18n, saveSettings } = this.props
const { tab } = this.state
const props = {
t,
settings,
saveSettings,
i18n,
}
this._items = [
{
key: 'display',
label: t('settings:tabs.display'),
value: () => <SectionDisplay {...props} i18n={i18n} />,
},
{
key: 'currencies',
label: t('settings:tabs.currencies'),
value: () => <SectionCurrencies {...props} />,
},
{
key: 'profile',
label: t('settings:tabs.profile'),
value: () => <SectionProfile {...props} />,
},
{
key: 'about',
label: t('settings:tabs.about'),
value: () => <SectionAbout {...props} />,
},
]
const item = this._items[tab]
const defaultItem = this._items[0]
return (
<Box>
<Box ff="Museo Sans|Regular" color="dark" fontSize={7} mb={5}>
{t('settings:title')}
</Box>
<Pills mb={4} items={this._items} activeKey={item.key} onChange={this.handleChangeTab} />
{item.value && item.value()}
<Pills mb={4} items={this._items} activeKey={tab.key} onChange={this.handleChangeTab} />
<Switch>
{this._items.map(i => (
<Route key={i.key} path={`${match.url}/${i.key}`} render={i.value && i.value(props)} />
))}
<Route render={defaultItem.value && defaultItem.value(props)} />
</Switch>
</Box>
)
}

21
src/components/SettingsPage/sections/Currencies.js

@ -2,8 +2,13 @@
import React, { PureComponent } from 'react'
import { listCurrencies } from '@ledgerhq/currencies'
import type { Currency } from '@ledgerhq/currencies'
import type { T } from 'types/common'
import SelectCurrency from 'components/SelectCurrency'
import IconCurrencies from 'icons/Currencies'
import {
@ -17,15 +22,29 @@ type Props = {
t: T,
}
class TabCurrencies extends PureComponent<Props> {
type State = {
currency: Currency,
}
class TabCurrencies extends PureComponent<Props, State> {
state = {
currency: listCurrencies()[0],
}
handleChangeCurrency = currency => this.setState({ currency })
render() {
const { t } = this.props
const { currency } = this.state
return (
<Section>
<Header
icon={<IconCurrencies size={16} />}
title={t('settings:tabs.currencies')}
desc="Lorem ipsum dolor sit amet"
renderRight={
<SelectCurrency small value={currency} onChange={this.handleChangeCurrency} />
}
/>
<Body>
<Row

10
src/components/SideBar/Item.js

@ -3,7 +3,7 @@
import React from 'react'
import styled from 'styled-components'
import { compose } from 'redux'
import { withRouter } from 'react-router'
import { matchPath, withRouter } from 'react-router'
import { push } from 'react-router-redux'
import { connect } from 'react-redux'
@ -77,7 +77,13 @@ function Item({
openModal,
}: Props) {
const { pathname } = location
const isActive = pathname === linkTo
const isActive = linkTo
? linkTo === '/'
? linkTo === pathname
: matchPath(pathname, {
path: linkTo,
})
: false
return (
<Container
big={big}

10
src/components/TopBar.js

@ -5,8 +5,10 @@ import { compose } from 'redux'
import { translate } from 'react-i18next'
import { connect } from 'react-redux'
import styled from 'styled-components'
import { withRouter } from 'react-router'
import { ipcRenderer } from 'electron'
import type { RouterHistory } from 'react-router'
import type { T } from 'types/common'
import { rgba } from 'styles/helpers'
@ -85,6 +87,7 @@ const mapDispatchToProps = {
}
type Props = {
history: RouterHistory,
t: T,
hasAccounts: boolean,
hasPassword: boolean,
@ -147,7 +150,7 @@ class TopBar extends PureComponent<Props, State> {
handleLock = () => this.props.lock()
render() {
const { hasPassword, hasAccounts, username, t } = this.props
const { hasPassword, history, hasAccounts, username, t } = this.props
const { sync } = this.state
return (
@ -173,6 +176,7 @@ class TopBar extends PureComponent<Props, State> {
key: 'profile',
label: t('common:editProfile'),
icon: <IconUser size={16} />,
onClick: () => history.push('/settings/profile'),
},
...(hasPassword
? [
@ -209,4 +213,6 @@ class TopBar extends PureComponent<Props, State> {
}
}
export default compose(connect(mapStateToProps, mapDispatchToProps), translate())(TopBar)
export default compose(withRouter, connect(mapStateToProps, mapDispatchToProps), translate())(
TopBar,
)

19
src/components/base/Button/index.js

@ -12,26 +12,26 @@ import fontFamily from 'styles/styled/fontFamily'
const buttonStyles = {
primary: {
default: p => `
background: ${p.disabled ? lighten(p.theme.colors.wallet, 0.1) : p.theme.colors.wallet};
color: white;
background: ${p.disabled ? p.theme.colors.lightFog : p.theme.colors.wallet};
color: ${p.disabled ? p.theme.colors.grey : p.theme.colors.white};
`,
hover: p => `
background: ${lighten(p.theme.colors.wallet, 0.05)};
background: ${darken(p.theme.colors.wallet, 0.05)};
`,
active: p => `
background: ${darken(p.theme.colors.wallet, 0.1)};
background: ${darken(p.theme.colors.wallet, 0.05)};
`,
},
danger: {
default: p => `
background: ${p.disabled ? lighten(p.theme.colors.alertRed, 0.3) : p.theme.colors.alertRed};
color: white;
background: ${p.disabled ? p.theme.colors.lightFog : p.theme.colors.alertRed};
color: ${p.disabled ? p.theme.colors.grey : p.theme.colors.white};
`,
hover: p => `
background: ${lighten(p.theme.colors.alertRed, 0.1)};
background: ${lighten(p.theme.colors.alertRed, 0.2)};
`,
active: p => `
background: ${darken(p.theme.colors.alertRed, 0.1)};
background: ${lighten(p.theme.colors.alertRed, 0.2)};
`,
},
outline: {
@ -87,7 +87,8 @@ const Base = styled.button.attrs({
outline: none;
${p => getStyles(p, 'default')};
&:hover {
&:hover,
&:focus {
${p => getStyles(p, 'hover')};
}
&:active {

1
src/components/base/CheckBox/index.js

@ -18,7 +18,6 @@ const Base = styled(Tabbable).attrs({
transition: 250ms linear background-color;
cursor: pointer;
&:focus {
box-shadow: rgba(0, 0, 0, 0.1) 0 2px 2px;
outline: none;
}
`

1
src/components/layout/Default.js

@ -6,6 +6,7 @@ import { ipcRenderer } from 'electron'
import styled from 'styled-components'
import { Route, withRouter } from 'react-router'
import { translate } from 'react-i18next'
import type { Location } from 'react-router'
import * as modals from 'components/modals'

1
static/i18n/en/common.yml

@ -4,6 +4,7 @@ cancel: Cancel
chooseWalletPlaceholder: Choose a wallet...
currency: Currency
selectAccount: Select an account
selectCurrency: Select an currency
sortBy: Sort by
search: Search
save: Save

Loading…
Cancel
Save