mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 06:52:04 +00:00
About forty compact rows and seventy cards still offered a retry on a spent read budget and drew an error card on a refusal, while a third primitive (ReadFailureRow) did the right thing at eight places. QueryErrorRow and QueryErrorCard now take the query's `error` and read it through readFailureKind, which moves to src/lib/api next to ApiError: a refusal (403) draws the surface's refused state or nothing, a spent budget (429) says so without a retry, an ended session (401) says so and offers sign-in instead of going blank, and only a real failure offers the retry. ReadFailureRow is gone and every site passes its error; a guard test fails on a site that does not. The coach read strip keeps its card in the error state and holds one body height across loading, failure and a one-line read.
75 lines
1.9 KiB
TypeScript
75 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
import { useQuery } from "@tanstack/react-query";
|
|
|
|
import { apiGet } from "@/lib/api/api-fetch";
|
|
import { queryKeys } from "@/lib/query-keys";
|
|
|
|
/**
|
|
* Every mood entry a person logged on ONE local day, from
|
|
* `GET /api/mood-entries?from=<day>&to=<day>`.
|
|
*
|
|
* The route filters on the mood `date` column, which already IS the local
|
|
* day key, so no timezone maths happens here. Entries come back newest
|
|
* first (`sortBy=moodLoggedAt`, `sortDir=desc`, the route's defaults).
|
|
*/
|
|
export interface MoodDayEntry {
|
|
id: string;
|
|
date: string;
|
|
/** The mood enum, e.g. `GUT`. Rendered through `MOOD_LABEL_KEYS`. */
|
|
mood: string;
|
|
score: number;
|
|
note: string | null;
|
|
source: string;
|
|
moodLoggedAt: string;
|
|
}
|
|
|
|
interface MoodDayResponse {
|
|
entries: MoodDayEntry[];
|
|
meta: { total: number };
|
|
}
|
|
|
|
export interface UseMoodDayResult {
|
|
/** `undefined` until the route has answered; `[]` means the day really
|
|
* carried no entry. */
|
|
entries: MoodDayEntry[] | undefined;
|
|
isError: boolean;
|
|
/** The failed read's error, for the error row to read. */
|
|
error: unknown;
|
|
refetch: () => void;
|
|
}
|
|
|
|
/**
|
|
* Reads one day's mood entries.
|
|
*
|
|
* `enabled` is the caller's gate — pass `false` when the user is signed
|
|
* out, and nothing is fetched. Mood has no module gate, so there is
|
|
* nothing else to check.
|
|
*/
|
|
export function useMoodDay(
|
|
date: string | undefined,
|
|
enabled: boolean,
|
|
): UseMoodDayResult {
|
|
const { data, isError, error, refetch } = useQuery({
|
|
queryKey: queryKeys.moodEntriesDay(date ?? ""),
|
|
queryFn: () => {
|
|
const params = new URLSearchParams({
|
|
from: date as string,
|
|
to: date as string,
|
|
limit: "50",
|
|
});
|
|
return apiGet<MoodDayResponse>(`/api/mood-entries?${params}`);
|
|
},
|
|
enabled: enabled && Boolean(date),
|
|
staleTime: 5 * 60_000,
|
|
refetchOnWindowFocus: false,
|
|
});
|
|
|
|
return {
|
|
entries: data?.entries,
|
|
isError,
|
|
error,
|
|
refetch: () => void refetch(),
|
|
};
|
|
}
|