feat: enhance transaction deletion process with optimistic updates, improved error handling, and restore previous data on failure
This commit is contained in:
@@ -123,8 +123,10 @@ export async function DELETE(request: Request) {
|
|||||||
return NextResponse.json({ success: true });
|
return NextResponse.json({ success: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error deleting transaction:", error);
|
console.error("Error deleting transaction:", error);
|
||||||
|
const errorMessage =
|
||||||
|
error instanceof Error ? error.message : "Failed to delete transaction";
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: "Failed to delete transaction" },
|
{ error: errorMessage },
|
||||||
{ status: 500 },
|
{ status: 500 },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
@import "tw-animate-css";
|
@import "tw-animate-css";
|
||||||
|
@import "react-day-picker/style.css";
|
||||||
|
|
||||||
@custom-variant dark (&:is(.dark *));
|
@custom-variant dark (&:is(.dark *));
|
||||||
|
|
||||||
|
|||||||
@@ -480,6 +480,23 @@ export default function TransactionsPage() {
|
|||||||
newSelected.delete(transactionId);
|
newSelected.delete(transactionId);
|
||||||
setSelectedTransactions(newSelected);
|
setSelectedTransactions(newSelected);
|
||||||
|
|
||||||
|
// Sauvegarder les données actuelles pour pouvoir les restaurer en cas d'erreur
|
||||||
|
const queryKey = getTransactionsQueryKey(transactionParams);
|
||||||
|
const previousData =
|
||||||
|
queryClient.getQueryData<typeof transactionsData>(queryKey);
|
||||||
|
|
||||||
|
// Mise à jour optimiste du cache
|
||||||
|
queryClient.setQueryData<typeof transactionsData>(queryKey, (oldData) => {
|
||||||
|
if (!oldData) return oldData;
|
||||||
|
return {
|
||||||
|
...oldData,
|
||||||
|
transactions: oldData.transactions.filter(
|
||||||
|
(t) => t.id !== transactionId
|
||||||
|
),
|
||||||
|
total: oldData.total - 1,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`/api/banking/transactions?id=${transactionId}`,
|
`/api/banking/transactions?id=${transactionId}`,
|
||||||
@@ -487,10 +504,25 @@ export default function TransactionsPage() {
|
|||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if (!response.ok) throw new Error("Failed to delete transaction");
|
|
||||||
invalidateTransactions();
|
if (!response.ok) {
|
||||||
|
const errorData = await response.json().catch(() => ({}));
|
||||||
|
throw new Error(
|
||||||
|
errorData.error || `Failed to delete transaction: ${response.status}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ne pas invalider immédiatement - la mise à jour optimiste est déjà correcte
|
||||||
|
// On invalide seulement les autres queries qui pourraient être affectées (métadonnées, stats)
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["banking-metadata"] });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to delete transaction:", error);
|
console.error("Failed to delete transaction:", error);
|
||||||
|
// Restaurer les données précédentes en cas d'erreur
|
||||||
|
if (previousData) {
|
||||||
|
queryClient.setQueryData(queryKey, previousData);
|
||||||
|
}
|
||||||
|
// Invalider pour récupérer les données correctes du serveur
|
||||||
|
invalidateTransactions();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -119,9 +119,16 @@ export const transactionService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async delete(id: string): Promise<void> {
|
async delete(id: string): Promise<void> {
|
||||||
await prisma.transaction.delete({
|
try {
|
||||||
where: { id },
|
await prisma.transaction.delete({
|
||||||
});
|
where: { id },
|
||||||
|
});
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.code === "P2025") {
|
||||||
|
throw new Error(`Transaction with id ${id} not found`);
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async deduplicate(): Promise<{
|
async deduplicate(): Promise<{
|
||||||
|
|||||||
Reference in New Issue
Block a user