mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-07-17 12:08:47 +02:00
Adopt TanStack Query: provider, timeouts, useBudget, Budget page
QueryClientProvider (30s staleTime, 1 retry) + Sonner Toaster at the root. api.ts gains AbortSignal support and a default 30s timeout (FE-24); query cancellation kills the stale-response races (FE-01, FE-03). useBudget is now queries + mutations with targeted ['budget'] invalidation and success/error toasts on every mutation (ARCH-13, UX-01); month navigation keeps the previous month visible while fetching. Budget's transaction list is a cancellable query with placeholder data; deferred-toggle gets feedback (UX-05); both panels render a shared ErrorState with retry instead of failing silently. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,8 +10,13 @@ class ApiError extends Error {
|
||||
|
||||
interface RequestConfig {
|
||||
params?: Record<string, string | number | boolean | undefined>;
|
||||
/** Caller cancellation (TanStack Query passes this); combined with the
|
||||
* default 30s timeout. */
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
|
||||
const REQUEST_TIMEOUT_MS = 30_000;
|
||||
|
||||
async function request<T>(
|
||||
method: string,
|
||||
url: string,
|
||||
@@ -38,11 +43,17 @@ async function request<T>(
|
||||
fetchBody = JSON.stringify(body);
|
||||
}
|
||||
|
||||
const timeout = AbortSignal.timeout(REQUEST_TIMEOUT_MS);
|
||||
const signal = config?.signal
|
||||
? AbortSignal.any([config.signal, timeout])
|
||||
: timeout;
|
||||
|
||||
const res = await fetch(fullUrl, {
|
||||
method,
|
||||
headers,
|
||||
body: fetchBody,
|
||||
credentials: "same-origin",
|
||||
signal,
|
||||
});
|
||||
|
||||
if (res.status === 401) {
|
||||
|
||||
Reference in New Issue
Block a user