Browse Source

Merge pull request #122 from loeck/master

Clean design, sort accounts on add
master
Meriadec Pillet 7 years ago
committed by GitHub
parent
commit
a2f1a85e4f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 43
      src/actions/accounts.js
  2. 42
      src/components/DashboardPage/index.js
  3. 28
      src/components/TopBar.js
  4. 7
      src/components/base/DropDown/index.js
  5. 16
      src/components/base/GrowScroll/index.js
  6. 6
      src/components/base/Pills/index.js
  7. 10
      src/icons/AngleDown.js

43
src/actions/accounts.js

@ -22,11 +22,27 @@ function sortAccounts(accounts, orderAccounts) {
return accountsSorted return accountsSorted
} }
export type AddAccount = Account => { type: string, payload: Account } export type UpdateOrderAccounts = string => (Dispatch<*>, Function) => void
export const addAccount: AddAccount = payload => ({ export const updateOrderAccounts: UpdateOrderAccounts = (orderAccounts: string) => (
type: 'DB:ADD_ACCOUNT', dispatch,
payload, getState,
}) ) => {
const { accounts } = getState()
dispatch({
type: 'DB:SET_ACCOUNTS',
payload: sortAccounts(accounts, orderAccounts),
})
}
export type AddAccount = Account => (Function, Function) => void
export const addAccount: AddAccount = payload => (dispatch, getState) => {
const { settings: { orderAccounts } } = getState()
dispatch({
type: 'ADD_ACCOUNT',
payload,
})
dispatch(updateOrderAccounts(orderAccounts))
}
export type RemoveAccount = Account => { type: string, payload: Account } export type RemoveAccount = Account => { type: string, payload: Account }
export const removeAccount: RemoveAccount = payload => ({ export const removeAccount: RemoveAccount = payload => ({
@ -44,25 +60,12 @@ export const fetchAccounts: FetchAccounts = () => (dispatch, getState) => {
}) })
} }
export type UpdateOrderAccounts = string => (Dispatch<*>, Function) => void
export const updateOrderAccounts: UpdateOrderAccounts = (orderAccounts: string) => (
dispatch,
getState,
) => {
const { accounts } = getState()
dispatch({
type: 'DB:SET_ACCOUNTS',
payload: sortAccounts(accounts, orderAccounts),
})
}
export type UpdateAccount = Account => (Function, Function) => void export type UpdateAccount = Account => (Function, Function) => void
export const updateAccount: UpdateAccount = payload => (dispatch, getState) => { export const updateAccount: UpdateAccount = payload => (dispatch, getState) => {
const { settings } = getState() const { settings: { orderAccounts } } = getState()
dispatch({ dispatch({
type: 'UPDATE_ACCOUNT', type: 'UPDATE_ACCOUNT',
payload, payload,
}) })
dispatch(updateOrderAccounts(settings.orderAccounts)) dispatch(updateOrderAccounts(orderAccounts))
} }

42
src/components/DashboardPage/index.js

