From 2abfafee2316bf2313a020212b89af8a178c4e0a Mon Sep 17 00:00:00 2001 From: Alex Phillips Date: Sat, 12 Feb 2022 09:50:35 -0500 Subject: [PATCH] another round of UI updates --- frontend/src/App.js | 40 ++-- frontend/src/components/AccountDetails.js | 217 ++++++++++++------ .../components/AccountTable/AccountTable.js | 13 +- .../AccountTable/BalanceCalculation.js | 2 +- frontend/src/components/BudgetDetails.js | 192 +++++++++------- .../src/components/BudgetMonthNavigator.js | 108 ++++----- .../BudgetTable/BudgetMonthCalculation.js | 2 +- .../src/components/BudgetTable/BudgetTable.js | 18 +- .../BudgetTable/BudgetTableHeader.js | 160 +++++-------- .../src/components/CategoryMonthActivity.js | 16 -- frontend/src/components/Drawer.js | 79 ++----- frontend/src/components/ReconcileForm.js | 4 +- frontend/src/pages/Account.js | 23 +- frontend/src/pages/Budget.js | 28 +-- 14 files changed, 460 insertions(+), 442 deletions(-) diff --git a/frontend/src/App.js b/frontend/src/App.js index 2dca27b..d7a9899 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -31,30 +31,30 @@ export default function App(props) { palette: { mode: 'dark', background: { - paper: 'rgb(28, 33, 40)', - drawer: 'rgb(28, 33, 40)', - tableHeader: 'rgb(28, 33, 40)', - tableBody: 'rgb(34, 39, 46)', - details: 'rgb(28, 33, 40)', + paper: '#272b30', + drawer: '#272b30', + tableHeader: '#272b30', + tableBody: '#2B3035', + details: '#272b30', }, secondary: { main: '#ffffff', }, - // success: { - // main: '#16a085', - // }, - error: { - main: '#e74c3c', + success: { + main: '#62c462', + }, + error: { + main: '#ee5f5b', + }, + warning: { + main: '#f89406', }, - // warning: { - // main: '#ffa84a', - // }, }, components: { MuiDrawer: { styleOverrides: { paper: { - backgroundColor: 'rgb(28, 33, 40)', + backgroundColor: '#272b30', color: 'white', }, }, @@ -79,12 +79,12 @@ export default function App(props) { palette: { mode: 'light', background: { - drawer: '#3a3f51', - header: '#536067', + drawer: '#333333', + header: '#333333', tableBody: '#ffffff', - tableHeader: '#3a3f51', - details: '#3a3f51', - detailsContent: '#3a3f51', + tableHeader: '#333333', + details: '#333333', + detailsContent: '#333333', }, action: { // disabledBackground: 'set color of background here', @@ -110,7 +110,7 @@ export default function App(props) { MuiDrawer: { styleOverrides: { paper: { - backgroundColor: '#3a3f51', + backgroundColor: '#333333', color: 'white', }, }, diff --git a/frontend/src/components/AccountDetails.js b/frontend/src/components/AccountDetails.js index c7405ae..21edc6f 100644 --- a/frontend/src/components/AccountDetails.js +++ b/frontend/src/components/AccountDetails.js @@ -1,13 +1,13 @@ import React, { useState, useEffect } from 'react' import Box from '@mui/material/Box' import { useSelector, useDispatch } from 'react-redux' -import { getBalanceColor, FromAPI, intlFormat } from '../utils/Currency' +import { FromAPI, intlFormat, inputToDinero } from '../utils/Currency' import { useTheme } from '@mui/styles' import Stack from '@mui/material/Stack' import Button from '@mui/material/Button' import Typography from '@mui/material/Typography' import Divider from '@mui/material/Divider' -import { accountsSelectors, editAccount } from '../redux/slices/Accounts' +import { accountsSelectors, editAccount, transactionsSelectors } from '../redux/slices/Accounts' import TextField from '@mui/material/TextField' import Popover from '@mui/material/Popover' import { usePopupState, bindTrigger, bindPopover } from 'material-ui-popup-state/hooks' @@ -16,11 +16,24 @@ import { createSelector } from '@reduxjs/toolkit' import Paper from '@mui/material/Paper' import BalanceCalculation from './AccountTable/BalanceCalculation' import EditIcon from '@mui/icons-material/Edit' +import Card from '@mui/material/Card' +import CardHeader from '@mui/material/CardHeader' +import CardMedia from '@mui/material/CardMedia' +import CardContent from '@mui/material/CardContent' +import CardActions from '@mui/material/CardActions' +import Table from '@mui/material/Table' +import TableContainer from '@mui/material/TableContainer' +import TableRow from '@mui/material/TableRow' +import TableCell from '@mui/material/TableCell' +import { add } from 'dinero.js' +import { formatMonthFromDateString } from '../utils/Date' export default function BudgetDetails({ accountId, name }) { const theme = useTheme() const dispatch = useDispatch() + const month = useSelector(state => state.budgets.currentMonth) + const categories = useSelector(state => state.categories.entities) const selectAccount = createSelector( [(state, accountId) => accountsSelectors.selectById(state, accountId)], account => FromAPI.transformAccount(account), @@ -47,68 +60,97 @@ export default function BudgetDetails({ accountId, name }) { dispatch(editAccount({ id: account.id, name: accountName })) } - const pendingTransactions = useSelector( - state => - Object.values(state.accounts.entities[accountId].transactions.entities).filter(trx => trx.status === 0).length, + const transactions = useSelector(state => { + const monthCheck = month.split('-') + return Object.values(account.transactions.entities).filter(trx => { + const trxDate = trx.date.split('-') + if (trxDate[0] === monthCheck[0] && trxDate[1] === monthCheck[1]) { + return true + } + + return false + }) + }) + + const [income, activity, pending] = transactions.reduce( + (vals, trx) => { + if (formatMonthFromDateString(trx.date) !== month) { + return vals + } + + if (!trx.categoryId) { + // No category === transfer + return vals + } + + if (trx.status === 0) { + vals[2]++ + } + + trx = FromAPI.transformTransaction(trx) + if (categories[trx.categoryId].inflow === true) { + vals[0] = add(vals[0], trx.amount) + } else { + vals[1] = add(vals[1], trx.amount) + } + + return vals + }, + [inputToDinero(0), inputToDinero(0), 0], ) return ( - + - - - - - {account.name} - - - {/* */} - - - - - setAccountName(e.target.value)} - /> - - - + + + + {account.name} + + + + setAccountName(e.target.value)} + /> + + + + + - + } + sx={{ + backgroundColor: theme.palette.success.main, + p: 1, + }} + /> - - - - - - )} + + + + {selectedCategory ? `${selectedCategory.name} Activity` : 'Activity'} + + } + sx={{ + backgroundColor: theme.palette.error.main, + // color: 'black', + p: 1, + }} + /> + + + + + {isPositive(underfunded) && !isZero(underfunded) && ( - You have overspent your budget this month! Your budget may not be accurate until you resolve any negative - balances. + You are {intlFormat(underfunded)} in self debt! Your budget may not be accurate until you resolve any + negative balances. )} diff --git a/frontend/src/components/BudgetMonthNavigator.js b/frontend/src/components/BudgetMonthNavigator.js index 2bc11ca..bff0030 100644 --- a/frontend/src/components/BudgetMonthNavigator.js +++ b/frontend/src/components/BudgetMonthNavigator.js @@ -69,71 +69,63 @@ export default function BudgetMonthNavigator({ mini }) { } return ( - - + + navigateMonth(-1)} + sx={{ + fontSize: theme.typography.h6.fontSize, + color: 'white', + }} > - - navigateMonth(-1)} + + + + + - - - - - - - navigateMonth(1)} - sx={{ - fontSize: theme.typography.h6.fontSize, - // [`.Mui-disabled`]: { color: theme.palette.grey[500] }, - color: 'white', - }} + - + + navigateMonth(1)} + sx={{ + fontSize: theme.typography.h6.fontSize, + // [`.Mui-disabled`]: { color: theme.palette.grey[500] }, + color: 'white', + }} + > + + + ) } diff --git a/frontend/src/components/BudgetTable/BudgetMonthCalculation.js b/frontend/src/components/BudgetTable/BudgetMonthCalculation.js index 8c5543d..95f11ca 100644 --- a/frontend/src/components/BudgetTable/BudgetMonthCalculation.js +++ b/frontend/src/components/BudgetTable/BudgetMonthCalculation.js @@ -20,7 +20,7 @@ export default function BudgetMonthCalculation({ account }) { const activity = budgetMonth ? valueToDinero(budgetMonth.activity) : inputToDinero(0) return ( - +
{popupState => ( <> - + ENVELOPE @@ -531,14 +527,14 @@ export default function BudgetTable(props) { sx={{ backgroundColor: theme.palette.background.tableBody, display: 'grid', - // gridTemplateColums: '1fr', - // gridTemplateRows: 'auto 1fr auto', + gridTemplateColums: '1fr', + gridTemplateRows: 'auto 1fr auto', height: '100vh', }} > - {/* */} + {/* - {/* */} + */} diff --git a/frontend/src/components/BudgetTable/BudgetTableHeader.js b/frontend/src/components/BudgetTable/BudgetTableHeader.js index 1797e8c..9cce905 100644 --- a/frontend/src/components/BudgetTable/BudgetTableHeader.js +++ b/frontend/src/components/BudgetTable/BudgetTableHeader.js @@ -12,9 +12,18 @@ import Typography from '@mui/material/Typography' import { usePopupState, bindTrigger } from 'material-ui-popup-state/hooks' import Stack from '@mui/material/Stack' import Box from '@mui/material/Box' +import Paper from '@mui/material/Paper' +import Card from '@mui/material/Card' +import CardHeader from '@mui/material/CardHeader' +import CardMedia from '@mui/material/CardMedia' +import CardContent from '@mui/material/CardContent' +import CardActions from '@mui/material/CardActions' import ExpandMore from '@mui/icons-material/ExpandMore' import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIosNew' import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos' +import BudgetMonthNavigator from '../BudgetMonthNavigator' +import BudgetMonthCalculation from './BudgetMonthCalculation' +import Divider from '@mui/material/Divider' export default function BudgetTableHeader(props) { const theme = useTheme() @@ -26,27 +35,6 @@ export default function BudgetTableHeader(props) { const toBeBudgeted = budget ? valueToDinero(budget.toBeBudgeted) : inputToDinero(0) - const nextMonth = getDateFromString(month) - nextMonth.setMonth(nextMonth.getMonth() + 1) - const nextMonthDisabled = !availableMonths.includes(formatMonthFromDateString(nextMonth)) - - const prevMonth = getDateFromString(month) - prevMonth.setMonth(prevMonth.getMonth() - 1) - const prevMonthDisabled = !availableMonths.includes(formatMonthFromDateString(prevMonth)) - - const monthPickerPopupState = usePopupState({ - variant: 'popover', - popupId: 'monthPicker', - }) - - const navigateMonth = direction => { - props.onMonthNavigate(true) - const monthDate = new Date(Date.UTC(...month.split('-'))) - monthDate.setDate(1) - monthDate.setMonth(monthDate.getMonth() + direction) - dispatch(setCurrentMonth({ month: formatMonthFromDateString(monthDate) })) - } - const isToday = month === formatMonthFromDateString(new Date()) return ( @@ -56,96 +44,56 @@ export default function BudgetTableHeader(props) { backgroundColor: theme.palette.background.tableHeader, }} > - -
- -
- navigateMonth(-1)} - sx={{ - fontSize: theme.typography.h6.fontSize, - color: 'white', - }} - > - - - - navigateMonth(1)} - sx={{ - fontSize: theme.typography.h6.fontSize, - // [`.Mui-disabled`]: { color: theme.palette.grey[500] }, - color: 'white', - }} - > - - - {isToday === false && ( - - )} -
-
+ + - + Available} + sx={{ + backgroundColor: 'green', + p: 1, + }} + /> + {intlFormat(toBeBudgeted)} + */} + + + + + + Available + + + + + + + + {intlFormat(toBeBudgeted)} + + + + + + - - - {intlFormat(toBeBudgeted)} - - - Available To Budget - - - + + ) diff --git a/frontend/src/components/CategoryMonthActivity.js b/frontend/src/components/CategoryMonthActivity.js index c4f1170..78c0fd0 100644 --- a/frontend/src/components/CategoryMonthActivity.js +++ b/frontend/src/components/CategoryMonthActivity.js @@ -58,22 +58,6 @@ export default function CategoryMonthActivity(props) {
- - - - - Payee - - - Amount - - - - {transactions.map(transaction => { transaction = FromAPI.transformTransaction(transaction) diff --git a/frontend/src/components/Drawer.js b/frontend/src/components/Drawer.js index 2c4fee9..32bf1f6 100644 --- a/frontend/src/components/Drawer.js +++ b/frontend/src/components/Drawer.js @@ -32,6 +32,7 @@ import Avatar from '@mui/material/Avatar' import ChevronLeftIcon from '@mui/icons-material/ChevronLeft' import ChevronRightIcon from '@mui/icons-material/ChevronRight' import AccountBalanceIcon from '@mui/icons-material/AccountBalance' +import BudgetMonthNavigator from './BudgetMonthNavigator' const drawerWidth = 300 @@ -131,11 +132,6 @@ export default function AppDrawer(props) { } const AccountList = (label, accounts) => { - const balance = accounts.reduce((total, account) => { - return add(valueToDinero(account.balance), total) - }, inputToDinero(0)) - const balanceColor = isNegative(balance) ? theme.palette.error.main : theme.palette.secondary.main - const key = label.replace(' ', '_') return ( @@ -150,21 +146,7 @@ export default function AppDrawer(props) { )} - - {label} - - - {intlFormat(balance)} - - - } - /> + )} {!drawerOpen && ( @@ -228,6 +210,7 @@ export default function AppDrawer(props) { selected={selectedItem === `account-${account.id}`} onClick={() => listItemClicked(`account-${account.id}`, `/accounts/${account.id}`)} draggable="true" + sx={{ ...(drawerOpen && { pl: 5 }) }} onDragStart={e => { DragState.account = account }} @@ -251,40 +234,22 @@ export default function AppDrawer(props) { )} {drawerOpen === true && ( - -
- -
- -
- {/* {selectedItem === `account-${account.id}` && ( - - )} */} - -
-
+ {intlFormat(balance)}} + primaryTypographyProps={{ + style: { + fontWeight: 'bold', + }, + }} + /> )} ) } + console.log(theme) + if (!budget) { return <> } @@ -319,10 +284,12 @@ export default function AppDrawer(props) { - - + + + + {menuItems.map((menuItemConfig, index) => ( - {/* */} + {budgetAccounts.length > 0 && AccountList('ACCOUNTS', budgetAccounts)} + + {trackingAccounts.length > 0 && AccountList('OFF BUDGET', trackingAccounts)} + + {drawerOpen && ( @@ -385,7 +356,7 @@ export default function AppDrawer(props) { - + {/* {currentTheme === 'dark' ? ( @@ -396,7 +367,7 @@ export default function AppDrawer(props) { - + */} diff --git a/frontend/src/components/ReconcileForm.js b/frontend/src/components/ReconcileForm.js index b08f9ec..a66375c 100644 --- a/frontend/src/components/ReconcileForm.js +++ b/frontend/src/components/ReconcileForm.js @@ -55,8 +55,8 @@ export default function ReconcileForm(props) { {balanceCorrectAnswer === null && ( - Is your current account balance - {intlFormat(props.balance)}? + Is this your current balance? + {intlFormat(props.balance)}