From 1afa7c03c11dba55d1b186dbc19073a4a2d4858a Mon Sep 17 00:00:00 2001 From: Kevin Bench Date: Tue, 13 Aug 2019 17:39:55 -0500 Subject: [PATCH 1/7] stateful labels --- client/src/Components/TrendsOverview.jsx | 24 +++++++++++++++++++++--- client/src/Components/TrendsPage.jsx | 9 ++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/client/src/Components/TrendsOverview.jsx b/client/src/Components/TrendsOverview.jsx index 1e322e7..73a65cc 100644 --- a/client/src/Components/TrendsOverview.jsx +++ b/client/src/Components/TrendsOverview.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { Doughnut } from 'react-chartjs-2'; - +import PropTypes from 'prop-types'; // test data for display const data = { labels: ['Red', 'Green', 'Yellow'], @@ -13,8 +13,26 @@ const data = { ] }; -const TrendsOverview = () => { - return ; +const TrendsOverview = props => { + const labels = props.data.accountData.budgetCategories.map( + category => category.name + ); + console.log(labels); + const userData = { + labels: labels, + datasets: [ + { + data: [300, 50, 100], + backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], + hoverBackgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'] + } + ] + }; + return ; }; export default TrendsOverview; + +TrendsOverview.propTypes = { + data: PropTypes.object +}; diff --git a/client/src/Components/TrendsPage.jsx b/client/src/Components/TrendsPage.jsx index d085fb8..683e6dc 100644 --- a/client/src/Components/TrendsPage.jsx +++ b/client/src/Components/TrendsPage.jsx @@ -46,14 +46,13 @@ function a11yProps(index) { }; } -export default function TrendsPage() { +export default function TrendsPage(props) { const classes = useStyles(); const [value, setValue] = React.useState(0); function handleChange(event, newValue) { setValue(newValue); } - return ( - + - + - + ); From 78c52eba0acdb1f2ca97cb0fc3e14079d2feb69b Mon Sep 17 00:00:00 2001 From: Kevin Bench Date: Tue, 13 Aug 2019 19:57:30 -0500 Subject: [PATCH 2/7] habits selector under construction --- .../Components/TrendsComparisonSelector.jsx | 0 .../src/Components/TrendsHabitsSelector.jsx | 145 ++++++++++++++++++ client/src/Components/TrendsOverview.jsx | 2 +- .../src/Components/TrendsOverviewSelector.jsx | 80 ++++++++++ client/src/Components/TrendsPage.jsx | 2 + 5 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 client/src/Components/TrendsComparisonSelector.jsx create mode 100644 client/src/Components/TrendsHabitsSelector.jsx create mode 100644 client/src/Components/TrendsOverviewSelector.jsx diff --git a/client/src/Components/TrendsComparisonSelector.jsx b/client/src/Components/TrendsComparisonSelector.jsx new file mode 100644 index 0000000..e69de29 diff --git a/client/src/Components/TrendsHabitsSelector.jsx b/client/src/Components/TrendsHabitsSelector.jsx new file mode 100644 index 0000000..3aa8dbb --- /dev/null +++ b/client/src/Components/TrendsHabitsSelector.jsx @@ -0,0 +1,145 @@ +import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import InputLabel from '@material-ui/core/InputLabel'; +import FormControl from '@material-ui/core/FormControl'; +import Select from '@material-ui/core/Select'; +import Radio from '@material-ui/core/Radio'; +import RadioGroup from '@material-ui/core/RadioGroup'; +import FormHelperText from '@material-ui/core/FormHelperText'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import FormLabel from '@material-ui/core/FormLabel'; + +const useStyles = makeStyles(theme => ({ + root: { + display: 'flex', + flexWrap: 'wrap' + }, + formControl: { + margin: theme.spacing(1), + minWidth: 120 + }, + selectEmpty: { + marginTop: theme.spacing(2) + }, + radioformControl: { + margin: theme.spacing(3) + }, + group: { + margin: theme.spacing(1, 0) + } +})); + +export default function HabitsSelector() { + const classes = useStyles(); + const [state, setState] = React.useState({ + month: 0, + year: 2019 + }); + const [value, setValue] = React.useState('time frame'); + + const handleChange1 = name => event => { + setState({ + ...state, + [name]: event.target.value + }); + }; + + const handleChange2 = event => { + setValue(event.target.value); + }; + + return ( +
+ + Month + + + + Year + + + + Gender + + } label="Female" /> + } label="Male" /> + } label="Other" /> + } + label="(Disabled option)" + /> + + + + Gender + + } + label="Female" + labelPlacement="start" + /> + } + label="Male" + labelPlacement="start" + /> + } + label="Other" + labelPlacement="start" + /> + } + label="(Disabled option)" + labelPlacement="start" + /> + + labelPlacement start + +
+ ); +} diff --git a/client/src/Components/TrendsOverview.jsx b/client/src/Components/TrendsOverview.jsx index 73a65cc..0f962a6 100644 --- a/client/src/Components/TrendsOverview.jsx +++ b/client/src/Components/TrendsOverview.jsx @@ -17,7 +17,7 @@ const TrendsOverview = props => { const labels = props.data.accountData.budgetCategories.map( category => category.name ); - console.log(labels); + console.log(props.data.accountData); const userData = { labels: labels, datasets: [ diff --git a/client/src/Components/TrendsOverviewSelector.jsx b/client/src/Components/TrendsOverviewSelector.jsx new file mode 100644 index 0000000..e483171 --- /dev/null +++ b/client/src/Components/TrendsOverviewSelector.jsx @@ -0,0 +1,80 @@ +import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import InputLabel from '@material-ui/core/InputLabel'; +import FormControl from '@material-ui/core/FormControl'; +import Select from '@material-ui/core/Select'; + +const useStyles = makeStyles(theme => ({ + root: { + display: 'flex', + flexWrap: 'wrap' + }, + formControl: { + margin: theme.spacing(1), + minWidth: 120 + }, + selectEmpty: { + marginTop: theme.spacing(2) + } +})); + +export default function NativeSelects() { + const classes = useStyles(); + const [state, setState] = React.useState({ + month: 0, + year: 2019 + }); + + const handleChange = name => event => { + setState({ + ...state, + [name]: event.target.value + }); + }; + + return ( +
+ + Month + + + + Year + + +
+ ); +} diff --git a/client/src/Components/TrendsPage.jsx b/client/src/Components/TrendsPage.jsx index 683e6dc..678e6db 100644 --- a/client/src/Components/TrendsPage.jsx +++ b/client/src/Components/TrendsPage.jsx @@ -9,6 +9,7 @@ import Box from '@material-ui/core/Box'; import TrendsOverview from './TrendsOverview.jsx'; import TrendsHabits from './TrendsHabits.jsx'; import TrendsComparison from './TrendsComparison.jsx'; +import NativeSelects from './TrendsOverviewSelector.jsx'; const useStyles = makeStyles({ root: { @@ -68,6 +69,7 @@ export default function TrendsPage(props) { + From 9e817d30fae4df661c4989fa59bb2c477b4db041 Mon Sep 17 00:00:00 2001 From: Kevin Bench Date: Wed, 14 Aug 2019 15:49:56 -0500 Subject: [PATCH 3/7] rendering overview page based on stateful data --- .../Components/TrendsComparisonSelector.jsx | 127 ++++++++++++++++++ .../src/Components/TrendsHabitsSelector.jsx | 86 ++---------- client/src/Components/TrendsOverview.jsx | 6 +- .../src/Components/TrendsOverviewSelector.jsx | 41 +++++- client/src/Components/TrendsPage.jsx | 9 +- 5 files changed, 186 insertions(+), 83 deletions(-) diff --git a/client/src/Components/TrendsComparisonSelector.jsx b/client/src/Components/TrendsComparisonSelector.jsx index e69de29..4a01e9d 100644 --- a/client/src/Components/TrendsComparisonSelector.jsx +++ b/client/src/Components/TrendsComparisonSelector.jsx @@ -0,0 +1,127 @@ +import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import InputLabel from '@material-ui/core/InputLabel'; +import FormControl from '@material-ui/core/FormControl'; +import Select from '@material-ui/core/Select'; + +const useStyles = makeStyles(theme => ({ + root: { + display: 'flex', + flexWrap: 'wrap' + }, + formControl: { + margin: theme.spacing(1), + minWidth: 120 + }, + selectEmpty: { + marginTop: theme.spacing(2) + } +})); + +export default function ComparisonSelector() { + const classes = useStyles(); + const [state, setState] = React.useState({ + month1: 0, + year1: 2019, + month2: 0, + year2: 2019 + }); + + const handleChange = name => event => { + setState({ + ...state, + [name]: event.target.value + }); + }; + + return ( +
+
+ + Month 1 + + + + Year 1 + + +
+
+ + Month 2 + + + + Year 2 + + +
+
+ ); +} diff --git a/client/src/Components/TrendsHabitsSelector.jsx b/client/src/Components/TrendsHabitsSelector.jsx index 3aa8dbb..c93055e 100644 --- a/client/src/Components/TrendsHabitsSelector.jsx +++ b/client/src/Components/TrendsHabitsSelector.jsx @@ -5,7 +5,6 @@ import FormControl from '@material-ui/core/FormControl'; import Select from '@material-ui/core/Select'; import Radio from '@material-ui/core/Radio'; import RadioGroup from '@material-ui/core/RadioGroup'; -import FormHelperText from '@material-ui/core/FormHelperText'; import FormControlLabel from '@material-ui/core/FormControlLabel'; import FormLabel from '@material-ui/core/FormLabel'; @@ -32,8 +31,7 @@ const useStyles = makeStyles(theme => ({ export default function HabitsSelector() { const classes = useStyles(); const [state, setState] = React.useState({ - month: 0, - year: 2019 + category: 0 }); const [value, setValue] = React.useState('time frame'); @@ -51,94 +49,38 @@ export default function HabitsSelector() { return (
- Month + Category - - - Year - - Gender + Time Period - } label="Female" /> - } label="Male" /> - } label="Other" /> } - label="(Disabled option)" - /> - - - - Gender - - } - label="Female" - labelPlacement="start" - /> - } - label="Male" - labelPlacement="start" - /> - } - label="Other" - labelPlacement="start" + label="Month to Month" /> } - label="(Disabled option)" - labelPlacement="start" + label="Year to Year" /> - labelPlacement start
); diff --git a/client/src/Components/TrendsOverview.jsx b/client/src/Components/TrendsOverview.jsx index 0f962a6..b04fbf3 100644 --- a/client/src/Components/TrendsOverview.jsx +++ b/client/src/Components/TrendsOverview.jsx @@ -17,12 +17,14 @@ const TrendsOverview = props => { const labels = props.data.accountData.budgetCategories.map( category => category.name ); - console.log(props.data.accountData); + const data = props.data.accountData.budgetCategories.map( + category => category.allotment[2019][6] + ); const userData = { labels: labels, datasets: [ { - data: [300, 50, 100], + data: data, backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], hoverBackgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'] } diff --git a/client/src/Components/TrendsOverviewSelector.jsx b/client/src/Components/TrendsOverviewSelector.jsx index e483171..224155b 100644 --- a/client/src/Components/TrendsOverviewSelector.jsx +++ b/client/src/Components/TrendsOverviewSelector.jsx @@ -3,6 +3,7 @@ import { makeStyles } from '@material-ui/core/styles'; import InputLabel from '@material-ui/core/InputLabel'; import FormControl from '@material-ui/core/FormControl'; import Select from '@material-ui/core/Select'; +import PropTypes, { object } from 'prop-types'; const useStyles = makeStyles(theme => ({ root: { @@ -18,11 +19,12 @@ const useStyles = makeStyles(theme => ({ } })); -export default function NativeSelects() { +export default function OverviewSelector(props) { const classes = useStyles(); const [state, setState] = React.useState({ - month: 0, - year: 2019 + month: '', + year: '', + years: [] }); const handleChange = name => event => { @@ -32,6 +34,25 @@ export default function NativeSelects() { }); }; + const updateYear = () => { + let result = {}; + for (let i = 0; i < props.data.accountData.accounts.length; i++) { + for (let obj in props.data.accountData.accounts[i].transactions) { + result[obj] = 1; + } + } + console.log(Object.keys(result)); + return Object.keys(result); + }; + + React.useEffect(() => { + console.log('this'); + setState({ + ...state, + years: updateYear() + }); + }, []); + return (
@@ -44,7 +65,7 @@ export default function NativeSelects() { name: 'month' }} > - @@ -70,11 +91,17 @@ export default function NativeSelects() { }} > - - + {state.years.map((year, i) => ( + + ))}
); } + +OverviewSelector.propTypes = { + data: PropTypes.object +}; diff --git a/client/src/Components/TrendsPage.jsx b/client/src/Components/TrendsPage.jsx index 678e6db..ea64083 100644 --- a/client/src/Components/TrendsPage.jsx +++ b/client/src/Components/TrendsPage.jsx @@ -9,7 +9,9 @@ import Box from '@material-ui/core/Box'; import TrendsOverview from './TrendsOverview.jsx'; import TrendsHabits from './TrendsHabits.jsx'; import TrendsComparison from './TrendsComparison.jsx'; -import NativeSelects from './TrendsOverviewSelector.jsx'; +import OverviewSelector from './TrendsOverviewSelector.jsx'; +import HabitsSelector from './TrendsHabitsSelector.jsx'; +import ComparisonSelector from './TrendsComparisonSelector.jsx'; const useStyles = makeStyles({ root: { @@ -54,6 +56,7 @@ export default function TrendsPage(props) { function handleChange(event, newValue) { setValue(newValue); } + return ( - + + + ); From 1014c229bb44e4832e5294cc83707c2bc834c148 Mon Sep 17 00:00:00 2001 From: Kevin Bench Date: Wed, 14 Aug 2019 18:10:40 -0500 Subject: [PATCH 4/7] overview passing data around --- .../Components/TrendsComparisonSelector.jsx | 43 +++++++++++++++---- .../src/Components/TrendsHabitsSelector.jsx | 19 +++++--- client/src/Components/TrendsOverview.jsx | 25 +++++++++-- .../src/Components/TrendsOverviewSelector.jsx | 13 ++++-- client/src/Components/TrendsPage.jsx | 20 ++++++--- 5 files changed, 94 insertions(+), 26 deletions(-) diff --git a/client/src/Components/TrendsComparisonSelector.jsx b/client/src/Components/TrendsComparisonSelector.jsx index 4a01e9d..af0c6b0 100644 --- a/client/src/Components/TrendsComparisonSelector.jsx +++ b/client/src/Components/TrendsComparisonSelector.jsx @@ -3,6 +3,7 @@ import { makeStyles } from '@material-ui/core/styles'; import InputLabel from '@material-ui/core/InputLabel'; import FormControl from '@material-ui/core/FormControl'; import Select from '@material-ui/core/Select'; +import PropTypes from 'prop-types'; const useStyles = makeStyles(theme => ({ root: { @@ -18,13 +19,14 @@ const useStyles = makeStyles(theme => ({ } })); -export default function ComparisonSelector() { +export default function ComparisonSelector(props) { const classes = useStyles(); const [state, setState] = React.useState({ month1: 0, year1: 2019, month2: 0, - year2: 2019 + year2: 2019, + years: [] }); const handleChange = name => event => { @@ -34,6 +36,23 @@ export default function ComparisonSelector() { }); }; + const updateYear = () => { + let result = {}; + for (let i = 0; i < props.data.accountData.accounts.length; i++) { + for (let obj in props.data.accountData.accounts[i].transactions) { + result[obj] = 1; + } + } + return Object.keys(result); + }; + + React.useEffect(() => { + setState({ + ...state, + years: updateYear() + }); + }, []); + return (
@@ -73,9 +92,11 @@ export default function ComparisonSelector() { }} > - - + {state.years.map((year, i) => ( + + ))}
@@ -116,12 +137,18 @@ export default function ComparisonSelector() { }} > - - + {state.years.map((year, i) => ( + + ))}
); } + +ComparisonSelector.propTypes = { + data: PropTypes.object +}; diff --git a/client/src/Components/TrendsHabitsSelector.jsx b/client/src/Components/TrendsHabitsSelector.jsx index c93055e..fa16c14 100644 --- a/client/src/Components/TrendsHabitsSelector.jsx +++ b/client/src/Components/TrendsHabitsSelector.jsx @@ -7,6 +7,7 @@ import Radio from '@material-ui/core/Radio'; import RadioGroup from '@material-ui/core/RadioGroup'; import FormControlLabel from '@material-ui/core/FormControlLabel'; import FormLabel from '@material-ui/core/FormLabel'; +import PropTypes from 'prop-types'; const useStyles = makeStyles(theme => ({ root: { @@ -28,10 +29,11 @@ const useStyles = makeStyles(theme => ({ } })); -export default function HabitsSelector() { +export default function HabitsSelector(props) { const classes = useStyles(); const [state, setState] = React.useState({ - category: 0 + category: '', + categories: [] }); const [value, setValue] = React.useState('time frame'); @@ -58,9 +60,12 @@ export default function HabitsSelector() { name: 'category' }} > - - - + + {props.data.accountData.budgetCategories.map((category, i) => ( + + ))} @@ -85,3 +90,7 @@ export default function HabitsSelector() { ); } + +HabitsSelector.propTypes = { + data: PropTypes.object +}; diff --git a/client/src/Components/TrendsOverview.jsx b/client/src/Components/TrendsOverview.jsx index b04fbf3..1664248 100644 --- a/client/src/Components/TrendsOverview.jsx +++ b/client/src/Components/TrendsOverview.jsx @@ -14,12 +14,27 @@ const data = { }; const TrendsOverview = props => { + console.log(data, props.data, props.month); const labels = props.data.accountData.budgetCategories.map( category => category.name ); - const data = props.data.accountData.budgetCategories.map( - category => category.allotment[2019][6] - ); + const [data, setData] = React.useState([]); + + React.useEffect(() => { + setData( + props.data.accountData.budgetCategories.map(category => { + if (category.allotment[props.year]) { + if ( + category.allotment[props.year][props.month] || + category.allotment[props.year][props.month] === 0 + ) { + return category.allotment[props.year][props.month]; + } + } + }) + ); + }, [props.year, props.month]); + const userData = { labels: labels, datasets: [ @@ -36,5 +51,7 @@ const TrendsOverview = props => { export default TrendsOverview; TrendsOverview.propTypes = { - data: PropTypes.object + data: PropTypes.object, + month: PropTypes.string, + year: PropTypes.string }; diff --git a/client/src/Components/TrendsOverviewSelector.jsx b/client/src/Components/TrendsOverviewSelector.jsx index 224155b..5fba2b5 100644 --- a/client/src/Components/TrendsOverviewSelector.jsx +++ b/client/src/Components/TrendsOverviewSelector.jsx @@ -3,7 +3,7 @@ import { makeStyles } from '@material-ui/core/styles'; import InputLabel from '@material-ui/core/InputLabel'; import FormControl from '@material-ui/core/FormControl'; import Select from '@material-ui/core/Select'; -import PropTypes, { object } from 'prop-types'; +import PropTypes from 'prop-types'; const useStyles = makeStyles(theme => ({ root: { @@ -41,18 +41,21 @@ export default function OverviewSelector(props) { result[obj] = 1; } } - console.log(Object.keys(result)); return Object.keys(result); }; React.useEffect(() => { - console.log('this'); setState({ ...state, years: updateYear() }); }, []); + React.useEffect(() => { + props.setMonth(state.month); + props.setYear(state.year); + }, [state.month, state.year]); + return (
@@ -103,5 +106,7 @@ export default function OverviewSelector(props) { } OverviewSelector.propTypes = { - data: PropTypes.object + data: PropTypes.object, + setMonth: PropTypes.func, + setYear: PropTypes.func }; diff --git a/client/src/Components/TrendsPage.jsx b/client/src/Components/TrendsPage.jsx index ea64083..3386a7e 100644 --- a/client/src/Components/TrendsPage.jsx +++ b/client/src/Components/TrendsPage.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useCallback } from 'react'; import { makeStyles } from '@material-ui/core/styles'; import PropTypes from 'prop-types'; import Paper from '@material-ui/core/Paper'; @@ -52,6 +52,8 @@ function a11yProps(index) { export default function TrendsPage(props) { const classes = useStyles(); const [value, setValue] = React.useState(0); + const [overviewYear, setOverviewYear] = React.useState(''); + const [overviewMonth, setOverviewMonth] = React.useState(''); function handleChange(event, newValue) { setValue(newValue); @@ -71,16 +73,24 @@ export default function TrendsPage(props) { - - + + - + - + ); From 5e415a64727542fd673ae23ea40be6190830d67a Mon Sep 17 00:00:00 2001 From: Kevin Bench Date: Wed, 14 Aug 2019 20:16:32 -0500 Subject: [PATCH 5/7] rendering data to habits page --- client/src/Components/TrendsHabits.jsx | 57 ++++++++++++++++++- .../src/Components/TrendsHabitsSelector.jsx | 11 +++- client/src/Components/TrendsOverview.jsx | 12 ---- client/src/Components/TrendsPage.jsx | 10 +++- 4 files changed, 71 insertions(+), 19 deletions(-) diff --git a/client/src/Components/TrendsHabits.jsx b/client/src/Components/TrendsHabits.jsx index 9c3f9da..430520c 100644 --- a/client/src/Components/TrendsHabits.jsx +++ b/client/src/Components/TrendsHabits.jsx @@ -1,7 +1,22 @@ import React from 'react'; import { Line } from 'react-chartjs-2'; +import PropTypes from 'prop-types'; // test data for display +const months = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December' +]; const data = { labels: ['Red', 'Green', 'Yellow'], datasets: [ @@ -11,11 +26,47 @@ const data = { hoverBackgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], lineTension: 0 } - ] + ], + options: { + title: 'test' + } }; +const TrendsHabits = props => { + const [categoryData, setCategory] = React.useState([]); + const [graphData, setGraph] = React.useState(data); -const TrendsHabits = () => { - return ; + React.useEffect(() => { + setCategory( + props.data.accountData.budgetCategories.filter(category => { + return category.name == props.category; + }) + ); + }, [props.category]); + + React.useEffect(() => { + if (props.view === 'month' && categoryData.length > 0) { + console.log(categoryData); + let numbers = Object.keys(categoryData[0].allotment[2019]); + setGraph({ + labels: numbers.map(num => months[num]), + datasets: [ + { + data: numbers.map(month => categoryData[0].allotment[2019][month]) + } + ] + }); + } else { + console.log('yearly view'); + } + }, [categoryData]); + + return ; }; export default TrendsHabits; + +TrendsHabits.propTypes = { + data: PropTypes.object, + view: PropTypes.string, + category: PropTypes.string +}; diff --git a/client/src/Components/TrendsHabitsSelector.jsx b/client/src/Components/TrendsHabitsSelector.jsx index fa16c14..1dc31e2 100644 --- a/client/src/Components/TrendsHabitsSelector.jsx +++ b/client/src/Components/TrendsHabitsSelector.jsx @@ -35,7 +35,7 @@ export default function HabitsSelector(props) { category: '', categories: [] }); - const [value, setValue] = React.useState('time frame'); + const [value, setValue] = React.useState('month'); const handleChange1 = name => event => { setState({ @@ -48,6 +48,11 @@ export default function HabitsSelector(props) { setValue(event.target.value); }; + React.useEffect(() => { + props.setView(value); + props.setCategory(state.category); + }, [value, state.category]); + return (
@@ -92,5 +97,7 @@ export default function HabitsSelector(props) { } HabitsSelector.propTypes = { - data: PropTypes.object + data: PropTypes.object, + setView: PropTypes.func, + setCategory: PropTypes.func }; diff --git a/client/src/Components/TrendsOverview.jsx b/client/src/Components/TrendsOverview.jsx index 1664248..fe8866d 100644 --- a/client/src/Components/TrendsOverview.jsx +++ b/client/src/Components/TrendsOverview.jsx @@ -1,20 +1,8 @@ import React from 'react'; import { Doughnut } from 'react-chartjs-2'; import PropTypes from 'prop-types'; -// test data for display -const data = { - labels: ['Red', 'Green', 'Yellow'], - datasets: [ - { - data: [300, 50, 100], - backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], - hoverBackgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'] - } - ] -}; const TrendsOverview = props => { - console.log(data, props.data, props.month); const labels = props.data.accountData.budgetCategories.map( category => category.name ); diff --git a/client/src/Components/TrendsPage.jsx b/client/src/Components/TrendsPage.jsx index 3386a7e..b248b27 100644 --- a/client/src/Components/TrendsPage.jsx +++ b/client/src/Components/TrendsPage.jsx @@ -54,6 +54,8 @@ export default function TrendsPage(props) { const [value, setValue] = React.useState(0); const [overviewYear, setOverviewYear] = React.useState(''); const [overviewMonth, setOverviewMonth] = React.useState(''); + const [habitView, setHabitView] = React.useState('month'); + const [habitCategory, setHabitCategory] = React.useState(''); function handleChange(event, newValue) { setValue(newValue); @@ -85,8 +87,12 @@ export default function TrendsPage(props) { /> - - + + From 191dd1793226fad5522e6450f1ebd0ed2262b353 Mon Sep 17 00:00:00 2001 From: Kevin Bench Date: Thu, 15 Aug 2019 16:03:10 -0500 Subject: [PATCH 6/7] overview, and habits working --- client/src/Components/TrendsHabits.jsx | 105 ++++++++++++++++-- client/src/Components/TrendsOverview.jsx | 38 ++++--- .../src/Components/TrendsOverviewSelector.jsx | 8 +- 3 files changed, 124 insertions(+), 27 deletions(-) diff --git a/client/src/Components/TrendsHabits.jsx b/client/src/Components/TrendsHabits.jsx index 430520c..ef0c65f 100644 --- a/client/src/Components/TrendsHabits.jsx +++ b/client/src/Components/TrendsHabits.jsx @@ -3,7 +3,7 @@ import { Line } from 'react-chartjs-2'; import PropTypes from 'prop-types'; // test data for display -const months = [ +const numToMonths = [ 'January', 'February', 'March', @@ -17,6 +17,9 @@ const months = [ 'November', 'December' ]; +const date = new Date(); +const currentYear = date.getFullYear(); + const data = { labels: ['Red', 'Green', 'Yellow'], datasets: [ @@ -32,8 +35,10 @@ const data = { } }; const TrendsHabits = props => { - const [categoryData, setCategory] = React.useState([]); + const [category, setCategory] = React.useState([]); const [graphData, setGraph] = React.useState(data); + const [months, setMonths] = React.useState([]); + const [years, setYears] = React.useState([]); React.useEffect(() => { setCategory( @@ -44,25 +49,105 @@ const TrendsHabits = props => { }, [props.category]); React.useEffect(() => { - if (props.view === 'month' && categoryData.length > 0) { - console.log(categoryData); - let numbers = Object.keys(categoryData[0].allotment[2019]); + if (props.view === 'month' && category.length > 0) { + const possibleMonths = {}; + props.data.accountData.accounts.map(account => { + Object.keys(account.transactions[currentYear]).map(month => { + if (possibleMonths[month]) { + possibleMonths[month] += account.transactions[currentYear][ + month + ].reduce((x, y) => { + if (y.category === category[0].name) { + return x + Number(y.amount); + } else { + return x + 0; + } + }, 0); + } else { + possibleMonths[month] = account.transactions[currentYear][ + month + ].reduce((x, y) => { + if (y.category === category[0].name) { + return x + Number(y.amount); + } else { + return x + 0; + } + }, 0); + } + }); + setMonths(possibleMonths); + }); + } else if (category.length > 0) { + const possibleYears = {}; + props.data.accountData.accounts.map(account => { + Object.keys(account.transactions).map(currentYear => { + let possibleMonths = {}; + Object.keys(account.transactions[currentYear]).map(month => { + if (possibleMonths[month]) { + possibleMonths[month] += account.transactions[currentYear][ + month + ].reduce((x, y) => { + if (y.category === category[0].name) { + return x + Number(y.amount); + } else { + return x + 0; + } + }, 0); + } else { + possibleMonths[month] = account.transactions[currentYear][ + month + ].reduce((x, y) => { + if (y.category === category[0].name) { + return x + Number(y.amount); + } else { + return x + 0; + } + }, 0); + } + }); + let total = 0; + Object.keys(possibleMonths).forEach( + month => (total += possibleMonths[month]) + ); + if (possibleYears[currentYear]) { + possibleYears[currentYear] += total; + } else { + possibleYears[currentYear] = total; + } + }); + }); + setYears(possibleYears); + } + }, [category, props.view]); + + React.useEffect(() => { + console.log(props.view); + if (props.view === 'month') { + console.log('yo'); + let numbers = Object.keys(months); setGraph({ - labels: numbers.map(num => months[num]), + labels: numbers.map(num => numToMonths[num]), datasets: [ { - data: numbers.map(month => categoryData[0].allotment[2019][month]) + data: numbers.map(num => Math.floor(months[num] * 1000) / 1000) } ] }); } else { - console.log('yearly view'); + let numbers = Object.keys(years); + setGraph({ + labels: numbers, + datasets: [ + { + data: numbers.map(num => Math.floor(years[num] * 1000) / 1000) + } + ] + }); } - }, [categoryData]); + }, [months, years, props.view]); return ; }; - export default TrendsHabits; TrendsHabits.propTypes = { diff --git a/client/src/Components/TrendsOverview.jsx b/client/src/Components/TrendsOverview.jsx index fe8866d..0c0e94c 100644 --- a/client/src/Components/TrendsOverview.jsx +++ b/client/src/Components/TrendsOverview.jsx @@ -3,26 +3,36 @@ import { Doughnut } from 'react-chartjs-2'; import PropTypes from 'prop-types'; const TrendsOverview = props => { - const labels = props.data.accountData.budgetCategories.map( - category => category.name - ); + const [labels, setLabels] = React.useState([]); const [data, setData] = React.useState([]); + const [transactions, setTransactions] = React.useState([]); React.useEffect(() => { - setData( - props.data.accountData.budgetCategories.map(category => { - if (category.allotment[props.year]) { - if ( - category.allotment[props.year][props.month] || - category.allotment[props.year][props.month] === 0 - ) { - return category.allotment[props.year][props.month]; - } + let transactions = {}; + props.data.accountData.accounts.map(account => { + if (account.transactions[props.year]) { + if (account.transactions[props.year][props.month]) { + account.transactions[props.year][props.month].forEach(transaction => { + if (transactions[transaction.category]) { + transactions[transaction.category] += Number(transaction.amount); + } else { + transactions[transaction.category] = Number(transaction.amount); + } + }); } - }) - ); + } + }); + setTransactions(transactions); }, [props.year, props.month]); + React.useEffect(() => { + setLabels(Object.keys(transactions)); + }, [transactions]); + + React.useEffect(() => { + setData(labels.map(label => Math.round(transactions[label] * 1000) / 1000)); + }, [labels]); + const userData = { labels: labels, datasets: [ diff --git a/client/src/Components/TrendsOverviewSelector.jsx b/client/src/Components/TrendsOverviewSelector.jsx index 5fba2b5..2ee6b1c 100644 --- a/client/src/Components/TrendsOverviewSelector.jsx +++ b/client/src/Components/TrendsOverviewSelector.jsx @@ -18,12 +18,14 @@ const useStyles = makeStyles(theme => ({ marginTop: theme.spacing(2) } })); - +const date = new Date(); +const currentMonth = date.getMonth().toString(); +const currentYear = date.getFullYear().toString(); export default function OverviewSelector(props) { const classes = useStyles(); const [state, setState] = React.useState({ - month: '', - year: '', + month: currentMonth, + year: currentYear, years: [] }); From 16aff2cc8f5aac15e0bdda1e876b6bbdf45062ce Mon Sep 17 00:00:00 2001 From: Kevin Bench Date: Thu, 15 Aug 2019 18:02:00 -0500 Subject: [PATCH 7/7] comparison working --- client/src/Components/TrendsComparison.jsx | 87 +++++++++++-- .../Components/TrendsComparisonSelector.jsx | 24 +++- client/src/Components/TrendsHabits.jsx | 116 +++++++++--------- client/src/Components/TrendsPage.jsx | 20 ++- 4 files changed, 167 insertions(+), 80 deletions(-) diff --git a/client/src/Components/TrendsComparison.jsx b/client/src/Components/TrendsComparison.jsx index b041626..cc2e7a7 100644 --- a/client/src/Components/TrendsComparison.jsx +++ b/client/src/Components/TrendsComparison.jsx @@ -1,20 +1,81 @@ import React from 'react'; import { Bar } from 'react-chartjs-2'; - +import PropTypes from 'prop-types'; // test data for display -const data = { - labels: ['Red', 'Green', 'Yellow'], - datasets: [ - { - data: [300, 50, 100], - backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], - hoverBackgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'] - } - ] -}; -const TrendsComparison = () => { - return ; +const TrendsComparison = props => { + const [m1Data, setm1Data] = React.useState({}); + const [m2Data, setm2Data] = React.useState({}); + const [categories, setCategories] = React.useState({}); + const [graphData, setGraphData] = React.useState({}); + + React.useEffect(() => { + let cat1 = {}; + let cat2 = {}; + let totalCats = {}; + props.data.accountData.accounts.forEach(account => { + if (account.transactions[props.y1]) { + if (account.transactions[props.y1][props.m1]) { + account.transactions[props.y1][props.m1].forEach(transaction => { + if (cat1[transaction.category]) { + cat1[transaction.category] += Number(transaction.amount); + } else { + cat1[transaction.category] = Number(transaction.amount); + totalCats[transaction.category] = 1; + } + }); + } + } + if (account.transactions[props.y2]) { + if (account.transactions[props.y2][props.m2]) { + account.transactions[props.y2][props.m2].forEach(transaction => { + if (cat2[transaction.category]) { + cat2[transaction.category] += Number(transaction.amount); + } else { + cat2[transaction.category] = Number(transaction.amount); + totalCats[transaction.category] = 1; + } + }); + } + } + }); + setm1Data(cat1); + setm2Data(cat2); + setCategories(totalCats); + }, [props.m1, props.m2, props.y1, props.y2]); + + React.useEffect(() => { + setGraphData({ + labels: Object.keys(categories).sort(), + datasets: [ + { + label: 'Month 1', + data: Object.keys(categories) + .sort() + .map(cat => m1Data[cat] || 0), + backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], + hoverBackgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'] + }, + { + label: 'Month 2', + data: Object.keys(categories) + .sort() + .map(cat => m2Data[cat] || 0), + backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], + hoverBackgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'] + } + ] + }); + }, [m1Data, m2Data, categories]); + return ; }; export default TrendsComparison; + +TrendsComparison.propTypes = { + data: PropTypes.object, + m1: PropTypes.string, + m2: PropTypes.string, + y1: PropTypes.string, + y2: PropTypes.string +}; diff --git a/client/src/Components/TrendsComparisonSelector.jsx b/client/src/Components/TrendsComparisonSelector.jsx index af0c6b0..5774dbb 100644 --- a/client/src/Components/TrendsComparisonSelector.jsx +++ b/client/src/Components/TrendsComparisonSelector.jsx @@ -19,13 +19,18 @@ const useStyles = makeStyles(theme => ({ } })); +const date = new Date(); +const year = date.getFullYear(); +const month = date.getMonth(); +const month2 = month === 0 ? 11 : month - 1; + export default function ComparisonSelector(props) { const classes = useStyles(); const [state, setState] = React.useState({ - month1: 0, - year1: 2019, - month2: 0, - year2: 2019, + month1: month.toString(), + year1: year.toString(), + month2: month2.toString(), + year2: year.toString(), years: [] }); @@ -53,6 +58,11 @@ export default function ComparisonSelector(props) { }); }, []); + React.useEffect(() => props.setM1(state.month1), [state.month1]); + React.useEffect(() => props.setM2(state.month2), [state.month2]); + React.useEffect(() => props.setY1(state.year1), [state.year1]); + React.useEffect(() => props.setY2(state.year2), [state.year2]); + return (
@@ -150,5 +160,9 @@ export default function ComparisonSelector(props) { } ComparisonSelector.propTypes = { - data: PropTypes.object + data: PropTypes.object, + setM1: PropTypes.func, + setM2: PropTypes.func, + setY1: PropTypes.func, + setY2: PropTypes.func }; diff --git a/client/src/Components/TrendsHabits.jsx b/client/src/Components/TrendsHabits.jsx index ef0c65f..a3d0c71 100644 --- a/client/src/Components/TrendsHabits.jsx +++ b/client/src/Components/TrendsHabits.jsx @@ -20,23 +20,9 @@ const numToMonths = [ const date = new Date(); const currentYear = date.getFullYear(); -const data = { - labels: ['Red', 'Green', 'Yellow'], - datasets: [ - { - data: [300, 50, 100], - backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], - hoverBackgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], - lineTension: 0 - } - ], - options: { - title: 'test' - } -}; const TrendsHabits = props => { - const [category, setCategory] = React.useState([]); - const [graphData, setGraph] = React.useState(data); + const [category, setCategory] = React.useState([{ name: '' }]); + const [graphData, setGraph] = React.useState({}); const [months, setMonths] = React.useState([]); const [years, setYears] = React.useState([]); @@ -80,39 +66,41 @@ const TrendsHabits = props => { } else if (category.length > 0) { const possibleYears = {}; props.data.accountData.accounts.map(account => { - Object.keys(account.transactions).map(currentYear => { + Object.keys(account.transactions).map(year => { let possibleMonths = {}; - Object.keys(account.transactions[currentYear]).map(month => { + Object.keys(account.transactions[year]).map(month => { if (possibleMonths[month]) { - possibleMonths[month] += account.transactions[currentYear][ - month - ].reduce((x, y) => { - if (y.category === category[0].name) { - return x + Number(y.amount); - } else { - return x + 0; - } - }, 0); + possibleMonths[month] += account.transactions[year][month].reduce( + (x, y) => { + if (y.category === category[0].name) { + return x + Number(y.amount); + } else { + return x + 0; + } + }, + 0 + ); } else { - possibleMonths[month] = account.transactions[currentYear][ - month - ].reduce((x, y) => { - if (y.category === category[0].name) { - return x + Number(y.amount); - } else { - return x + 0; - } - }, 0); + possibleMonths[month] = account.transactions[year][month].reduce( + (x, y) => { + if (y.category === category[0].name) { + return x + Number(y.amount); + } else { + return x + 0; + } + }, + 0 + ); } }); let total = 0; Object.keys(possibleMonths).forEach( month => (total += possibleMonths[month]) ); - if (possibleYears[currentYear]) { - possibleYears[currentYear] += total; + if (possibleYears[year]) { + possibleYears[year] += total; } else { - possibleYears[currentYear] = total; + possibleYears[year] = total; } }); }); @@ -121,28 +109,36 @@ const TrendsHabits = props => { }, [category, props.view]); React.useEffect(() => { - console.log(props.view); - if (props.view === 'month') { - console.log('yo'); - let numbers = Object.keys(months); - setGraph({ - labels: numbers.map(num => numToMonths[num]), - datasets: [ - { - data: numbers.map(num => Math.floor(months[num] * 1000) / 1000) - } - ] - }); - } else { - let numbers = Object.keys(years); - setGraph({ - labels: numbers, - datasets: [ - { - data: numbers.map(num => Math.floor(years[num] * 1000) / 1000) + if (category) { + if (category[0]) { + if (category[0].name) { + if (props.view === 'month') { + let numbers = Object.keys(months); + setGraph({ + labels: numbers.map(num => numToMonths[num]), + datasets: [ + { + label: category[0].name, + data: numbers.map( + num => Math.floor(months[num] * 1000) / 1000 + ) + } + ] + }); + } else { + let numbers = Object.keys(years); + setGraph({ + labels: numbers, + datasets: [ + { + label: category[0].name, + data: numbers.map(num => Math.floor(years[num] * 1000) / 1000) + } + ] + }); } - ] - }); + } + } } }, [months, years, props.view]); diff --git a/client/src/Components/TrendsPage.jsx b/client/src/Components/TrendsPage.jsx index b248b27..4f009b1 100644 --- a/client/src/Components/TrendsPage.jsx +++ b/client/src/Components/TrendsPage.jsx @@ -56,6 +56,10 @@ export default function TrendsPage(props) { const [overviewMonth, setOverviewMonth] = React.useState(''); const [habitView, setHabitView] = React.useState('month'); const [habitCategory, setHabitCategory] = React.useState(''); + const [compareMonth1, setCompareMonth1] = React.useState(''); + const [compareMonth2, setCompareMonth2] = React.useState(''); + const [compareYear1, setCompareYear1] = React.useState(''); + const [compareYear2, setCompareYear2] = React.useState(''); function handleChange(event, newValue) { setValue(newValue); @@ -95,8 +99,20 @@ export default function TrendsPage(props) { /> - - + + );