another round of UI updates

This commit is contained in:
Alex Phillips 2022-02-12 09:50:35 -05:00
parent c980f515b9
commit 2abfafee23
14 changed files with 460 additions and 442 deletions

View File

@ -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',
},
},

View File

@ -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 (
<Stack
direction="column"
justifyContent="space-between"
alignItems="center"
spacing={2}
sx={{ px: 2, pb: 2, height: '100%' }}
>
<Stack direction="column" justifyContent="flex-start" alignItems="center" spacing={2} sx={{ p: 2, height: '100%' }}>
<Box sx={{ width: '100%' }}>
<Paper sx={{ p: 2, m: 2 }}>
<Stack direction="row" justifyContent="space-between" alignItems="center" sx={{ pb: 2 }}>
<Stack
direction="row"
justifyContent="flex-start"
alignItems="center"
{...bindTrigger(editAccountPopupState)}
sx={{ width: '100%', pr: 2 }}
>
<Typography
variant="h5"
sx={{ fontWeight: 'bold', color: 'white', cursor: 'pointer', display: 'inline-block', pr: 2 }}
>
{account.name}
</Typography>
{/* <EditIcon sx={{ cursor: 'pointer' }} /> */}
</Stack>
<Popover
{...bindPopover(editAccountPopupState)}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
>
<Box sx={{ p: 2 }}>
<TextField
autoFocus
margin="dense"
id="account-name"
label="Account Name"
type="text"
fullWidth
variant="standard"
value={accountName}
onChange={e => setAccountName(e.target.value)}
/>
<Stack direction="row" justifyContent="flex-end" alignItems="center" spacing={2}>
<Button size="small" sx={{ p: 1 }} onClick={editAccountName}>
Save
</Button>
</Stack>
<Card sx={{ mx: 2 }}>
<CardHeader
title={
<Box>
<Box
{...bindTrigger(editAccountPopupState)}
sx={{ fontWeight: 'bold', fontSize: theme.typography.h6.fontSize, cursor: 'pointer' }}
>
{account.name}
</Box>
<Popover
{...bindPopover(editAccountPopupState)}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
>
<Box sx={{ p: 2 }}>
<TextField
autoFocus
margin="dense"
id="account-name"
label="Account Name"
type="text"
fullWidth
variant="standard"
value={accountName}
onChange={e => setAccountName(e.target.value)}
/>
<Stack direction="row" justifyContent="flex-end" alignItems="center" spacing={2}>
<Button size="small" sx={{ p: 1 }} onClick={editAccountName}>
Save
</Button>
</Stack>
</Box>
</Popover>
</Box>
</Popover>
}
sx={{
backgroundColor: theme.palette.success.main,
p: 1,
}}
/>
<Box>
<Button {...bindTrigger(reconcilePopupState)} color="primary" variant="outlined">
<CardContent sx={{ p: '10px !important' }}>
<BalanceCalculation account={account} />
<Box sx={{ pt: 2 }}>
<Button {...bindTrigger(reconcilePopupState)} color="secondary" variant="outlined">
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
Reconcile
</Typography>
@ -120,21 +162,62 @@ export default function BudgetDetails({ accountId, name }) {
balance={account.cleared}
/>
</Box>
</Stack>
</CardContent>
</Card>
</Box>
<BalanceCalculation account={account} />
<Box sx={{ width: '100%' }}>
<Card sx={{ mx: 2 }}>
<CardHeader
title={
<Box sx={{ fontWeight: 'bold', fontSize: theme.typography.h6.fontSize }}>{`${new Date(
Date.UTC(...month.split('-')),
).toLocaleDateString(undefined, {
month: 'long',
})} Activity`}</Box>
}
sx={{
backgroundColor: '#5bc0de',
p: 1,
}}
/>
<Stack
direction="row"
justifyContent="space-between"
alignItems="center"
sx={{ width: '100%', mt: 1, pt: 1, borderTop: `1px solid ${theme.palette.action.disabled}` }}
>
<CardContent sx={{ p: '10px !important' }}>
<TableContainer>
<Table size="small">
<TableRow>
<TableCell>Transactions</TableCell>
<TableCell sx={{ textAlign: 'right' }}>{transactions.length}</TableCell>
</TableRow>
<TableRow>
<TableCell>Pending</TableCell>
<TableCell sx={{ textAlign: 'right' }}>{pending}</TableCell>
</TableRow>
<TableRow>
<TableCell>Income</TableCell>
<TableCell sx={{ textAlign: 'right' }}>{intlFormat(income)}</TableCell>
</TableRow>
<TableRow>
<TableCell>Activity</TableCell>
<TableCell sx={{ textAlign: 'right' }}>{intlFormat(activity)}</TableCell>
</TableRow>
</Table>
</TableContainer>
</CardContent>
</Card>
</Box>
{/* <Box sx={{ width: '100%' }}>
<Paper sx={{ p: 2, mx: 2 }}>
<Stack direction="row" justifyContent="space-between" alignItems="center" sx={{ width: '100%' }}>
<Box>Pending Transactions</Box>
<Box> {pendingTransactions}</Box>
</Stack>
</Paper>
</Box>
</Box> */}
</Stack>
)
}

