diff --git a/app/accounts/page.tsx b/app/accounts/page.tsx index 651058b..b29d6d5 100644 --- a/app/accounts/page.tsx +++ b/app/accounts/page.tsx @@ -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() { ({accountsByFolder["no-folder"].length}) + sum + getAccountBalance(a), + 0, + ) >= 0 + ? "text-emerald-600" + : "text-red-600", + )} + > + {formatCurrency( + accountsByFolder["no-folder"].reduce( + (sum, a) => sum + getAccountBalance(a), + 0, + ), + )} +
{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, ); diff --git a/app/statistics/page.tsx b/app/statistics/page.tsx index 863f355..2c3eca7 100644 --- a/app/statistics/page.tsx +++ b/app/statistics/page.tsx @@ -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(); 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(); 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(); data.accounts.forEach((account) => { - lastBalances.set(account.id, 0); + lastBalances.set(account.id, account.initialBalance || 0); }); const perAccountBalanceData = sortedDates.map((date) => { diff --git a/components/accounts/account-card.tsx b/components/accounts/account-card.tsx index 0c34377..f60018e 100644 --- a/components/accounts/account-card.tsx +++ b/components/accounts/account-card.tsx @@ -14,6 +14,7 @@ import Link from "next/link"; import type { Account, Folder } from "@/lib/types"; import { accountTypeIcons, accountTypeLabels } from "./constants"; import { Checkbox } from "@/components/ui/checkbox"; +import { getAccountBalance } from "@/lib/account-utils"; interface AccountCardProps { account: Account; @@ -37,10 +38,11 @@ export function AccountCard({ onSelect, }: AccountCardProps) { const Icon = accountTypeIcons[account.type]; + const realBalance = getAccountBalance(account); return ( - +
{onSelect && ( @@ -89,14 +91,14 @@ export function AccountCard({
- +
= 0 ? "text-emerald-600" : "text-red-600" + realBalance >= 0 ? "text-emerald-600" : "text-red-600" )} > - {formatCurrency(account.balance)} + {formatCurrency(realBalance)}
+
+ + + onFormDataChange({ + ...formData, + initialBalance: parseFloat(e.target.value) || 0, + }) + } + placeholder="0.00" + /> +

+ Solde de départ pour équilibrer le compte +

+
a.balance > 0) - .reduce((sum, a) => sum + a.balance, 0); + .filter((a) => getAccountBalance(a) > 0) + .reduce((sum, a) => sum + getAccountBalance(a), 0); if (data.accounts.length === 0) { return ( @@ -49,9 +50,10 @@ export function AccountsSummary({ data }: AccountsSummaryProps) {
{data.accounts.map((account) => { + const realBalance = getAccountBalance(account); const percentage = totalPositive > 0 - ? Math.max(0, (account.balance / totalPositive) * 100) + ? Math.max(0, (realBalance / totalPositive) * 100) : 0; return ( @@ -71,15 +73,15 @@ export function AccountsSummary({ data }: AccountsSummaryProps) { = 0 + realBalance >= 0 ? "text-emerald-600" : "text-red-600", )} > - {formatCurrency(account.balance)} + {formatCurrency(realBalance)}
- {account.balance > 0 && ( + {realBalance > 0 && ( )}
diff --git a/components/dashboard/overview-cards.tsx b/components/dashboard/overview-cards.tsx index 42b6360..80e0480 100644 --- a/components/dashboard/overview-cards.tsx +++ b/components/dashboard/overview-cards.tsx @@ -3,13 +3,17 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { TrendingUp, TrendingDown, Wallet, CreditCard } from "lucide-react"; import type { BankingData } from "@/lib/types"; +import { getAccountBalance } from "@/lib/account-utils"; interface OverviewCardsProps { data: BankingData; } export function OverviewCards({ data }: OverviewCardsProps) { - const totalBalance = data.accounts.reduce((sum, acc) => sum + acc.balance, 0); + const totalBalance = data.accounts.reduce( + (sum, acc) => sum + getAccountBalance(acc), + 0, + ); const thisMonth = new Date(); thisMonth.setDate(1); diff --git a/components/folders/draggable-account-item.tsx b/components/folders/draggable-account-item.tsx index 80370d6..1058c41 100644 --- a/components/folders/draggable-account-item.tsx +++ b/components/folders/draggable-account-item.tsx @@ -7,6 +7,7 @@ import { Building2, GripVertical, Pencil } from "lucide-react"; import { cn } from "@/lib/utils"; import Link from "next/link"; import type { Account } from "@/lib/types"; +import { getAccountBalance } from "@/lib/account-utils"; interface DraggableAccountItemProps { account: Account; @@ -19,6 +20,7 @@ export function DraggableAccountItem({ onEditAccount, formatCurrency, }: DraggableAccountItemProps) { + const realBalance = getAccountBalance(account); const { attributes, listeners, @@ -71,10 +73,10 @@ export function DraggableAccountItem({ = 0 ? "text-emerald-600" : "text-red-600" + realBalance >= 0 ? "text-emerald-600" : "text-red-600" )} > - {formatCurrency(account.balance)} + {formatCurrency(realBalance)}