@ -30,6 +30,8 @@ import Text from 'components/base/Text'
import TransactionsList from 'components/TransactionsList' import TransactionsList from 'components/TransactionsList'
import DropDown from 'components/base/DropDown' import DropDown from 'components/base/DropDown'
import IconAngleDown from 'icons/AngleDown'
import AccountCard from './AccountCard' import AccountCard from './AccountCard'
import BalanceInfos from './BalanceInfos' import BalanceInfos from './BalanceInfos'
@ -143,19 +145,21 @@ class DashboardPage extends PureComponent<Props, State> {
addFakeDatasOnAccounts = () => { addFakeDatasOnAccounts = () => {
const { accounts } = this.props const { accounts } = this.props
this._timeout = setTimeout(() => { window.requestAnimationFrame(() => {
window.requestAnimationFrame(() => { this.setState(prev => ({
this.setState(prev => ({ fakeDatas: [
fakeDatas: [ ...accounts.reduce((res, acc, i) => {
...accounts.reduce((res, acc, i) => { if (res[i]) {
if (res[i]) { const nextIndex = res[i].length
const nextIndex = res[i].length res[i][nextIndex] = generateFakeData(nextIndex)
res[i][nextIndex] = generateFakeData(nextIndex) }
} return res
return res }, prev.fakeDatas),
}, prev.fakeDatas), ],
], }))
}))
this._timeout = setTimeout(() => {
this.addFakeDatasOnAccounts()
}, TIMEOUT_REFRESH_DATAS) }, TIMEOUT_REFRESH_DATAS)
}) })
} }
@ -250,8 +254,12 @@ class DashboardPage extends PureComponent<Props, State> {
items={sortItems} items={sortItems}
ff="Open Sans|SemiBold" ff="Open Sans|SemiBold"
fontSize={4} fontSize={4}
value={sortItems.find(s => s.key === orderAccounts)}
> >
<Text color="dark">{t(`orderAccounts.${orderAccounts}`)}</Text> <Box horizontal align="center" flow={1} color="dark">
<Text>{t(`orderAccounts.${orderAccounts}`)}</Text>
<IconAngleDown height={7} width={8} />
</Box>
</DropDown> </DropDown>
</Box> </Box>
</Box> </Box>
@ -282,10 +290,10 @@ class DashboardPage extends PureComponent<Props, State> {
</Box> </Box>
))} ))}
</Box> </Box>
<Card p={0} px={4} title="Recent activity">
<TransactionsList withAccounts transactions={getAllTransactions(accounts)} />
</Card>
</Box> </Box>
<Card p={0} px={4} title="Recent activity">
<TransactionsList withAccounts transactions={getAllTransactions(accounts)} />
</Card>
</Fragment> </Fragment>
)} )}
</Box> </Box>

28
src/components/TopBar.js