View File

@ -5,6 +5,7 @@ import MaterialTable, {
MTableEditField,
MTableToolbar,
MTableEditRow,
MTableActions,
} from '@material-table/core'
import { useDispatch, useSelector } from 'react-redux'
import {
@ -57,6 +58,8 @@ import { styled } from '@mui/material/styles'
import UploadIcon from '@mui/icons-material/Upload'
import ImportCSV from '../ImportCSV'
import AccountTableHeader from './AccountTableHeader'
import MoreVertIcon from '@mui/icons-material/MoreVert'
import DeleteOutline from '@mui/icons-material/DeleteOutline'
const StyledMTableToolbar = styled(MTableToolbar)(({ theme }) => ({
backgroundColor: theme.palette.background.tableBody,
@ -857,7 +860,7 @@ export default function Account(props) {
onSelectionChange={onSelectionChange}
localization={{
header: {
// actions: '',
actions: '',
},
body: {
emptyDataSourceMessage: 'No transactions to display',
@ -903,6 +906,14 @@ export default function Account(props) {
/>
),
EditRow: props => <MTableEditRow {...props} />,
Actions: props => {
console.log(props)
if (typeof props.actions[1] !== 'function') {
return <MTableActions {...props} />
}
return <></>
},
}}
icons={TableIcons}
columns={columns}

View File

@ -106,7 +106,7 @@ export default function BalanceCalculation({ account }) {
fontWeight: 'bold',
}}
>
Working Balance
Balance
</Typography>
</Stack>
</div>

View File

@ -3,7 +3,7 @@ import { useSelector, useDispatch } from 'react-redux'
import { inputToDinero, intlFormat, valueToDinero, getBalanceColor } from '../utils/Currency'
import { useTheme } from '@mui/styles'
import Stack from '@mui/material/Stack'
import { isPositive, isZero } from 'dinero.js'
import { isPositive, isNegative, isZero, add } from 'dinero.js'
import Alert from '@mui/material/Alert'
import Typography from '@mui/material/Typography'
import { selectActiveBudget } from '../redux/slices/Budgets'
@ -11,16 +11,29 @@ import Paper from '@mui/material/Paper'
import BudgetMonthCalculation from './BudgetTable/BudgetMonthCalculation'
import CategoryMonthActivity from './CategoryMonthActivity'
import BudgetMonthNavigator from './BudgetMonthNavigator'
import Card from '@mui/material/Card'
import CardActions from '@mui/material/CardActions'
import CardContent from '@mui/material/CardContent'
import Button from '@mui/material/Button'
import { setSelectedCategory } from '../redux/slices/Categories'
import { accountsSelectors } from '../redux/slices/Accounts'
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 Divider from '@mui/material/Divider'
export default function BudgetDetails(props) {
const theme = useTheme()
const dispatch = useDispatch()
const accounts = useSelector(accountsSelectors.selectAll)
const balance = accounts.reduce((total, account) => {
if (account.type === 2) {
return total
}
return add(valueToDinero(account.balance), total)
}, inputToDinero(0))
const balanceColor = isNegative(balance) ? theme.palette.error.main : theme.palette.secondary.main
const month = useSelector(state => state.budgets.currentMonth)
const budgetMonth = useSelector(state => {
return state.budgetMonths.entities[month] || null
@ -47,103 +60,124 @@ export default function BudgetDetails(props) {
justifyContent="space-between"
alignItems="center"
spacing={2}
sx={{ px: 2, height: '100%' }}
sx={{ p: 2, height: '100%' }}
>
<Box sx={{ width: '100%' }}>
<Stack direction="column" justifyContent="flex-start" alignItems="center" spacing={2} sx={{ width: '100%' }}>
<BudgetMonthNavigator mini={false} />
<Box sx={{ width: '100%' }}>
<Paper sx={{ p: 2, mx: 2 }}>
<Stack direction="row" spacing={4} justifyContent="space-between" alignItems="center">
<Box>
<Typography
style={{
fontSize: theme.typography.h6.fontSize,
}}
>
Available
</Typography>
</Box>
<Box>
<Typography
style={{
fontSize: theme.typography.h5.fontSize,
fontWeight: 'bold',
color: !isZero(toBeBudgeted) ? getBalanceColor(toBeBudgeted, theme) : theme.palette.grey[500],
}}
>
{intlFormat(toBeBudgeted)}
</Typography>
</Box>
</Stack>
</Paper>
</Box>
<Box sx={{ width: '100%' }}>
<Paper sx={{ p: 2, mx: 2 }}>
<Typography
<Card sx={{ mx: 2 }}>
<CardHeader
title={<Box sx={{ fontSize: theme.typography.h6.fontSize, fontWeight: 'bold' }}>Balance</Box>}
sx={{
fontSize: theme.typography.h6.fontSize,
pb: 2,
backgroundColor: theme.palette.success.main,
// color: 'black',
p: 1,
}}
>
Monthly Summary
</Typography>
/>
<CardContent sx={{ p: '10px !important' }}>
<Stack direction="row" spacing={4} justifyContent="space-between" alignItems="center">
<Box>
<Typography
style={{
fontSize: theme.typography.h6.fontSize,
}}
>
Available
</Typography>
</Box>
<BudgetMonthCalculation />
<Box>
<Typography
style={{
fontSize: theme.typography.h5.fontSize,
fontWeight: 'bold',
color: !isZero(toBeBudgeted) ? getBalanceColor(toBeBudgeted, theme) : theme.palette.grey[500],
}}
>
{intlFormat(toBeBudgeted)}
</Typography>
</Box>
</Stack>
<Stack
direction="row"
justifyContent="space-between"
alignItems="center"
sx={{ width: '100%', mt: 1, pt: 1, borderTop: `1px solid ${theme.palette.action.disabled}` }}
>
<Box>Underfunded</Box>
<Box> {intlFormat(underfunded)}</Box>
</Stack>
</Paper>
<Box sx={{ py: 1 }}>
<Divider />
</Box>
<Stack direction="row" spacing={4} justifyContent="space-between" alignItems="center">
<Box>
<Typography
style={{
fontSize: theme.typography.subtitle1.fontSize,
}}
>
Accounts
</Typography>
</Box>
<Box>
<Typography
style={{
fontSize: theme.typography.subtitle1.fontSize,
// fontWeight: 'bold',
// color: balanceColor,
}}
>
{intlFormat(balance)}
</Typography>
</Box>
</Stack>
</CardContent>
</Card>
</Box>
{selectedCategory && (
<Box sx={{ width: '100%' }}>
<Card sx={{ mx: 2 }}>
<CardContent>
<Typography
sx={{
fontSize: theme.typography.h6.fontSize,
pb: 1,
}}
>
{selectedCategory.name} Activity
</Typography>
<Box sx={{ width: '100%' }}>
<Card sx={{ mx: 2 }}>
<CardHeader
title={<Box sx={{ fontSize: theme.typography.h6.fontSize, fontWeight: 'bold' }}>Monthly Summary</Box>}
sx={{
backgroundColor: '#5bc0de',
// color: 'black',
p: 1,
}}
/>
<CardContent sx={{ p: '10px !important' }}>
<BudgetMonthCalculation />
</CardContent>
</Card>
</Box>
<CategoryMonthActivity />
</CardContent>
<CardActions>
<Button size="small" onClick={clearSelectedCategory}>
Close
</Button>
</CardActions>
</Card>
</Box>
)}
<Box sx={{ width: '100%' }}>
<Card sx={{ mx: 2 }}>
<CardHeader
title={
<Box sx={{ fontSize: theme.typography.h6.fontSize, fontWeight: 'bold' }}>
{selectedCategory ? `${selectedCategory.name} Activity` : 'Activity'}
</Box>
}
sx={{
backgroundColor: theme.palette.error.main,
// color: 'black',
p: 1,
}}
/>
<CardContent sx={{ p: '10px !important' }}>
<CategoryMonthActivity />
</CardContent>
</Card>
</Box>
</Stack>
</Box>
<Box
sx={{
m: 4,
pb: 2,
width: '100%',
}}
>
{isPositive(underfunded) && !isZero(underfunded) && (
<Alert variant="filled" severity="error">
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.
</Alert>
)}
</Box>

View File

@ -69,71 +69,63 @@ export default function BudgetMonthNavigator({ mini }) {
}
return (
<Box sx={{ width: '100%' }}>
<Stack
className="budget-month-navigation"
direction="row"
justifyContent="space-evenly"
alignItems="center"
sx={{ width: '100%', margin: 'auto' }}
<Stack className="budget-month-navigation" direction="row" justifyContent="space-evenly" alignItems="center">
<BudgetMonthPicker
popupState={monthPickerPopupState}
currentMonth={month}
minDate={availableMonths[0]}
maxDate={availableMonths[availableMonths.length - 1]}
/>
<IconButton
disabled={prevMonthDisabled}
onClick={() => navigateMonth(-1)}
sx={{
fontSize: theme.typography.h6.fontSize,
color: 'white',
}}
>
<BudgetMonthPicker
popupState={monthPickerPopupState}
currentMonth={month}
minDate={availableMonths[0]}
maxDate={availableMonths[availableMonths.length - 1]}
/>
<IconButton
disabled={prevMonthDisabled}
onClick={() => navigateMonth(-1)}
<ArrowBackIosIcon fontSize="large" variant="outlined" />
</IconButton>
<Stack direction="column" justifyContent="space-around" alignItems="center" sx={{ minHeight: '80px' }}>
<Button
{...bindTrigger(monthPickerPopupState)}
sx={{
fontSize: theme.typography.h6.fontSize,
color: 'white',
fontWeight: 'bold',
color: theme.palette.secondary.main,
}}
>
<ArrowBackIosIcon fontSize="large" variant="outlined" />
</IconButton>
{new Date(Date.UTC(...month.split('-'))).toLocaleDateString(undefined, {
year: 'numeric',
month: 'long',
})}
</Button>
<Stack direction="column" justifyContent="space-around" alignItems="center" sx={{ minHeight: '80px' }}>
<Button
{...bindTrigger(monthPickerPopupState)}
sx={{
fontSize: theme.typography.h6.fontSize,
fontWeight: 'bold',
color: theme.palette.secondary.main,
}}
>
{new Date(Date.UTC(...month.split('-'))).toLocaleDateString(undefined, {
year: 'numeric',
month: 'long',
})}
</Button>
<Button
variant="outlined"
size="small"
color="secondary"
disabled={isToday}
onClick={() => dispatch(setCurrentMonth({ month: formatMonthFromDateString(new Date()) }))}
>
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
Jump to Today
</Typography>
</Button>
</Stack>
<IconButton
disabled={nextMonthDisabled}
onClick={() => navigateMonth(1)}
sx={{
fontSize: theme.typography.h6.fontSize,
// [`.Mui-disabled`]: { color: theme.palette.grey[500] },
color: 'white',
}}
<Button
variant="outlined"
size="small"
color="secondary"
disabled={isToday}
onClick={() => dispatch(setCurrentMonth({ month: formatMonthFromDateString(new Date()) }))}
>
<ArrowForwardIosIcon fontSize="large" />
</IconButton>
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
Jump to Today
</Typography>
</Button>
</Stack>
</Box>
<IconButton
disabled={nextMonthDisabled}
onClick={() => navigateMonth(1)}
sx={{
fontSize: theme.typography.h6.fontSize,
// [`.Mui-disabled`]: { color: theme.palette.grey[500] },
color: 'white',
}}
>
<ArrowForwardIosIcon fontSize="large" />
</IconButton>
</Stack>
)
}

View File

@ -20,7 +20,7 @@ export default function BudgetMonthCalculation({ account }) {
const activity = budgetMonth ? valueToDinero(budgetMonth.activity) : inputToDinero(0)
return (
<Stack direction="row" justifyContent="space-evenly" alignItems="center" spacing={0}>
<Stack direction="row" justifyContent="space-evenly" alignItems="center" spacing={2}>
<div>
<Stack
direction="column"

View File

@ -225,18 +225,14 @@ export default function BudgetTable(props) {
<PopupState variant="popover" popupId="popover-category-group">
{popupState => (
<>
<Stack
direction="row"
alignItems="center"
spacing={0.5}
{...bindTrigger(popupState)}
sx={{ cursor: 'pointer' }}
>
<Stack direction="row" alignItems="center" spacing={0.5}>
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
ENVELOPE
</Typography>
<AddCircleIcon
{...bindTrigger(popupState)}
style={{
cursor: 'pointer',
fontSize: theme.typography.subtitle2.fontSize,
}}
/>
@ -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',
}}
>
{/* <BudgetTableHeader /> */}
{/* <BudgetTableHeader />
{/* <Divider /> */}
<Divider /> */}
<TableContainer component={Box}>
<Table stickyHeader {...getTableProps()} size="small">

View File

@ -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,
}}
>
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2} sx={{ p: 2 }}>
<div>
<BudgetMonthPicker
popupState={monthPickerPopupState}
currentMonth={month}
minDate={availableMonths[0]}
maxDate={availableMonths[availableMonths.length - 1]}
/>
<div className="budget-month-navigation">
<IconButton
disabled={prevMonthDisabled}
onClick={() => navigateMonth(-1)}
sx={{
fontSize: theme.typography.h6.fontSize,
color: 'white',
}}
>
<ArrowBackIosIcon fontSize="large" variant="outlined" />
</IconButton>
<Button
{...bindTrigger(monthPickerPopupState)}
sx={{
fontSize: theme.typography.h6.fontSize,
fontWeight: 'bold',
color: theme.palette.secondary.main,
pl: 2,
}}
>
{new Date(Date.UTC(...month.split('-'))).toLocaleDateString(undefined, {
year: 'numeric',
month: 'short',
})}
</Button>
<IconButton
disabled={nextMonthDisabled}
onClick={() => navigateMonth(1)}
sx={{
fontSize: theme.typography.h6.fontSize,
// [`.Mui-disabled`]: { color: theme.palette.grey[500] },
color: 'white',
}}
>
<ArrowForwardIosIcon fontSize="large" />
</IconButton>
{isToday === false && (
<Button
variant="outlined"
size="small"
color="secondary"
onClick={() => dispatch(setCurrentMonth({ month: formatMonthFromDateString(new Date()) }))}
sx={{ ml: 1 }}
>
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
Today
</Typography>
</Button>
)}
</div>
</div>
<Stack direction="row" justifyContent="space-around" alignItems="center" spacing={2} sx={{ p: 2 }}>
<BudgetMonthNavigator />
<Box
{/* <Card sx={{ minWidth: 200 }}>
<CardHeader
title={<Box sx={{ fontSize: theme.typography.subtitle1.fontSize }}>Available</Box>}
sx={{
backgroundColor: 'green',
p: 1,
}}
/>
<CardContent sx={{ p: '10px !important' }}>{intlFormat(toBeBudgeted)}</CardContent>
</Card> */}
<Paper sx={{ p: 2, mx: 2 }}>
<Stack direction="row" spacing={4} justifyContent="space-between" alignItems="center">
<Box>
<Typography
style={{
fontSize: theme.typography.h6.fontSize,
}}
>
Available
</Typography>
</Box>
<Divider />
<Box>
<Typography
style={{
fontSize: theme.typography.h5.fontSize,
fontWeight: 'bold',
color: !isZero(toBeBudgeted) ? getBalanceColor(toBeBudgeted, theme) : theme.palette.grey[500],
}}
>
{intlFormat(toBeBudgeted)}
</Typography>
</Box>
</Stack>
</Paper>
<Paper
sx={{
py: 0.5,
py: 1,
px: 2,
borderRadius: 1.5,
// backgroundColor: !isZero(toBeBudgeted) ? getBalanceColor(toBeBudgeted, theme) : theme.palette.grey[500],
}}
>
<Stack direction="column" justifyContent="center" alignItems="center" spacing={0}>
<Typography
style={{
fontSize: theme.typography.h5.fontSize,
fontWeight: 'bold',
// color: 'black',
color: !isZero(toBeBudgeted) ? getBalanceColor(toBeBudgeted, theme) : theme.palette.grey[500],
}}
>
{intlFormat(toBeBudgeted)}
</Typography>
<Typography
style={{
fontSize: theme.typography.subtitle1.fontSize,
// color: 'black',
color: 'white',
}}
>
Available To Budget
</Typography>
</Stack>
</Box>
<BudgetMonthCalculation />
</Paper>
</Stack>
</Box>
)

View File

@ -58,22 +58,6 @@ export default function CategoryMonthActivity(props) {
<Box>
<TableContainer sx={{ maxHeight: 300 }}>
<Table stickyHeader size="small">
<TableHead>
<TableRow>
<TableCell
sx={{ backgroundColor: theme.palette.background.tableHeader, pl: 1, pr: 0, width: 10, color: 'white' }}
></TableCell>
<TableCell sx={{ backgroundColor: theme.palette.background.tableHeader, color: 'white' }}>
Payee
</TableCell>
<TableCell
sx={{ backgroundColor: theme.palette.background.tableHeader, textAlign: 'right', color: 'white' }}
>
Amount
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{transactions.map(transaction => {
transaction = FromAPI.transformTransaction(transaction)

View File

@ -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) {
<ChevronRightIcon sx={{ color: theme.palette.secondary.main }} fontSize="small" />
)}
</ListItemIcon>
<ListItemText
primary={
<Stack direction="row" justifyContent="space-between" alignItems="center">
<Typography>{label}</Typography>
<Typography
sx={{
color: balanceColor,
}}
>
{intlFormat(balance)}
</Typography>
</Stack>
}
/>
<ListItemText primary={label} />
</>
)}
{!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) {
</ListItemIcon>
)}
{drawerOpen === true && (
<Stack direction="row" justifyContent="space-between" alignItems="center" sx={{ width: '100%' }}>
<div>
<ListItemText
sx={{ maxWidth: 150 }}
primary={account.name}
primaryTypographyProps={{
style: {
fontWeight: 'bold',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
},
}}
/>
</div>
<div>
{/* {selectedItem === `account-${account.id}` && (
<BalanceCalculation account={FromAPI.transformAccount(account)} />
)} */}
<ListItemText
secondary={intlFormat(balance)}
secondaryTypographyProps={{
fontWeight: 'bold',
color: balanceColor,
}}
/>
</div>
</Stack>
<ListItemText
primary={account.name}
secondary={<Box sx={{ color: balanceColor }}>{intlFormat(balance)}</Box>}
primaryTypographyProps={{
style: {
fontWeight: 'bold',
},
}}
/>
)}
</ListItem>
)
}
console.log(theme)
if (!budget) {
return <></>
}
@ -319,10 +284,12 @@ export default function AppDrawer(props) {
</ListItem>
</List>
<Box sx={{ pt: 2 }}>
<Divider />
<Box sx={{ ...(drawerOpen && { pb: 2 }) }}>
<BudgetMonthNavigator mini={!drawerOpen} />
</Box>
<Divider />
<List>
{menuItems.map((menuItemConfig, index) => (
<ListItem
@ -339,12 +306,16 @@ export default function AppDrawer(props) {
))}
</List>
{/* <Divider /> */}
<Divider />
{budgetAccounts.length > 0 && AccountList('ACCOUNTS', budgetAccounts)}
<Divider />
{trackingAccounts.length > 0 && AccountList('OFF BUDGET', trackingAccounts)}
<Divider />
<List dense={true}>
<ListItemButton>
{drawerOpen && (
@ -385,7 +356,7 @@ export default function AppDrawer(props) {
</ListItemButton>
</ListItem>
<ListItem disablePadding>
{/* <ListItem disablePadding>
<ListItemButton onClick={toggleTheme}>
<ListItemIcon>
{currentTheme === 'dark' ? (
@ -396,7 +367,7 @@ export default function AppDrawer(props) {
</ListItemIcon>
<ListItemText primary="Toggle Theme" />
</ListItemButton>
</ListItem>
</ListItem> */}
<ListItem disablePadding>
<ListItemButton onClick={logout}>

View File

@ -55,8 +55,8 @@ export default function ReconcileForm(props) {
<Box sx={{ p: 2 }}>
{balanceCorrectAnswer === null && (
<Stack direction="column" spacing={0.5} justifyContent="center" alignItems="center">
<Typography>Is your current account balance</Typography>
<Typography variant="h6">{intlFormat(props.balance)}?</Typography>
<Typography>Is this your current balance?</Typography>
<Typography variant="h6">{intlFormat(props.balance)}</Typography>
<ButtonGroup variant="contained" aria-label="outlined primary button group">
<Button size="small" onClick={submit}>
Yes

View File

@ -29,6 +29,17 @@ export default function Account(props) {
alignItems="flex-start"
sx={{ width: '100%', height: '100%' }}
>
<Box
sx={{
backgroundColor: theme.palette.background.tableBody,
width: '100%',
}}
>
<div style={{ maxWidth: '100%' }}>
<Box>{account && <AccountTable accountId={params.accountId} account={account} />}</Box>
</div>
</Box>
<Box
sx={{
backgroundColor: theme.palette.background.details,
@ -39,18 +50,6 @@ export default function Account(props) {
>
<AccountDetails accountId={params.accountId} name={account.name} />
</Box>
<Box
sx={{
backgroundColor: theme.palette.background.tableBody,
borderLeft: `1px solid ${theme.palette.action.disabledBackground}`,
width: '100%',
}}
>
<div style={{ maxWidth: '100%' }}>
<Box>{account && <AccountTable accountId={params.accountId} account={account} />}</Box>
</div>
</Box>
</Stack>
)
}

View File

@ -19,25 +19,25 @@ export default function Budget(props) {
<Box
sx={{
backgroundColor: theme.palette.background.details,
width: 600,
maxWidth: 600,
display: 'grid',
height: '100vh',
overflow: 'auto',
}}
>
<BudgetDetails />
</Box>
<Box
sx={{
backgroundColor: theme.palette.background.details,
borderLeft: `1px solid ${theme.palette.action.disabledBackground}`,
width: '100%',
}}
>
<BudgetTable index={0} />
</Box>
<Box
sx={{
backgroundColor: theme.palette.background.details,
width: 600,
maxWidth: 600,
display: 'grid',
height: '100vh',
overflow: 'auto',
borderLeft: `1px solid ${theme.palette.action.disabledBackground}`,
}}
>
<BudgetDetails />
</Box>
</Stack>
)
}