Resolve plural tiers through the i18n context

Importing the plural helper directly from the dashboard trend tile cost
~78 KB gz across the route chunks: the module is tiny, but a new edge
from a widely-instantiated component gets duplicated into every chunk
that contains it rather than hoisted. The provider is already in every
chunk, so expose a plural-aware tCount() there and let components call
that instead. Total client JS goes back under budget.

Also fix the two tests the honest-loading-state change invalidated: the
mental-wellbeing landing tests seeded a never-resolving read and so now
render skeletons rather than instrument cards, and the achievements page
needs a router in scope for its module-gate redirect.
This commit is contained in:
Marc-André Bombeck committed 2026-07-19 06:39:29 +02:00
1 parent f31a12e174
commit 323b111a24
6 files changed
+119 -16

No files matched your search

+3 -8
View File
@@ -10,7 +10,6 @@ import {
TooltipTrigger,
} from "@/components/ui/tooltip";
import { useTranslations, useFormatters } from "@/lib/i18n/context";
import { pluralKey } from "@/lib/i18n/plural";
import type { ComparisonBaseline } from "@/lib/dashboard-layout";
import {
getTrendSentiment,
@@ -131,7 +130,7 @@ export function TrendCard({
emptyHint = null,
valueAdornment = null,
}: TrendCardProps) {
const { t, locale } = useTranslations();
const { t, tCount } = useTranslations();
const fmt = useFormatters();
// v1.4.33 F5 — pick a single signal to drive both the arrow and the
@@ -371,14 +370,10 @@ export function TrendCard({
}
if (staleDays <= 60) {
const weeks = Math.floor(staleDays / 7);
return t(pluralKey("dashboard.staleHintWeeks", weeks, locale), {
count: weeks,
});
return tCount("dashboard.staleHintWeeks", weeks);
}
const months = Math.floor(staleDays / 30);
return t(pluralKey("dashboard.staleHintMonths", months, locale), {
count: months,
});
return tCount("dashboard.staleHintMonths", months);
})()}
</span>
)}
@@ -3,6 +3,7 @@ import { renderToStaticMarkup } from "react-dom/server";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { I18nProvider } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
import en from "../../../../messages/en.json";
/**
@@ -35,6 +36,15 @@ function withProviders(node: React.ReactNode): string {
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
});
// The landing now distinguishes loading from an empty record: while the
// history read is in flight it paints skeletons rather than the instrument
// cards' "not taken yet" copy, since that copy is a claim about the user's
// record. These tests exercise the LOADED landing, so seed the read as a
// settled empty result. The failed and in-flight states are covered in
// `failed-read-never-empty.test.tsx`.
queryClient.setQueryData(queryKeys.mentalHealthAssessments(), {
assessments: [],
});
return renderToStaticMarkup(
<QueryClientProvider client={queryClient}>
<I18nProvider initialLocale="en">{node}</I18nProvider>