@ -14,6 +14,7 @@ import { hasPassword } from 'reducers/settings'
import IconDevices from 'icons/Devices' import IconDevices from 'icons/Devices'
import IconActivity from 'icons/Activity' import IconActivity from 'icons/Activity'
import IconAngleDown from 'icons/AngleDown'
import DropDown from 'components/base/DropDown' import DropDown from 'components/base/DropDown'
import Box from 'components/base/Box' import Box from 'components/base/Box'
@ -44,6 +45,19 @@ const Bar = styled.div`
background: ${p => p.theme.colors.mouse}; background: ${p => p.theme.colors.mouse};
` `
const Activity = styled.div`
background: ${p =>
p.progress === true
? p.theme.colors.dodgerBlue
: p.fail === true ? p.theme.colors.grenade : p.theme.colors.green};
border-radius: 50%;
bottom: 20px;
height: 4px;
position: absolute;
right: -2px;
width: 4px;
`
const mapStateToProps: MapStateToProps<*, *, *> = state => ({ const mapStateToProps: MapStateToProps<*, *, *> = state => ({
hasAccounts: getAccounts(state).length > 0, hasAccounts: getAccounts(state).length > 0,
hasPassword: hasPassword(state), hasPassword: hasPassword(state),
@ -125,18 +139,13 @@ class TopBar extends PureComponent<Props, State> {
<Box justify="center"> <Box justify="center">
<IconDevices height={16} width={16} /> <IconDevices height={16} width={16} />
</Box> </Box>
<Box justify="center"> <Box justify="center" relative>
<IconActivity height={16} width={16} /> <IconActivity height={16} width={16} />
{hasAccounts && <Activity progress={sync.progress} fail={sync.fail} />}
</Box> </Box>
<Box justify="center"> <Box justify="center">
<Bar /> <Bar />
</Box> </Box>
<Box>
{hasAccounts &&
(sync.progress === true
? 'Synchronizing...'
: sync.fail === true ? 'Synchronization fail :(' : 'Synchronisation finished!')}
</Box>
<Box justify="flex-end" horizontal> <Box justify="flex-end" horizontal>
{hasPassword && <LockApplication onLock={this.handleLock} />} {hasPassword && <LockApplication onLock={this.handleLock} />}
</Box> </Box>
@ -147,7 +156,10 @@ class TopBar extends PureComponent<Props, State> {
ff="Open Sans|SemiBold" ff="Open Sans|SemiBold"
fontSize={4} fontSize={4}
> >
{'Khalil Benihoud'} <Box horizontal align="center" flow={1} color="warmGrey">
<Box>{'Khalil Benihoud'}</Box>
<IconAngleDown height={7} width={8} />
</Box>
</DropDown> </DropDown>
</Box> </Box>
</Inner> </Inner>

7
src/components/base/DropDown/index.js

@ -27,14 +27,21 @@ const Trigger = styled(Box)`
const Drop = styled(Box).attrs({ const Drop = styled(Box).attrs({
bg: 'white', bg: 'white',
boxShadow: 0, boxShadow: 0,
borderRadius: 1,
mt: 1,
})` })`
position: absolute; position: absolute;
top: 100%; top: 100%;
right: 0; right: 0;
> * + * {
border-top: 1px solid ${p => p.theme.colors.argile};
}
` `
const Item = styled(Box).attrs({ const Item = styled(Box).attrs({
py: 2, py: 2,
fontSize: 3,
px: 4, px: 4,
bg: p => (p.isHighlighted ? 'pearl' : ''), bg: p => (p.isHighlighted ? 'pearl' : ''),
})` })`

16
src/components/base/GrowScroll/index.js

@ -1,7 +1,10 @@
// @flow // @flow
/* eslint-disable class-methods-use-this */
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import Scrollbar from 'react-smooth-scrollbar' import Scrollbar from 'react-smooth-scrollbar'
import SmoothScrollbar, { ScrollbarPlugin } from 'smooth-scrollbar'
import noop from 'lodash/noop' import noop from 'lodash/noop'
import Box from 'components/base/Box' import Box from 'components/base/Box'
@ -73,4 +76,17 @@ class GrowScroll extends PureComponent<Props> {
} }
} }
SmoothScrollbar.use(
class DisableXScroll extends ScrollbarPlugin {
static pluginName = 'disableXScroll'
transformDelta(delta) {
return {
x: 0,
y: delta.y,
}
}
},
)
export default GrowScroll export default GrowScroll

6
src/components/base/Pills/index.js

@ -26,13 +26,13 @@ const Pill = styled(Tabbable).attrs({
ff: p => (p.isActive ? 'Open Sans|SemiBold' : 'Open Sans'), ff: p => (p.isActive ? 'Open Sans|SemiBold' : 'Open Sans'),
color: p => (p.isActive ? 'dodgerBlue' : 'warmGrey'), color: p => (p.isActive ? 'dodgerBlue' : 'warmGrey'),
bg: p => (p.isActive ? rgba(p.theme.colors.dodgerBlue, 0.1) : ''), bg: p => (p.isActive ? rgba(p.theme.colors.dodgerBlue, 0.1) : ''),
px: 2, px: 3,
fontSize: 4, fontSize: 4,
borderRadius: 1,
align: 'center', align: 'center',
justify: 'center', justify: 'center',
})` })`
height: 30px; height: 28px;
border-radius: 4px;
outline: none; outline: none;
cursor: ${p => (p.isActive ? 'default' : 'pointer')}; cursor: ${p => (p.isActive ? 'default' : 'pointer')};

10
src/icons/AngleDown.js

@ -0,0 +1,10 @@
import React from 'react'
export default props => (
<svg viewBox="0 0 8 7" {...props}>
<path
fill="currentColor"
d="M4 3.76671849l2.19299639-2.05643618c.29899515-.28037641.78376209-.28037641 1.08275724 0 .29899516.28037641.29899516.73495639 0 1.0153328L4.54137862 5.28971769c-.29899515.28037641-.78376209.28037641-1.08275724 0L.72424637 2.72561511c-.29899516-.28037641-.29899516-.73495639 0-1.0153328.29899515-.28037641.78376209-.28037641 1.08275724 0L4 3.76671849z"
/>
</svg>
)
Loading…
Cancel
Save