fix(insights): show the Rest Mode onset as a date, not a raw timestamp

The health score card passed the episode onset, an ISO instant, straight
into its sentence, so it read "Rest Mode active since
2025-08-04T09:55:00.000Z". It now shows the day that instant falls on in
the profile timezone, in the user's date format. The test that pinned the
raw value now pins the formatted day.
This commit is contained in:
Marc-André Bombeck committed 2026-10-04 15:36:04 +02:00
1 parent be69e409af
commit b25df614f9
2 files changed
+51 -6

No files matched your search

@@ -20,7 +20,11 @@ import {
type Translate,
} from "../health-score-pillar-detail";
let mockAuthUser: { unitPreference: string; glucoseUnit: string } = {
let mockAuthUser: {
unitPreference: string;
glucoseUnit: string;
timezone?: string;
} = {
unitPreference: "metric",
glucoseUnit: "mg/dL",
};
@@ -624,14 +628,21 @@ describe("<HealthScoreCard> composite states", () => {
const html = render(
<HealthScoreCard
report={scoredReport({
restMode: { active: true, since: "2026-07-20", episodeCount: 1 },
restMode: {
active: true,
since: "2026-07-19T23:30:00.000Z",
episodeCount: 1,
},
})}
tension={{ band: "yellow", positive: ["sleep"], negative: ["rhr"] }}
returnToBand={{ metricType: "RESTING_HEART_RATE", daysInside: 6 }}
/>,
);
const rest = atRest(html);
expect(rest).toContain("Rest Mode active since 2026-07-20");
// The onset is an instant; it reads as the day it falls on in the
// profile timezone, in the user's date format, never as raw ISO.
expect(rest).toMatch(/Rest Mode active since \d{2}\/\d{2}\/2026\./);
expect(rest).not.toContain("T23:30:00");
expect(rest).toContain('data-slot="health-score-tension"');
expect(rest).toContain('data-slot="health-score-return-to-band"');
// The contributor key and the metric type are localised, never raw.
@@ -640,6 +651,28 @@ describe("<HealthScoreCard> composite states", () => {
expect(rest).not.toContain(">rhr<");
});
it("reads the Rest Mode onset as the day in the profile timezone", () => {
mockAuthUser = {
unitPreference: "metric",
glucoseUnit: "mg/dL",
timezone: "Europe/Berlin",
};
const html = render(
<HealthScoreCard
report={scoredReport({
restMode: {
active: true,
since: "2026-07-19T23:30:00.000Z",
episodeCount: 1,
},
})}
/>,
);
const rest = atRest(html);
expect(rest).toMatch(/Rest Mode active since (07\/20\/2026|20\/07\/2026)/);
expect(rest).not.toContain("2026-07-19T");
});
it("shows the weekly gain as a chip beside the label", () => {
const html = render(<HealthScoreCard report={scoredReport()} />);
expect(html).toContain('data-slot="health-score-card-label"');
+15 -3
View File
@@ -24,6 +24,8 @@ import {
type PillarDetailContext,
} from "@/components/insights/health-score-pillar-detail";
import { useAuth } from "@/hooks/use-auth";
import { formatDate } from "@/lib/date-format";
import { DEFAULT_TIMEZONE, userDayKey } from "@/lib/tz/format";
import { useUnitDisplay } from "@/hooks/use-unit-display";
import { resolveGlucoseUnit } from "@/lib/glucose";
import type {
@@ -31,7 +33,7 @@ import type {
ScoreBand,
ScorePillarResult,
} from "@/lib/analytics/score/types";
import { useTranslations } from "@/lib/i18n/context";
import { useDateFormatPreference, useTranslations } from "@/lib/i18n/context";
import { SCORE_PILLAR_LABEL_KEYS } from "@/lib/score-config/labels";
import { cn } from "@/lib/utils";
@@ -265,7 +267,8 @@ export function HealthScoreCard({
onRetry,
className,
}: HealthScoreCardProps) {
const { t } = useTranslations();
const { t, locale } = useTranslations();
const dateFormat = useDateFormatPreference();
const { user } = useAuth();
const [open, setOpen] = useState(false);
const regionId = useId();
@@ -528,7 +531,16 @@ export function HealthScoreCard({
className="text-muted-foreground text-xs"
>
{t("insights.healthScore.restMode", {
since: report.restMode.since ?? t("insights.healthScore.none"),
since: report.restMode.since
? formatDate(
userDayKey(
new Date(report.restMode.since),
user?.timezone || DEFAULT_TIMEZONE,
),
dateFormat,
locale,
)
: t("insights.healthScore.none"),
})}
</p>
) : null}