feat: add initial balance support to accounts, enhancing account management and balance calculations across components
This commit is contained in:
@@ -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 (
|
||||
<Card className={cn("relative", isSelected && "ring-2 ring-primary")}>
|
||||
<CardHeader className="pb-1.5">
|
||||
<CardHeader className="pb-0">
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex items-center gap-2 flex-1">
|
||||
{onSelect && (
|
||||
@@ -89,14 +91,14 @@ export function AccountCard({
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-1.5">
|
||||
<CardContent className="pt-1">
|
||||
<div
|
||||
className={cn(
|
||||
"text-xl font-bold mb-1.5",
|
||||
account.balance >= 0 ? "text-emerald-600" : "text-red-600"
|
||||
realBalance >= 0 ? "text-emerald-600" : "text-red-600"
|
||||
)}
|
||||
>
|
||||
{formatCurrency(account.balance)}
|
||||
{formatCurrency(realBalance)}
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-xs text-muted-foreground">
|
||||
<Link
|
||||
|
||||
@@ -24,6 +24,7 @@ interface AccountFormData {
|
||||
type: Account["type"];
|
||||
folderId: string;
|
||||
externalUrl: string;
|
||||
initialBalance: number;
|
||||
}
|
||||
|
||||
interface AccountEditDialogProps {
|
||||
@@ -99,6 +100,24 @@ export function AccountEditDialog({
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>Solde initial</Label>
|
||||
<Input
|
||||
type="number"
|
||||
step="0.01"
|
||||
value={formData.initialBalance}
|
||||
onChange={(e) =>
|
||||
onFormDataChange({
|
||||
...formData,
|
||||
initialBalance: parseFloat(e.target.value) || 0,
|
||||
})
|
||||
}
|
||||
placeholder="0.00"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Solde de départ pour équilibrer le compte
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>Lien externe (portail banque)</Label>
|
||||
<Input
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Progress } from "@/components/ui/progress";
|
||||
import type { BankingData } from "@/lib/types";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Building2 } from "lucide-react";
|
||||
import { getAccountBalance } from "@/lib/account-utils";
|
||||
|
||||
interface AccountsSummaryProps {
|
||||
data: BankingData;
|
||||
@@ -19,8 +20,8 @@ export function AccountsSummary({ data }: AccountsSummaryProps) {
|
||||
};
|
||||
|
||||
const totalPositive = data.accounts
|
||||
.filter((a) => 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) {
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
{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) {
|
||||
<span
|
||||
className={cn(
|
||||
"font-semibold tabular-nums",
|
||||
account.balance >= 0
|
||||
realBalance >= 0
|
||||
? "text-emerald-600"
|
||||
: "text-red-600",
|
||||
)}
|
||||
>
|
||||
{formatCurrency(account.balance)}
|
||||
{formatCurrency(realBalance)}
|
||||
</span>
|
||||
</div>
|
||||
{account.balance > 0 && (
|
||||
{realBalance > 0 && (
|
||||
<Progress value={percentage} className="h-1.5" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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({
|
||||
<span
|
||||
className={cn(
|
||||
"text-sm tabular-nums",
|
||||
account.balance >= 0 ? "text-emerald-600" : "text-red-600"
|
||||
realBalance >= 0 ? "text-emerald-600" : "text-red-600"
|
||||
)}
|
||||
>
|
||||
{formatCurrency(account.balance)}
|
||||
{formatCurrency(realBalance)}
|
||||
</span>
|
||||
<Button
|
||||
variant="ghost"
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useState } from "react";
|
||||
import { DraggableFolderItem } from "./draggable-folder-item";
|
||||
import { DraggableAccountItem } from "./draggable-account-item";
|
||||
import type { Folder as FolderType, Account } from "@/lib/types";
|
||||
import { getAccountBalance } from "@/lib/account-utils";
|
||||
|
||||
interface FolderTreeItemProps {
|
||||
folder: FolderType;
|
||||
@@ -35,7 +36,10 @@ export function FolderTreeItem({
|
||||
(folder.id === "folder-root" && a.folderId === null)
|
||||
);
|
||||
const childFolders = allFolders.filter((f) => f.parentId === folder.id);
|
||||
const folderTotal = folderAccounts.reduce((sum, a) => sum + a.balance, 0);
|
||||
const folderTotal = folderAccounts.reduce(
|
||||
(sum, a) => sum + getAccountBalance(a),
|
||||
0,
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user