feat: enhance transaction management with optimistic updates and error handling for reconciliation and category changes
This commit is contained in:
@@ -157,34 +157,113 @@ export default function TransactionsPage() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleReconciled = (transactionId: string) => {
|
const toggleReconciled = async (transactionId: string) => {
|
||||||
|
const transaction = data.transactions.find((t) => t.id === transactionId);
|
||||||
|
if (!transaction) return;
|
||||||
|
|
||||||
|
const updatedTransaction = { ...transaction, isReconciled: !transaction.isReconciled };
|
||||||
|
|
||||||
|
// Optimistic update
|
||||||
const updatedTransactions = data.transactions.map((t) =>
|
const updatedTransactions = data.transactions.map((t) =>
|
||||||
t.id === transactionId ? { ...t, isReconciled: !t.isReconciled } : t,
|
t.id === transactionId ? updatedTransaction : t,
|
||||||
);
|
);
|
||||||
update({ ...data, transactions: updatedTransactions });
|
update({ ...data, transactions: updatedTransactions });
|
||||||
|
|
||||||
|
// Persist to database
|
||||||
|
try {
|
||||||
|
await fetch("/api/banking/transactions", {
|
||||||
|
method: "PUT",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(updatedTransaction),
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to update transaction:", error);
|
||||||
|
// Revert on error
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const setCategory = (transactionId: string, categoryId: string | null) => {
|
const setCategory = async (transactionId: string, categoryId: string | null) => {
|
||||||
|
const transaction = data.transactions.find((t) => t.id === transactionId);
|
||||||
|
if (!transaction) return;
|
||||||
|
|
||||||
|
const updatedTransaction = { ...transaction, categoryId };
|
||||||
|
|
||||||
|
// Optimistic update
|
||||||
const updatedTransactions = data.transactions.map((t) =>
|
const updatedTransactions = data.transactions.map((t) =>
|
||||||
t.id === transactionId ? { ...t, categoryId } : t,
|
t.id === transactionId ? updatedTransaction : t,
|
||||||
);
|
);
|
||||||
update({ ...data, transactions: updatedTransactions });
|
update({ ...data, transactions: updatedTransactions });
|
||||||
|
|
||||||
|
// Persist to database
|
||||||
|
try {
|
||||||
|
await fetch("/api/banking/transactions", {
|
||||||
|
method: "PUT",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(updatedTransaction),
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to update transaction:", error);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const bulkReconcile = (reconciled: boolean) => {
|
const bulkReconcile = async (reconciled: boolean) => {
|
||||||
|
const transactionsToUpdate = data.transactions.filter((t) =>
|
||||||
|
selectedTransactions.has(t.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Optimistic update
|
||||||
const updatedTransactions = data.transactions.map((t) =>
|
const updatedTransactions = data.transactions.map((t) =>
|
||||||
selectedTransactions.has(t.id) ? { ...t, isReconciled: reconciled } : t,
|
selectedTransactions.has(t.id) ? { ...t, isReconciled: reconciled } : t,
|
||||||
);
|
);
|
||||||
update({ ...data, transactions: updatedTransactions });
|
update({ ...data, transactions: updatedTransactions });
|
||||||
setSelectedTransactions(new Set());
|
setSelectedTransactions(new Set());
|
||||||
|
|
||||||
|
// Persist to database
|
||||||
|
try {
|
||||||
|
await Promise.all(
|
||||||
|
transactionsToUpdate.map((t) =>
|
||||||
|
fetch("/api/banking/transactions", {
|
||||||
|
method: "PUT",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ ...t, isReconciled: reconciled }),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to update transactions:", error);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const bulkSetCategory = (categoryId: string | null) => {
|
const bulkSetCategory = async (categoryId: string | null) => {
|
||||||
|
const transactionsToUpdate = data.transactions.filter((t) =>
|
||||||
|
selectedTransactions.has(t.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Optimistic update
|
||||||
const updatedTransactions = data.transactions.map((t) =>
|
const updatedTransactions = data.transactions.map((t) =>
|
||||||
selectedTransactions.has(t.id) ? { ...t, categoryId } : t,
|
selectedTransactions.has(t.id) ? { ...t, categoryId } : t,
|
||||||
);
|
);
|
||||||
update({ ...data, transactions: updatedTransactions });
|
update({ ...data, transactions: updatedTransactions });
|
||||||
setSelectedTransactions(new Set());
|
setSelectedTransactions(new Set());
|
||||||
|
|
||||||
|
// Persist to database
|
||||||
|
try {
|
||||||
|
await Promise.all(
|
||||||
|
transactionsToUpdate.map((t) =>
|
||||||
|
fetch("/api/banking/transactions", {
|
||||||
|
method: "PUT",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ ...t, categoryId }),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to update transactions:", error);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleSelectAll = () => {
|
const toggleSelectAll = () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user