mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 22:26:13 +00:00
fix(checkups): show the Coach and switched-off badges in the list view
The card view marks a checkup the Coach created and one that is switched off; the list view drew neither, so a disabled checkup looked active there. Both views now take the badges from one helper, and the list row shows them beside the title.
This commit is contained in:
1 parent
d77fe9aa7d
commit
71d4516808
2 files changed
+104
-15
No files matched your search
@@ -0,0 +1,74 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
|
||||
import { I18nProvider } from "@/lib/i18n/context";
|
||||
import type { MeasurementReminder } from "@/hooks/use-measurement-reminders";
|
||||
|
||||
/**
|
||||
* A checkup that is switched off, or that the Coach created, says so in the
|
||||
* card view. The list view used to drop both badges, so a disabled checkup
|
||||
* looked active there; which view a person sees is a remembered preference,
|
||||
* so the same checkup read differently depending on a toggle.
|
||||
*/
|
||||
|
||||
vi.mock("next/navigation", () => ({
|
||||
useRouter: () => ({ replace: vi.fn(), push: vi.fn() }),
|
||||
}));
|
||||
|
||||
import { VorsorgeCard } from "../checkups/checkup-card";
|
||||
|
||||
const reminder = {
|
||||
id: "coach-off",
|
||||
label: "Check blood pressure",
|
||||
measurementType: null,
|
||||
intervalDays: 30,
|
||||
rrule: null,
|
||||
anchorDate: null,
|
||||
endsOn: null,
|
||||
origin: "COACH",
|
||||
nextDueAt: null,
|
||||
notifyHour: 9,
|
||||
location: null,
|
||||
lastSatisfiedAt: null,
|
||||
enabled: false,
|
||||
createdAt: "2030-01-01T00:00:00.000Z",
|
||||
updatedAt: "2030-01-01T00:00:00.000Z",
|
||||
} as MeasurementReminder;
|
||||
|
||||
function render(view: "cards" | "list"): string {
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: { queries: { retry: false } },
|
||||
});
|
||||
const noop = () => {};
|
||||
return renderToStaticMarkup(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<I18nProvider initialLocale="en">
|
||||
<VorsorgeCard
|
||||
reminder={reminder}
|
||||
now={Date.parse("2030-02-01T12:00:00.000Z")}
|
||||
view={view}
|
||||
onPrimaryAction={noop}
|
||||
onFileVisit={noop}
|
||||
onRemove={noop}
|
||||
onEdit={noop}
|
||||
onSkip={noop}
|
||||
onSnooze={noop}
|
||||
busy={false}
|
||||
/>
|
||||
</I18nProvider>
|
||||
</QueryClientProvider>,
|
||||
);
|
||||
}
|
||||
|
||||
describe("checkup state badges", () => {
|
||||
it.each(["cards", "list"] as const)(
|
||||
"show the Coach and switched-off badges in the %s view",
|
||||
(view) => {
|
||||
const html = render(view);
|
||||
expect(html).toContain("Check blood pressure");
|
||||
expect(html).toContain(">Coach<");
|
||||
expect(html).toContain(">Off<");
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -244,6 +244,30 @@ function NextLastSlot({
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The Coach-origin and switched-off badges, shared by the card and the list
|
||||
* view; `undefined` when neither applies, so no empty row is drawn.
|
||||
*/
|
||||
function checkupStateBadges(
|
||||
reminder: MeasurementReminder,
|
||||
t: (key: string) => string,
|
||||
): React.ReactNode {
|
||||
const isCoach = reminder.origin === "COACH";
|
||||
if (!isCoach && reminder.enabled) return undefined;
|
||||
return (
|
||||
<>
|
||||
{isCoach && (
|
||||
<Badge variant="outline">{t("measurementReminders.originCoach")}</Badge>
|
||||
)}
|
||||
{!reminder.enabled && (
|
||||
<Badge variant="outline">
|
||||
{t("measurementReminders.disabledBadge")}
|
||||
</Badge>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
/** The dense list variant of a checkup. */
|
||||
function CheckupListRow({
|
||||
reminder,
|
||||
@@ -251,6 +275,7 @@ function CheckupListRow({
|
||||
categoryLabel,
|
||||
cadenceText,
|
||||
meta,
|
||||
stateBadges,
|
||||
isLinked,
|
||||
isScreening,
|
||||
canManageMeasurements,
|
||||
@@ -265,6 +290,8 @@ function CheckupListRow({
|
||||
categoryLabel: string;
|
||||
cadenceText: string | null;
|
||||
meta: React.ReactNode;
|
||||
/** The same Coach and disabled badges the card view shows. */
|
||||
stateBadges: React.ReactNode;
|
||||
isLinked: boolean;
|
||||
isScreening: boolean;
|
||||
canManageMeasurements: boolean;
|
||||
@@ -283,6 +310,7 @@ function CheckupListRow({
|
||||
<span className="truncate font-medium">
|
||||
{resolveReminderLabel(reminder, t)}
|
||||
</span>
|
||||
{stateBadges}
|
||||
</div>
|
||||
{/* Cadence rides on the metric line, styled like the
|
||||
metric text (no shaded pill). */}
|
||||
@@ -537,7 +565,6 @@ export function VorsorgeCard({
|
||||
: reminder.rrule
|
||||
? t("measurementReminders.cadence.custom")
|
||||
: "";
|
||||
const isCoach = reminder.origin === "COACH";
|
||||
const isLinked = reminder.measurementType != null;
|
||||
// A screening reminder's action starts the check-in, never numeric entry.
|
||||
const isScreening = isScreeningReminderType(reminder.measurementType);
|
||||
@@ -558,20 +585,7 @@ export function VorsorgeCard({
|
||||
? `/measurements?type=${encodeURIComponent(reminder.measurementType as string)}`
|
||||
: undefined;
|
||||
|
||||
// Provenance and disabled badges get a row only when one applies.
|
||||
const hasStateBadges = isCoach || !reminder.enabled;
|
||||
const stateBadges = hasStateBadges ? (
|
||||
<>
|
||||
{isCoach && (
|
||||
<Badge variant="outline">{t("measurementReminders.originCoach")}</Badge>
|
||||
)}
|
||||
{!reminder.enabled && (
|
||||
<Badge variant="outline">
|
||||
{t("measurementReminders.disabledBadge")}
|
||||
</Badge>
|
||||
)}
|
||||
</>
|
||||
) : undefined;
|
||||
const stateBadges = checkupStateBadges(reminder, t);
|
||||
|
||||
const headerActions = canManageMeasurements ? (
|
||||
<CheckupMenu
|
||||
@@ -643,6 +657,7 @@ export function VorsorgeCard({
|
||||
categoryLabel={categoryLabel}
|
||||
cadenceText={cadenceText}
|
||||
meta={skipSnoozeMeta}
|
||||
stateBadges={stateBadges}
|
||||
isLinked={isLinked}
|
||||
isScreening={isScreening}
|
||||
canManageMeasurements={canManageMeasurements}
|
||||
|
||||
Reference in new issue
Block a user