fix(settings): drop the score pillar group headings for a flat list

The score-composition settings grouped its topics under domain headings
(Heart and metabolism, Activity, Sleep, Body shape, Wellbeing). Remove
them and list the individual topics one under another with hairline
dividers, the way the health profile lists its facts. Each row keeps its
domain data attribute, so the flattening preserves the registry order and
tests still address a pillar by its domain. The now-orphaned domain-label
map and its six-locale strings go with it.
This commit is contained in:
Marc-André Bombeck committed 2026-08-08 20:56:50 +02:00
1 parent 955ef6c6b6
commit e344ebb781
10 files changed
+23 -92

No files matched your search

+5 -6
View File
@@ -130,14 +130,13 @@ test.describe("Settings → Health Score", () => {
1,
);
// The cardiometabolic triple, visibly under one heading.
// The cardiometabolic triple. The list is flat (no group headings) — the
// rows carry their domain, so the three cardiometabolic pillars are found
// on the row itself.
const cardio = page.locator(
'[data-slot="score-config-group"][data-domain="cardiometabolic"]',
);
await expect(cardio).toHaveCount(1);
await expect(cardio.locator('[data-slot="score-pillar-row"]')).toHaveCount(
3,
'[data-slot="score-pillar-row"][data-domain="cardiometabolic"]',
);
await expect(cardio).toHaveCount(3);
// The rows say nothing about recording or showing — the card says it
// once, above them, and the modules screen owns those two questions.
-7
View File
@@ -5207,13 +5207,6 @@
"axis": {
"countsFor": "{pillar} in den Score einrechnen"
},
"domain": {
"cardiometabolic": "Herz und Stoffwechsel",
"activity": "Aktivität",
"sleep": "Schlaf",
"adiposity": "Körperform",
"wellbeing": "Wohlbefinden"
},
"state": {
"counting": "Zählt in deinen Score",
"waiting": "Ausgewählt, wartet auf Daten",
-7
View File
@@ -5207,13 +5207,6 @@
"axis": {
"countsFor": "Count {pillar} toward the score"
},
"domain": {
"cardiometabolic": "Heart and metabolism",
"activity": "Activity",
"sleep": "Sleep",
"adiposity": "Body shape",
"wellbeing": "Wellbeing"
},
"state": {
"counting": "Counting toward your score",
"waiting": "Selected, waiting for data",
-7
View File
@@ -5207,13 +5207,6 @@
"axis": {
"countsFor": "Contar {pillar} para la puntuación"
},
"domain": {
"cardiometabolic": "Corazón y metabolismo",
"activity": "Actividad",
"sleep": "Sueño",
"adiposity": "Forma corporal",
"wellbeing": "Bienestar"
},
"state": {
"counting": "Cuenta para tu puntuación",
"waiting": "Seleccionado, esperando datos",
-7
View File
@@ -5207,13 +5207,6 @@
"axis": {
"countsFor": "Compter {pillar} dans le score"
},
"domain": {
"cardiometabolic": "Cœur et métabolisme",
"activity": "Activité",
"sleep": "Sommeil",
"adiposity": "Silhouette",
"wellbeing": "Bien-être"
},
"state": {
"counting": "Compte dans votre score",
"waiting": "Sélectionné, en attente de données",
-7
View File
@@ -5207,13 +5207,6 @@
"axis": {
"countsFor": "Conta {pillar} nel punteggio"
},
"domain": {
"cardiometabolic": "Cuore e metabolismo",
"activity": "Attività",
"sleep": "Sonno",
"adiposity": "Forma corporea",
"wellbeing": "Benessere"
},
"state": {
"counting": "Conta nel tuo punteggio",
"waiting": "Selezionato, in attesa di dati",
-7
View File
@@ -5207,13 +5207,6 @@
"axis": {
"countsFor": "Licz {pillar} do wyniku"
},
"domain": {
"cardiometabolic": "Serce i metabolizm",
"activity": "Aktywność",
"sleep": "Sen",
"adiposity": "Sylwetka",
"wellbeing": "Samopoczucie"
},
"state": {
"counting": "Liczy się do Twojego wyniku",
"waiting": "Wybrany, czeka na dane",
+1 -1
View File
@@ -60,7 +60,7 @@ export function ScorePillarRow({
data-domain={row.domain}
data-counts={row.counts ? "true" : "false"}
data-eligibility={row.eligibility}
className="flex min-h-11 items-center justify-between gap-4"
className="flex min-h-11 items-center justify-between gap-4 py-3"
>
<div className="min-w-0 space-y-0.5">
<Label htmlFor={inputId} className="text-sm font-medium">
+16 -33
View File
@@ -72,7 +72,6 @@ import {
import { useTranslations } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
import { useAnalyticsQuery } from "@/lib/queries/use-analytics-query";
import { SCORE_DOMAIN_LABEL_KEYS } from "@/lib/score-config/labels";
import {
buildScoreConfigRows,
type ScorePillarVerdict,
@@ -387,38 +386,22 @@ export function ScoreSection() {
<Skeleton className="h-11 w-full" />
</div>
) : (
<div className="space-y-6">
{groups.map((group) => (
<div
key={group.domain}
data-slot="score-config-group"
data-domain={group.domain}
className="space-y-2"
>
{/* Names an area of health, so it sits in the content
tier. The muted section-label treatment it shipped
with read as switched-off beside the rows it
heads. */}
<h3
data-slot="score-config-group-heading"
className="text-foreground text-xs font-medium tracking-wide uppercase"
>
{t(SCORE_DOMAIN_LABEL_KEYS[group.domain])}
</h3>
{/* No rules between the rows: the gap between groups
is the grouping. */}
<div className="space-y-3">
{group.rows.map((row) => (
<ScorePillarRow
key={row.id}
row={row}
pending={busy}
onToggle={(next) => toggle(row.id, next)}
/>
))}
</div>
</div>
))}
// One flat list of topics separated by hairline dividers, the
// way Anamnese lists its facts. The group headings are gone; the
// registry order (domain, then pillar) is preserved by flattening
// the groups in order, and each row keeps its `data-domain` for
// tests and e2e.
<div className="divide-border divide-y">
{groups.flatMap((group) =>
group.rows.map((row) => (
<ScorePillarRow
key={row.id}
row={row}
pending={busy}
onToggle={(next) => toggle(row.id, next)}
/>
)),
)}
</div>
)}
+1 -10
View File
@@ -6,7 +6,7 @@
* surface renames a pillar, and the two surfaces would then be talking
* about different things while showing the same list.
*/
import type { ScoreDomain, ScorePillarId } from "@/lib/analytics/score/types";
import type { ScorePillarId } from "@/lib/analytics/score/types";
export const SCORE_PILLAR_LABEL_KEYS: Record<ScorePillarId, string> = {
BLOOD_PRESSURE: "insights.healthScore.pillar.bloodPressure",
@@ -17,12 +17,3 @@ export const SCORE_PILLAR_LABEL_KEYS: Record<ScorePillarId, string> = {
WELLBEING: "insights.healthScore.pillar.wellbeing",
LIPIDS: "insights.healthScore.pillar.lipids",
};
/** Domain headings, one per distinct area of health. */
export const SCORE_DOMAIN_LABEL_KEYS: Record<ScoreDomain, string> = {
cardiometabolic: "settings.sections.score.domain.cardiometabolic",
activity: "settings.sections.score.domain.activity",
sleep: "settings.sections.score.domain.sleep",
adiposity: "settings.sections.score.domain.adiposity",
wellbeing: "settings.sections.score.domain.wellbeing",
};