diff --git a/.eslintrc b/.eslintrc index 8771a924..9cac6933 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,6 +7,7 @@ "__DEV__": false, "__PROD__": false, "__static": false, + "window": false, }, "rules": { "camelcase": 0, diff --git a/src/components/SettingsPage.js b/src/components/SettingsPage/Profile.js similarity index 96% rename from src/components/SettingsPage.js rename to src/components/SettingsPage/Profile.js index 9cc1dbb0..9a9790c8 100644 --- a/src/components/SettingsPage.js +++ b/src/components/SettingsPage/Profile.js @@ -16,7 +16,7 @@ import type { Settings } from 'types/common' import { saveSettings } from 'actions/settings' import { unlock } from 'reducers/application' -import Box from 'components/base/Box' +import Box, { Card } from 'components/base/Box' import Input from 'components/base/Input' import Button from 'components/base/Button' @@ -93,11 +93,9 @@ class SettingsPage extends PureComponent { render() { const { inputValue } = this.state - return (
- - {'settings'} + { - + ) } diff --git a/src/components/SettingsPage/index.js b/src/components/SettingsPage/index.js new file mode 100644 index 00000000..328c3695 --- /dev/null +++ b/src/components/SettingsPage/index.js @@ -0,0 +1,76 @@ +// @flow + +import React, { PureComponent } from 'react' + +import Box from 'components/base/Box' +import Text from 'components/base/Text' +import Tabs from 'components/base/Tabs' + +import TabProfile from './Profile' + +type Props = {} + +type State = { + tab: number, +} + +class SettingsPage extends PureComponent { + state = { + tab: 6, + } + + handleChangeTab = (tab: number) => this.setState({ tab }) + + render() { + const { tab } = this.state + + return ( + + {'Settings'} +
{'Affichage'}
, + }, + { + key: 'money', + title: 'Monnaie', + render: () =>
{'Monnaie'}
, + }, + { + key: 'material', + title: 'Matériel', + render: () =>
{'Matériel'}
, + }, + { + key: 'app', + title: 'App (beta)', + render: () =>
{'App (beta)'}
, + }, + { + key: 'tools', + title: 'Outils', + render: () =>
{'Outils'}
, + }, + { + key: 'blockchain', + title: 'Blockchain', + render: () =>
{'Blockchain'}
, + }, + { + key: 'profile', + title: 'Profil', + render: () => , + }, + ]} + /> +
+ ) + } +} + +export default SettingsPage diff --git a/src/components/SideBar/Item.js b/src/components/SideBar/Item.js index 0c7d4f31..0e177da9 100644 --- a/src/components/SideBar/Item.js +++ b/src/components/SideBar/Item.js @@ -46,7 +46,11 @@ const Container = styled(Box).attrs({ p: 2, })` cursor: pointer; - color: ${p => (p.active ? p.theme.colors.white : '')}; + color: ${p => (p.isActive ? p.theme.colors.white : '')}; + background: ${p => (p.isActive ? 'rgba(255, 255, 255, 0.05)' : '')}; + box-shadow: ${p => + p.isActive ? `${p.theme.colors.blue} 4px 0 0 inset` : `${p.theme.colors.blue} 0 0 0 inset`}; + transition: ease-in-out 100ms box-shadow; &:hover { background: rgba(255, 255, 255, 0.05); @@ -54,9 +58,9 @@ const Container = styled(Box).attrs({ ` const IconWrapper = styled(Box)` - width: 30px; - height: 30px; - border: 2px solid rgba(255, 255, 255, 0.1); + width: 25px; + height: 25px; + border: 2px solid ${p => (p.isActive ? p.theme.colors.blue : 'rgba(255, 255, 255, 0.1)')}; ` function Item({ @@ -71,15 +75,19 @@ function Item({ isModalOpened, }: Props) { const { pathname } = location - const active = pathname === linkTo || isModalOpened + const isActive = pathname === linkTo || isModalOpened return ( push(linkTo)) : modal ? () => openModal(modal) : void 0 + linkTo + ? isActive ? undefined : () => push(linkTo) + : modal ? () => openModal(modal) : void 0 } - active={active} + isActive={isActive} > - {icon || null} + + {icon || null} +
{children} diff --git a/src/components/base/Box/index.js b/src/components/base/Box/index.js index 7803f153..1764dd5e 100644 --- a/src/components/base/Box/index.js +++ b/src/components/base/Box/index.js @@ -1,6 +1,6 @@ // @flow -import React from 'react' +import React, { PureComponent } from 'react' import styled from 'styled-components' import { alignItems, @@ -59,7 +59,7 @@ const RawCard = styled(Box).attrs({ bg: 'white', p: 3 })` border-radius: 5px; ` -export const Card = ({ title, ...props }: { title: string }) => { +export const Card = ({ title, ...props }: { title?: string }) => { if (title) { return ( @@ -73,10 +73,31 @@ export const Card = ({ title, ...props }: { title: string }) => { return } +Card.defaultProps = { + title: undefined, +} + export const GrowScroll = (props: *) => ( ) +export class Tabbable extends PureComponent { + componentDidMount() { + window.addEventListener('keydown', this.handleKeydown) + } + componentWillUnmount() { + window.removeEventListener('keydown', this.handleKeydown) + } + handleKeydown = (e: SyntheticKeyboardEvent) => { + if (e.which === 13 && this.props.onClick) { + this.props.onClick(e) + } + } + render() { + return + } +} + export default Box diff --git a/src/components/base/Tabs/index.js b/src/components/base/Tabs/index.js new file mode 100644 index 00000000..a8d847ab --- /dev/null +++ b/src/components/base/Tabs/index.js @@ -0,0 +1,51 @@ +// @flow + +import React, { Fragment } from 'react' +import styled from 'styled-components' + +import type { Element } from 'react' + +import Box, { Tabbable } from 'components/base/Box' + +const Tab = styled(Tabbable).attrs({ + flex: 1, + pb: 1, + align: 'center', + justify: 'center', + fontSize: 1, +})` + border-bottom: 2px solid transparent; + border-bottom-color: ${p => (p.isActive ? p.theme.colors.blue : '')}; + color: ${p => (p.isActive ? p.theme.colors.blue : p.theme.colors.steel)}; + font-weight: ${p => (p.isActive ? 'bold' : '')}; + margin-bottom: -1px; + outline: none; + cursor: ${p => (p.isActive ? 'default' : 'pointer')}; +` + +type Item = { + key: string | number, + title: string | Element, + render: () => Element, +} + +type Props = { + items: Array, + index: number, + onTabClick: number => void, +} + +const Tabs = ({ items, index, onTabClick }: Props) => ( + + + {items.map((item, i) => ( + onTabClick(i)}> + {item.title} + + ))} + + {items[index] && items[index].render()} + +) + +export default Tabs diff --git a/src/components/base/Tabs/stories.js b/src/components/base/Tabs/stories.js new file mode 100644 index 00000000..5cbb22b7 --- /dev/null +++ b/src/components/base/Tabs/stories.js @@ -0,0 +1,28 @@ +import React from 'react' + +import { number } from '@storybook/addon-knobs' +import { action } from '@storybook/addon-actions' +import { storiesOf } from '@storybook/react' + +import Tabs from 'components/base/Tabs' + +const stories = storiesOf('Tabs', module) + +stories.add('basic', () => ( +
{'first tab content'}
, + }, + { + key: 'second', + title: 'second tab', + render: () =>
{'second tab content'}
, + }, + ]} + /> +)) diff --git a/src/styles/theme.js b/src/styles/theme.js index 9631ddc4..a4a8f46d 100644 --- a/src/styles/theme.js +++ b/src/styles/theme.js @@ -6,6 +6,7 @@ export default { white: '#ffffff', argile: '#eeeeee', + blue: '#6193ff', cream: '#f9f9f9', grenade: '#ea2e49', lead: '#999999',