Skip to content

Commit

Permalink
Feature/portfolio (#38)
Browse files Browse the repository at this point in the history
* feat(portfolio): Started with portfolio
Linked up with the graph, needs refactoring

* Rebased and updated

* Updated inteface to add new transaction

* Added new transaction form

* Updated save and load transactions

* update

* Added Transactions and confirmation dialog

* importing market values from alphavantage.com; Showing the aggregated transactions on the portfolio page

* Added portfolio filters
  • Loading branch information
JackNeto committed Aug 21, 2018
1 parent f188823 commit a895b81
Show file tree
Hide file tree
Showing 43 changed files with 1,404 additions and 153 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ yarn-error.log*

.idea
tmp

/src/core/Portfolios/portfolios/*.json
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
"flux": "flux"
},
"dependencies": {
"@material-ui/core": "^1.0.0-rc.1",
"@material-ui/icons": "^1.0.0-rc.0",
"@material-ui/core": "^1.3.1",
"@material-ui/icons": "^1.1.0",
"@vx/axis": "^0.0.160",
"@vx/curve": "^0.0.153",
"@vx/event": "^0.0.153",
Expand Down Expand Up @@ -75,6 +75,7 @@
"eslint-plugin-react": "^7.7.0",
"extract-text-webpack-plugin": "3.0.2",
"file-loader": "1.1.5",
"formik": "^0.11.11",
"fs-extra": "3.0.1",
"gh-pages": "^1.1.0",
"html-webpack-plugin": "2.29.0",
Expand All @@ -90,22 +91,26 @@
"prop-types": "^15.6.1",
"raf": "3.4.0",
"react": "^16.3.1",
"react-confirm": "^0.1.17",
"react-dev-utils": "^5.0.1",
"react-dom": "^16.3.1",
"react-motion": "^0.5.2",
"react-number-format": "^3.3.1",
"react-popper": "^1.0.0-beta.6",
"react-redux": "^5.0.7",
"react-router-dom": "^4.2.2",
"recompose": "^0.27.1",
"redux": "^4.0.0",
"redux-devtools-extension": "^2.13.2",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.2.0",
"reselect": "^3.0.1",
"resolve": "1.6.0",
"style-loader": "0.19.0",
"sw-precache-webpack-plugin": "0.11.4",
"typeface-roboto": "^0.0.54",
"url-loader": "0.6.2",
"uuid": "^3.2.1",
"webpack": "3.8.1",
"webpack-dev-server": "2.9.4",
"webpack-manifest-plugin": "1.3.2",
Expand Down
44 changes: 44 additions & 0 deletions src/common/ConfirmDialog/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react'
import PropTypes from 'prop-types'
import Button from '@material-ui/core/Button'
import Dialog from '@material-ui/core/Dialog'
import DialogTitle from '@material-ui/core/DialogTitle'
import DialogContent from '@material-ui/core/DialogContent'
import DialogActions from '@material-ui/core/DialogActions'
import { confirmable } from 'react-confirm'

const ConfirmDialog = ({
title,
description,
show,
proceed,
dismiss
}) => (
<Dialog
disableBackdropClick
disableEscapeKeyDown
maxWidth="xs"
aria-labelledby="confirmation-dialog-title"
open={show}
>
<DialogTitle id="confirmation-dialog-title">{title}</DialogTitle>
<DialogContent>{description}</DialogContent>
<DialogActions>
<Button onClick={dismiss} color="primary">
Cancel
</Button>
<Button onClick={proceed} color="primary">
Ok
</Button>
</DialogActions>
</Dialog>
)

ConfirmDialog.propTypes = {
show: PropTypes.bool.isRequired, // from confirmable. indicates if the dialog is shown or not.
proceed: PropTypes.func.isRequired, // from confirmable. call to close the dialog with promise resolved.
dismiss: PropTypes.func.isRequired, // from confirmable. call to only close the dialog.
title: PropTypes.string.isRequired, // the title of the dialog
description: PropTypes.string.isRequired // the description of the dialog
}
export default confirmable(ConfirmDialog)
1 change: 0 additions & 1 deletion src/common/HandleLogin/__tests__/index.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ describe('HandleLogin', () => {
it('matches snapshot with logged out user', () => {
const component = renderer.create((
<HandleLoginComponent
user={{ isLoginPending: false }}
handlePendingSignIn={jest.fn()}
/>
))
Expand Down
28 changes: 9 additions & 19 deletions src/common/HandleLogin/index.jsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,26 @@
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { isSignInPending } from 'blockstack'
import { handleBlockstackLogin } from '../../store/user/actions'

const mapStateToProps = ({ user }) => {
return {
user
}
}

const mapDispatchToProps = (dispatch) => {
return {
handlePendingSignIn: () => dispatch(handleBlockstackLogin())
}
}

export const HandleLoginComponent = ({ user, handlePendingSignIn }) => {
if (user.isLoginPending) {
handlePendingSignIn()
return (
<div className="Login">
<h2>Logging In...</h2>
</div>
)
export const HandleLoginComponent = ({ history, handlePendingSignIn }) => {
if (isSignInPending()) {
handlePendingSignIn().then(() => {
history.push('/')
})
}

return null
}

HandleLoginComponent.propTypes = {
user: PropTypes.object.isRequired,
handlePendingSignIn: PropTypes.func.isRequired
handlePendingSignIn: PropTypes.func.isRequired,
history: PropTypes.object.isRequired
}

export default connect(mapStateToProps, mapDispatchToProps)(HandleLoginComponent)
export default connect(null, mapDispatchToProps)(HandleLoginComponent)
5 changes: 3 additions & 2 deletions src/common/Header/__tests__/__snapshots__/index.test.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ exports[`Header matches snapshot 1`] = `
Entaxy
</a>
</div>
<div />
<button
className="MuiButtonBase-root-83 MuiButton-root-67 MuiButton-colorInherit-72"
className="MuiButtonBase-root-91 MuiButton-root-67 MuiButton-text-69 MuiButton-flat-72 MuiButton-colorInherit-86"
disabled={false}
onBlur={[Function]}
onClick={[Function]}
Expand All @@ -46,7 +47,7 @@ exports[`Header matches snapshot 1`] = `
Login
</span>
<span
className="MuiTouchRipple-root-86"
className="MuiTouchRipple-root-94"
/>
</button>
</div>
Expand Down
4 changes: 3 additions & 1 deletion src/common/Header/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import AppBar from '@material-ui/core/AppBar'
import Toolbar from '@material-ui/core/Toolbar'
import { withStyles } from '@material-ui/core/styles'
import Logo from '../Logo/index'
import LoginButton from './../LoginButton'
import LoginButton from '../LoginButton'
import TopNav from '../TopNav'

const styles = {
toolbar: {
Expand All @@ -17,6 +18,7 @@ const Header = ({ classes }) => (
<AppBar position="static">
<Toolbar className={classes.toolbar}>
<Logo />
<TopNav />
<LoginButton />
</Toolbar>
</AppBar>
Expand Down
54 changes: 54 additions & 0 deletions src/common/LoadingOverlay/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { withStyles } from '@material-ui/core/styles'
import './rotating-icon.css'

const styles = {
root: {
top: 0,
left: 0,
right: 0,
bottom: 0,
'z-index': 1000,
padding: '1.2rem',
display: 'flex',
position: 'fixed',
'overflow-y': 'auto',
'overflow-x': 'hidden',
'align-items': 'center',
'justify-content': 'center',
background: 'rgba(36, 123, 160, 0.7)'
},
label: {
'margin-left': '20px',
color: 'var(--color-white)',
'font-weight': 'bold',
'font-family': 'SW Garden Grove',
'font-size': '24px'
}
}

const mapStateToProps = ({ user }) => {
return { isLoading: user.isLoading }
}

const LoadingOverlay = ({ classes, isLoading }) => {
if (isLoading) {
return (
<div className={classes.root}>
<div className="rotating-icon" />
<div className={classes.label}>Loading ...</div>
</div>
)
}
return null
}

LoadingOverlay.propTypes = {
classes: PropTypes.object.isRequired,
isLoading: PropTypes.bool.isRequired
}


export default connect(mapStateToProps)(withStyles(styles)(LoadingOverlay))
25 changes: 25 additions & 0 deletions src/common/LoadingOverlay/rotating-icon.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* --- Loader --- */
.rotating-icon {
display: inline-block;
width: 25px;
height: 25px;
}
.rotating-icon:after {
content: " ";
display: block;
width: 25px;
height: 25px;
margin: 1px;
border-radius: 50%;
border: 3px solid var(--color-white);
border-color: var(--color-white) transparent var(--color-white) transparent;
animation: rotating-icon 1.2s linear infinite;
}
@keyframes rotating-icon {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
4 changes: 2 additions & 2 deletions src/common/LoginButton/__tests__/__snapshots__/index.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Array [

exports[`HandleLogin matches snapshot with logged out user 1`] = `
<button
className="MuiButtonBase-root-17 MuiButton-root-1 MuiButton-colorInherit-6"
className="MuiButtonBase-root-25 MuiButton-root-1 MuiButton-text-3 MuiButton-flat-6 MuiButton-colorInherit-20"
disabled={false}
onBlur={[Function]}
onClick={[MockFunction]}
Expand All @@ -137,7 +137,7 @@ exports[`HandleLogin matches snapshot with logged out user 1`] = `
Login
</span>
<span
className="MuiTouchRipple-root-20"
className="MuiTouchRipple-root-28"
/>
</button>
`;
15 changes: 9 additions & 6 deletions src/common/LoginButton/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import MenuList from '@material-ui/core/MenuList'
import Paper from '@material-ui/core/Paper'
import Grow from '@material-ui/core/Grow'
import ClickAwayListener from '@material-ui/core/ClickAwayListener'
import Tooltip from '@material-ui/core/Tooltip'
import { withStyles } from '@material-ui/core/styles'
import { userLogin, userLogout } from '../../store/user/actions'

const styles = () => ({
const styles = {
root: {
display: 'flex'
}
})
}

const mapStateToProps = ({ user }) => {
return { user }
Expand Down Expand Up @@ -60,10 +61,12 @@ export class LoginButtonComponent extends React.Component {
<Reference>
{({ ref }) => (
<div ref={ref} className={classes.root}>
<Avatar
src={user.pictureUrl}
alt={user.name}
/>
<Tooltip id="tooltip-icon" title={user.username}>
<Avatar
src={user.pictureUrl}
alt={user.name}
/>
</Tooltip>
<Button
color="inherit"
aria-owns={open ? 'menu-list-grow' : null}
Expand Down
36 changes: 36 additions & 0 deletions src/common/TopNav/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react'
import Button from '@material-ui/core/Button'
import { Route, NavLink } from 'react-router-dom'

const TopNav = () => (
<div>
<Route
path="/transactions"
render={(() => (
<div>
<Button size="small" color="inherit" component={NavLink} to="/portfolio">
Portfolio
</Button>
</div>
))}
/>
<Route
path="/portfolio"
render={(() => (
<Button size="small" color="inherit" component={NavLink} to="/transactions">
Transactions
</Button>
))}
/>
<Route
path="/data-sources"
render={(() => (
<Button size="small" color="inherit" component={NavLink} to="/transactions">
Transactions
</Button>
))}
/>
</div>
)

export default TopNav
Loading

0 comments on commit a895b81

Please sign in to comment.