feat: add initial balance support to accounts, enhancing account management and balance calculations across components

This commit is contained in:
Julien Froidefond
2025-11-30 12:13:02 +01:00
parent c26ba9ddc6
commit 184a073bb1
13 changed files with 117 additions and 30 deletions

View File

@@ -13,6 +13,7 @@ import { Card, CardContent } from "@/components/ui/card";
import { Building2, Folder } from "lucide-react";
import type { Account } from "@/lib/types";
import { cn } from "@/lib/utils";
import { getAccountBalance } from "@/lib/account-utils";
export default function AccountsPage() {
const { data, isLoading, refresh } = useBankingData();
@@ -26,6 +27,7 @@ export default function AccountsPage() {
type: "CHECKING" as Account["type"],
folderId: "folder-root",
externalUrl: "",
initialBalance: 0,
});
if (isLoading || !data) {
@@ -46,6 +48,7 @@ export default function AccountsPage() {
type: account.type,
folderId: account.folderId || "folder-root",
externalUrl: account.externalUrl || "",
initialBalance: account.initialBalance || 0,
});
setIsDialogOpen(true);
};
@@ -60,6 +63,7 @@ export default function AccountsPage() {
type: formData.type,
folderId: formData.folderId,
externalUrl: formData.externalUrl || null,
initialBalance: formData.initialBalance,
};
await updateAccount(updatedAccount);
refresh();
@@ -126,7 +130,10 @@ export default function AccountsPage() {
return data.transactions.filter((t) => t.accountId === accountId).length;
};
const totalBalance = data.accounts.reduce((sum, a) => sum + a.balance, 0);
const totalBalance = data.accounts.reduce(
(sum, a) => sum + getAccountBalance(a),
0,
);
// Grouper les comptes par folder
const accountsByFolder = data.accounts.reduce(
@@ -194,6 +201,24 @@ export default function AccountsPage() {
<span className="text-sm text-muted-foreground">
({accountsByFolder["no-folder"].length})
</span>
<span
className={cn(
"text-sm font-semibold tabular-nums ml-auto",
accountsByFolder["no-folder"].reduce(
(sum, a) => sum + getAccountBalance(a),
0,
) >= 0
? "text-emerald-600"
: "text-red-600",
)}
>
{formatCurrency(
accountsByFolder["no-folder"].reduce(
(sum, a) => sum + getAccountBalance(a),
0,
),
)}
</span>
</div>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
{accountsByFolder["no-folder"].map((account) => {
@@ -225,7 +250,7 @@ export default function AccountsPage() {
if (folderAccounts.length === 0) return null;
const folderBalance = folderAccounts.reduce(
(sum, a) => sum + a.balance,
(sum, a) => sum + getAccountBalance(a),
0,
);

View File

@@ -10,6 +10,7 @@ import {
TopExpensesList,
} from "@/components/statistics";
import { useBankingData } from "@/lib/hooks";
import { getAccountBalance } from "@/lib/account-utils";
import {
Select,
SelectContent,
@@ -231,7 +232,19 @@ export default function StatisticsPage() {
(a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
);
// Start with sum of initial balances for filtered accounts
let runningBalance = 0;
if (selectedAccounts.includes("all")) {
runningBalance = data.accounts.reduce(
(sum, acc) => sum + (acc.initialBalance || 0),
0,
);
} else {
runningBalance = data.accounts
.filter((acc) => selectedAccounts.includes(acc.id))
.reduce((sum, acc) => sum + (acc.initialBalance || 0), 0);
}
const aggregatedBalanceByDate = new Map<string, number>();
sortedFilteredTransactions.forEach((t) => {
runningBalance += t.amount;
@@ -254,10 +267,10 @@ export default function StatisticsPage() {
accountBalances.set(account.id, new Map());
});
// Calculate running balance per account
// Calculate running balance per account (start with initialBalance)
const accountRunningBalances = new Map<string, number>();
data.accounts.forEach((account) => {
accountRunningBalances.set(account.id, 0);
accountRunningBalances.set(account.id, account.initialBalance || 0);
});
sortedFilteredTransactions.forEach((t) => {
@@ -280,7 +293,7 @@ export default function StatisticsPage() {
const sortedDates = Array.from(allDates).sort();
const lastBalances = new Map<string, number>();
data.accounts.forEach((account) => {
lastBalances.set(account.id, 0);
lastBalances.set(account.id, account.initialBalance || 0);
});
const perAccountBalanceData = sortedDates.map((date) => {