169 lines
5.3 KiB
TypeScript
169 lines
5.3 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogDescription,
|
|
} from "@/components/ui/dialog";
|
|
import { Label } from "@/components/ui/label";
|
|
import { Alert, AlertDescription } from "@/components/ui/alert";
|
|
import { AlertTriangle, Info } from "lucide-react";
|
|
import type { Account } from "@/lib/types";
|
|
import { getAccountBalance } from "@/lib/account-utils";
|
|
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
|
|
|
interface AccountMergeSelectDialogProps {
|
|
open: boolean;
|
|
onOpenChange: (open: boolean) => void;
|
|
accounts: Account[];
|
|
selectedAccountIds: string[];
|
|
onMerge: (sourceAccountId: string, targetAccountId: string) => Promise<void>;
|
|
formatCurrency: (amount: number) => string;
|
|
}
|
|
|
|
export function AccountMergeSelectDialog({
|
|
open,
|
|
onOpenChange,
|
|
accounts,
|
|
selectedAccountIds,
|
|
onMerge,
|
|
formatCurrency,
|
|
}: AccountMergeSelectDialogProps) {
|
|
const [targetAccountId, setTargetAccountId] = useState<string>("");
|
|
const [isMerging, setIsMerging] = useState(false);
|
|
|
|
const selectedAccounts = accounts.filter((a) =>
|
|
selectedAccountIds.includes(a.id),
|
|
);
|
|
|
|
const sourceAccountId =
|
|
selectedAccounts.length === 2 && targetAccountId
|
|
? selectedAccounts.find((a) => a.id !== targetAccountId)?.id || ""
|
|
: "";
|
|
|
|
const sourceAccount = accounts.find((a) => a.id === sourceAccountId);
|
|
const targetAccount = accounts.find((a) => a.id === targetAccountId);
|
|
|
|
// Initialiser avec le premier compte si pas encore sélectionné
|
|
if (open && selectedAccounts.length === 2 && !targetAccountId) {
|
|
setTargetAccountId(selectedAccounts[0].id);
|
|
}
|
|
|
|
const handleMerge = async () => {
|
|
if (
|
|
!sourceAccountId ||
|
|
!targetAccountId ||
|
|
sourceAccountId === targetAccountId
|
|
) {
|
|
return;
|
|
}
|
|
|
|
setIsMerging(true);
|
|
try {
|
|
await onMerge(sourceAccountId, targetAccountId);
|
|
setTargetAccountId("");
|
|
onOpenChange(false);
|
|
} catch (error) {
|
|
console.error("Error merging accounts:", error);
|
|
alert("Erreur lors de la fusion des comptes");
|
|
} finally {
|
|
setIsMerging(false);
|
|
}
|
|
};
|
|
|
|
const canMerge =
|
|
selectedAccounts.length === 2 &&
|
|
sourceAccountId &&
|
|
targetAccountId &&
|
|
sourceAccountId !== targetAccountId &&
|
|
sourceAccount &&
|
|
targetAccount;
|
|
|
|
if (selectedAccounts.length !== 2) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent className="sm:max-w-[500px]">
|
|
<DialogHeader>
|
|
<DialogTitle>Fusionner des comptes</DialogTitle>
|
|
<DialogDescription>
|
|
Choisissez quel compte conserver. Toutes les transactions de l'autre
|
|
compte seront déplacées vers celui-ci.
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<div className="space-y-4">
|
|
<Alert>
|
|
<Info className="h-4 w-4" />
|
|
<AlertDescription>
|
|
Le compte sélectionné sera conservé et utilisé pour les prochains
|
|
imports. Choisissez celui qui a le bon bankId.
|
|
</AlertDescription>
|
|
</Alert>
|
|
|
|
<div className="space-y-3">
|
|
<Label>Compte à conserver (destination)</Label>
|
|
<RadioGroup
|
|
value={targetAccountId}
|
|
onValueChange={setTargetAccountId}
|
|
>
|
|
{selectedAccounts.map((account) => (
|
|
<div
|
|
key={account.id}
|
|
className="flex items-start space-x-3 rounded-lg border p-3 hover:bg-accent"
|
|
>
|
|
<RadioGroupItem
|
|
value={account.id}
|
|
id={account.id}
|
|
className="mt-1"
|
|
/>
|
|
<Label
|
|
htmlFor={account.id}
|
|
className="flex-1 cursor-pointer space-y-1"
|
|
>
|
|
<div className="font-medium">{account.name}</div>
|
|
<div className="text-xs text-muted-foreground space-y-0.5">
|
|
<div>Numéro: {account.accountNumber}</div>
|
|
<div>Bank ID: {account.bankId}</div>
|
|
<div>
|
|
Solde: {formatCurrency(getAccountBalance(account))}
|
|
</div>
|
|
</div>
|
|
</Label>
|
|
</div>
|
|
))}
|
|
</RadioGroup>
|
|
</div>
|
|
|
|
{canMerge && (
|
|
<Alert>
|
|
<AlertTriangle className="h-4 w-4" />
|
|
<AlertDescription>
|
|
<strong>Attention :</strong> Toutes les transactions du compte "
|
|
{sourceAccount.name}" seront déplacées vers "
|
|
{targetAccount.name}". Le compte "{sourceAccount.name}" sera
|
|
supprimé après la fusion. Cette action est irréversible.
|
|
</AlertDescription>
|
|
</Alert>
|
|
)}
|
|
|
|
<div className="flex justify-end gap-2 pt-2">
|
|
<Button variant="outline" onClick={() => onOpenChange(false)}>
|
|
Annuler
|
|
</Button>
|
|
<Button onClick={handleMerge} disabled={!canMerge || isMerging}>
|
|
{isMerging ? "Fusion en cours..." : "Fusionner"}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|