feat: implement transaction updating state management and loading indicators in transaction table for improved user feedback during updates

This commit is contained in:
Julien Froidefond
2025-12-08 08:29:58 +01:00
parent 5014051e10
commit 4224c8aa83
4 changed files with 150 additions and 90 deletions

View File

@@ -1,6 +1,6 @@
"use client";
import { useState, useEffect, useCallback } from "react";
import { useState, useEffect, useCallback, useMemo } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import type { BankingData, Account } from "./types";
import { loadData } from "./store-db";
@@ -81,14 +81,40 @@ export function useLocalStorage<T>(key: string, initialValue: T) {
return [storedValue, setValue] as const;
}
// Helper function to serialize transaction params into a query key
export function getTransactionsQueryKey(
params: TransactionsPaginatedParams = {}
): (string | number)[] {
const key: (string | number)[] = ["transactions"];
if (params.limit) key.push(`limit:${params.limit}`);
if (params.offset !== undefined) key.push(`offset:${params.offset}`);
if (params.startDate) key.push(`startDate:${params.startDate}`);
if (params.endDate) key.push(`endDate:${params.endDate}`);
if (params.accountIds?.length)
key.push(`accountIds:${params.accountIds.sort().join(",")}`);
if (params.categoryIds?.length)
key.push(`categoryIds:${params.categoryIds.sort().join(",")}`);
if (params.includeUncategorized) key.push("includeUncategorized:true");
if (params.search) key.push(`search:${params.search}`);
if (params.isReconciled !== undefined && params.isReconciled !== "all") {
key.push(`isReconciled:${params.isReconciled}`);
}
if (params.sortField) key.push(`sortField:${params.sortField}`);
if (params.sortOrder) key.push(`sortOrder:${params.sortOrder}`);
return key;
}
export function useTransactions(
params: TransactionsPaginatedParams = {},
enabled = true,
enabled = true
) {
const queryClient = useQueryClient();
// Create a stable query key by serializing the params
const queryKey = useMemo(() => getTransactionsQueryKey(params), [params]);
const query = useQuery({
queryKey: ["transactions", params],
queryKey,
queryFn: async (): Promise<TransactionsPaginatedResult> => {
const searchParams = new URLSearchParams();
if (params.limit) searchParams.set("limit", params.limit.toString());
@@ -108,7 +134,7 @@ export function useTransactions(
if (params.isReconciled !== undefined && params.isReconciled !== "all") {
searchParams.set(
"isReconciled",
params.isReconciled === true ? "true" : "false",
params.isReconciled === true ? "true" : "false"
);
}
if (params.sortField) searchParams.set("sortField", params.sortField);