Skip to content

Adjust some styling and layouting issues in the front-end #25

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 14, 2024
13 changes: 12 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import TwoFactorCard from "./security/two-factor.card";
import SecurityRepository from "./core/repositories/security-repository";
import RestAPI from "./core/repositories/rest-api";
import { AxiosError } from "axios";
import { CurrencyRepository } from "./core/RestAPI";

const LoginCard = lazy(() => import("./security/login-card"));
const RegisterCard = lazy(() => import("./security/RegisterCard"));
Expand All @@ -45,9 +46,13 @@ function App() {
const authenticated = () => {
RestAPI.profile()
.then(() => {
console.log('Profile loaded')
setAuthenticate(true)
setTwoFactor(false)
CurrencyRepository.list().then(() => {
const profile: any = RestAPI.user()
profile.defaultCurrency = CurrencyRepository.cached(profile.currency)
})

})
.catch((ex: AxiosError) => {
if (ex.response?.status === 403) {
Expand Down Expand Up @@ -104,6 +109,12 @@ function App() {
);
}

if (sessionStorage.getItem('token')) {
return <div className='h-[100vh] w-full flex justify-center items-center'>
<Layout.Loading />
</div>
}

return (
<Suspense>
<BrowserRouter basename='/ui'>
Expand Down
2 changes: 1 addition & 1 deletion src/account/liability/liability-detail-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const LiabilityDetailView = () => {
<BreadCrumbItem label='page.nav.transactions'/>
</BreadCrumbs>

<div className="flex gap-2">
<div className="flex gap-2 flex-wrap">
<Layout.Card className='flex-1'>
<h1 className='font-bold'>{ account.name }</h1>
<div className="flex">
Expand Down
43 changes: 21 additions & 22 deletions src/config/global-chart-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,17 @@ const GlobalChartConfig = {
enabled: true,
usePointStyle: true,
position: 'nearest',
backgroundColor: 'white',
bodyColor: 'black',
titleColor: 'black',
borderColor: 'black',
borderWidth: .5,
callbacks: {
title: (context) => context.label,
label: (context) => {
const value = context.parsed?.y ?? context.parsed.value;
return `${value}`
},
labelPointStyle: (_) => {
return {
pointStyle: 'triangle',
Expand Down Expand Up @@ -189,28 +199,17 @@ const Service = {
}

export const defaultGraphColors = [
'#E0FFFF',
'#00CED1',
'#40E0D0',
'#48D1CC',
'#AFEEEE',
'#7FFFD4',
'#B0E0E6',
'#5F9EA0',
'#66CDAA',
'#3CB371',
'#20B2AA',
'#2F4F4F',
'#008080',
'#008B8B',
'#32CD32',
'#90EE90',
'#ADFF2F',
'#90EE90',
'#ADFF2F',
'#7FFF00',
'#7FFF00',
'#6B8E23',
'rgba(25, 25, 112, 0.8)', // Midnight Blue
'rgba(0, 0, 128, 0.8)', // Navy Blue
'rgba(0, 0, 139, 0.8)', // Dark Blue
'rgba(0, 0, 156, 0.8)', // Medium Blue
'rgba(0, 0, 205, 0.8)', // Medium Blue
'rgba(0, 0, 255, 0.8)', // Blue
'rgba(70, 130, 180, 0.8)', // Steel Blue
'rgba(100, 149, 237, 0.8)', // Cornflower Blue
'rgba(135, 206, 235, 0.8)', // Sky Blue
'rgba(135, 206, 250, 0.8)', // Light Sky Blue
'rgba(240, 248, 255, 0.8)', // Alice Blue
]

export {
Expand Down
12 changes: 11 additions & 1 deletion src/core/RestAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,20 @@ const TransactionRepository = (api => {
})(RestApi)

const CurrencyRepository = (api => {
let knownCurrencies = []
return {
list: () => api.get('settings/currencies'),
list: () => api.get('settings/currencies').then(currencies => {
knownCurrencies = currencies
return currencies
}),
get: code => api.get(`settings/currencies/${code}`),
change: (code, enabled) => api.patch(`settings/currencies/${code}`, { enabled: enabled })
.then(response => {
const currency = knownCurrencies.find(currency => currency.code === code)
currency.enabled = enabled
return response
}),
cached: (code) => knownCurrencies.find(currency => currency.code === code)
}
})(RestApi)

Expand Down
38 changes: 27 additions & 11 deletions src/core/graphs/categorized-pie-chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { isArray } from "chart.js/helpers";
import { Account } from "../types";
import StatisticalRepository from "../repositories/statistical-repository";
import { Chart } from "react-chartjs-2";
import { ChartData } from "chart.js";
import { ChartData, Tooltip, TooltipPosition } from "chart.js";
import { defaultGraphColors } from "../../config/global-chart-config";

type CategorizedPieChartProps = {
Expand All @@ -15,8 +15,17 @@ type CategorizedPieChartProps = {
accounts?: Account[] | Account
}

let lastPosition: TooltipPosition
(Tooltip.positioners as any)['center'] = (_: any[], eventPosition: any) => {
const chartArea = eventPosition.chart?.chartArea
if (!chartArea) return lastPosition

lastPosition = { x: chartArea.right / 2 - 40, y: chartArea.bottom / 2 }
return lastPosition
}

const CategorizedPieChart: FC<CategorizedPieChartProps> = ({ id, split, incomeOnly, accounts = [] }) => {
const [pieSeries, setPieSeries] = useState<ChartData | undefined>(undefined)
const [pieSeries, setPieSeries] = useState<ChartData<'doughnut'> | undefined>(undefined)
const [range] = useDateRange()

useEffect(() => {
Expand Down Expand Up @@ -44,39 +53,46 @@ const CategorizedPieChart: FC<CategorizedPieChartProps> = ({ id, split, incomeOn
})
}, [split, incomeOnly, range]) // eslint-disable-line react-hooks/exhaustive-deps

const currency = accounts && !isArray(accounts) ? accounts.account.currency : '€'

if (!pieSeries) return <Layout.Loading />
return <>
<Chart id={ id }
type='pie'
type='doughnut'
height={ 300 }
data={ pieSeries }
options={
{
cutout: '65%',
elements: {
arc: {
hoverOffset: 15,
borderWidth: .5,
backgroundColor: (context : any) => defaultGraphColors[context.dataIndex]
}
},
plugins: {
legend: {
display: true,
position: 'right'
display: false,
},
tooltip: {
backgroundColor: 'white',
bodyColor: 'black',
titleColor: 'black',
cornerRadius: 0,
caretSize: 0,
position: 'center',
bodyAlign: 'left',
callbacks: {
title: (context : any) => context.label,
label: (context: any) => {
if (accounts && !isArray(accounts)) {
return `${context.raw} ${accounts?.account?.currency}`
}

return context.raw
return ` ${currency}${context.raw}`
}
}
}
},
maintainAspectRatio: false
}}/>
} as any }/>
</>
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/layout/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const Card: FC<CardProps> = ({ title, actions, buttons, children, className = ''
{actions && <div className='font-normal text-sm'>{ actions }</div>}
</header>
)}
<article className='bg-white p-5 first:rounded-t-lg last:rounded-b-lg'>
<article className='bg-white p-4 first:rounded-t-lg last:rounded-b-lg'>
{children}
</article>
{buttons &&
Expand Down
31 changes: 31 additions & 0 deletions src/reports/budget-monthly/budget-chart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Chart } from "react-chartjs-2";
import { DefaultChartConfig, Service } from "../../config/global-chart-config";
import React from "react";
import { ChartData } from "chart.js";

const BudgetChart = ({ dataSet, currencySymbol = '' } : { dataSet: ChartData, currencySymbol: string }) => {
return <Chart type='line'
height={ 300 }
options={ Service.mergeOptions(DefaultChartConfig.line,{
scales: {
x: {
time: {
unit: 'month'
}
},
y: {
ticks: {
callback: (value: any) => `${currencySymbol}${value}`
}
}
},
plugins: {
legend: {
display: true
}
}
}) }
data={ dataSet } />
}

export default BudgetChart
29 changes: 5 additions & 24 deletions src/reports/budget-monthly/budget-yearly-expense.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,19 @@ import { Dates, Layout, Translations } from "../../core";
import { ChartData } from "chart.js";
import { Budget, BudgetExpense } from "../../core/types";
import StatisticalRepository from "../../core/repositories/statistical-repository";
import { Chart } from "react-chartjs-2";
import { DefaultChartConfig, Service } from "../../config/global-chart-config";
import BudgetChart from "./budget-chart";

type BudgetYearlyExpenseProps = {
year: number,
budgets: Budget[]
budgets: Budget[],
currencySymbol: string
}

const BudgetYearlyExpense = ({ year, budgets } : BudgetYearlyExpenseProps) => {
const BudgetYearlyExpense = ({ year, budgets, currencySymbol } : BudgetYearlyExpenseProps) => {
const [chartData, setChartData] = useState<ChartData | undefined>()

useEffect(() => {
if (budgets.length === 0) return
console.info(`BudgetYearlyExpense: ${year} ${budgets.length}`)
setChartData(undefined)

const uniqueExpenses = budgets.reduce((left, right) => [...left, ...right.expenses], new Array<BudgetExpense>())
Expand Down Expand Up @@ -54,25 +53,7 @@ const BudgetYearlyExpense = ({ year, budgets } : BudgetYearlyExpenseProps) => {
return <>
<Layout.Card title='page.reports.budget.expensePercent'>
{ !chartData && <Layout.Loading /> }
{ chartData && <>
<Chart type='line'
height={ 300 }
options={ Service.mergeOptions(DefaultChartConfig.line,{
scales: {
x: {
time: {
unit: 'month'
}
}
},
plugins: {
legend: {
display: true
}
}
}) }
data={ chartData } />
</> }
{ chartData && <BudgetChart dataSet={ chartData } currencySymbol={ currencySymbol } /> }
</Layout.Card>
</>
}
Expand Down
28 changes: 5 additions & 23 deletions src/reports/budget-monthly/budget-yearly-income.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import React, { useEffect, useState } from "react";
import { Dates, Layout, Statistical, Translations } from "../../core";
import { Budget } from "../../core/types";
import { ChartData } from "chart.js";
import { Chart } from "react-chartjs-2";
import { DefaultChartConfig, Service } from "../../config/global-chart-config";
import BudgetChart from "./budget-chart";

type BudgetYearlyExpenseProps = {
year: number,
budgets: Budget[]
budgets: Budget[],
currencySymbol: string
}

const YearlyIncomeGraphComponent = ({ year = 1970, budgets = [] } : BudgetYearlyExpenseProps) => {
const YearlyIncomeGraphComponent = ({ year = 1970, budgets = [], currencySymbol = '' } : BudgetYearlyExpenseProps) => {
const [chartData, setChartData] = useState<ChartData | undefined>()

useEffect(() => {
Expand Down Expand Up @@ -46,25 +46,7 @@ const YearlyIncomeGraphComponent = ({ year = 1970, budgets = [] } : BudgetYearly
return <>
<Layout.Card title='page.reports.budget.incomePercent'>
{ !chartData && <Layout.Loading /> }
{ chartData && <>
<Chart type='line'
height={ 300 }
options={ Service.mergeOptions(DefaultChartConfig.line,{
scales: {
x: {
time: {
unit: 'month'
}
}
},
plugins: {
legend: {
display: true
}
}
}) }
data={ chartData } />
</> }
{ chartData && <BudgetChart dataSet={ chartData } currencySymbol={ currencySymbol } /> }
</Layout.Card>
</>
}
Expand Down
10 changes: 8 additions & 2 deletions src/reports/budget-monthly/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ import BudgetYearlyExpense from "./budget-yearly-expense";

import '../../assets/css/BudgetReportView.scss'
import BudgetRepository from "../../core/repositories/budget.repository";
import { CurrencyRepository } from "../../core/RestAPI";

export const BudgetReportView = () => {
const [currencySymbol, setCurrencySymbol] = useState('')
const [range, setRange] = useState(() => Dates.Ranges.currentYear())
const { currency = 'EUR', year = new Date().getFullYear() } = useParams()
const [budgets, setBudgets] = useState([])
Expand All @@ -36,6 +38,10 @@ export const BudgetReportView = () => {
.catch(console.error)
}
}, [year])
useEffect(() => {
CurrencyRepository.get(currency)
.then((c) => setCurrencySymbol(c.symbol))
}, [currency])

const onDateChanged = ({
newYear = year,
Expand All @@ -60,8 +66,8 @@ export const BudgetReportView = () => {
</Layout.Grid>

<Layout.Grid type='column' minWidth='25em'>
<YearlyIncomeGraphComponent year={parseInt(year)} budgets={budgets}/>
<BudgetYearlyExpense year={parseInt(year)} budgets={budgets}/>
<YearlyIncomeGraphComponent year={parseInt(year)} budgets={budgets} currencySymbol={ currencySymbol } />
<BudgetYearlyExpense year={parseInt(year)} budgets={budgets} currencySymbol={ currencySymbol }/>
</Layout.Grid>

<Layout.Card>
Expand Down
Loading
Loading