From 43251ba59bb7037d69a46a936ea3800e9c3e54e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sun, 5 Jul 2026 14:49:46 +0200 Subject: [PATCH] feat(mental-health): rebuild the test cards on the shared med-card anatomy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PHQ-9 / GAD-7 cards adopt the medication / Vorsorge card grammar: MedicationCardHeader (bold title + outline category badge), a label/value block carrying "last test" as a relative day and "last result" as score + band word, and a single bottom-pinned Start action. Titles read "PHQ-9 · Stimmung" / "GAD-7 · Sorgen" (middle-dot separator, all six locales) and a new last-result label lands in every locale bundle. The card surface stays neutral regardless of the last band. --- messages/de.json | 5 +- messages/en.json | 5 +- messages/es.json | 5 +- messages/fr.json | 5 +- messages/it.json | 5 +- messages/pl.json | 5 +- .../__tests__/mental-wellbeing.test.tsx | 34 +++++++- .../mental-health/instrument-card.tsx | 77 +++++++++++-------- 8 files changed, 95 insertions(+), 46 deletions(-) diff --git a/messages/de.json b/messages/de.json index e9e1948be..3a5359378 100644 --- a/messages/de.json +++ b/messages/de.json @@ -7636,8 +7636,8 @@ "error": "Etwas ist schiefgelaufen. Bitte versuche es erneut.", "considerProfessional": "Dein Wert liegt in einem Bereich, in dem ein Gespräch mit einer Fachperson helfen kann. Das ist ein behutsamer Hinweis, keine Diagnose.", "instrument": { - "phq9": "PHQ-9 — Stimmung", - "gad7": "GAD-7 — Sorgen" + "phq9": "PHQ-9 · Stimmung", + "gad7": "GAD-7 · Sorgen" }, "instrumentSub": { "phq9": "Depressions-Screening, 9 Fragen", @@ -7745,6 +7745,7 @@ "questionAria": "Frage {current} von {total}", "next": "Weiter", "lastResult": "Letzter Test", + "lastScore": "Letztes Ergebnis", "noResultYet": "Noch kein Check-in", "backToList": "Übersicht", "jumpFirst": "Zur ersten Frage springen", diff --git a/messages/en.json b/messages/en.json index 486122f95..bbbbd05ae 100644 --- a/messages/en.json +++ b/messages/en.json @@ -7636,8 +7636,8 @@ "error": "Something went wrong. Please try again.", "considerProfessional": "Your score is in a range where talking to a health professional may help. This is a gentle suggestion, not a diagnosis.", "instrument": { - "phq9": "PHQ-9 — mood", - "gad7": "GAD-7 — worry" + "phq9": "PHQ-9 · mood", + "gad7": "GAD-7 · worry" }, "instrumentSub": { "phq9": "Depression screen, 9 questions", @@ -7745,6 +7745,7 @@ "questionAria": "Question {current} of {total}", "next": "Next", "lastResult": "Last test", + "lastScore": "Last result", "noResultYet": "No check-in yet", "backToList": "Overview", "jumpFirst": "Jump to first question", diff --git a/messages/es.json b/messages/es.json index cf87c537c..f46501f73 100644 --- a/messages/es.json +++ b/messages/es.json @@ -7636,8 +7636,8 @@ "error": "Algo salió mal. Inténtalo de nuevo.", "considerProfessional": "Tu puntuación está en un rango en el que hablar con un profesional de salud puede ayudar. Es una sugerencia amable, no un diagnóstico.", "instrument": { - "phq9": "PHQ-9 — ánimo", - "gad7": "GAD-7 — preocupación" + "phq9": "PHQ-9 · ánimo", + "gad7": "GAD-7 · preocupación" }, "instrumentSub": { "phq9": "Cribado de depresión, 9 preguntas", @@ -7745,6 +7745,7 @@ "questionAria": "Pregunta {current} de {total}", "next": "Siguiente", "lastResult": "Última prueba", + "lastScore": "Último resultado", "noResultYet": "Aún sin check-in", "backToList": "Vista general", "jumpFirst": "Ir a la primera pregunta", diff --git a/messages/fr.json b/messages/fr.json index 94a427606..f09d5b325 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -7636,8 +7636,8 @@ "error": "Une erreur est survenue. Réessaie.", "considerProfessional": "Ton score se situe dans une plage où parler à un professionnel de santé peut aider. C'est une suggestion bienveillante, pas un diagnostic.", "instrument": { - "phq9": "PHQ-9 — humeur", - "gad7": "GAD-7 — inquiétude" + "phq9": "PHQ-9 · humeur", + "gad7": "GAD-7 · inquiétude" }, "instrumentSub": { "phq9": "Dépistage de la dépression, 9 questions", @@ -7745,6 +7745,7 @@ "questionAria": "Question {current} sur {total}", "next": "Suivant", "lastResult": "Dernier test", + "lastScore": "Dernier résultat", "noResultYet": "Pas encore de check-in", "backToList": "Vue d'ensemble", "jumpFirst": "Aller à la première question", diff --git a/messages/it.json b/messages/it.json index 1575f4e47..9163c8997 100644 --- a/messages/it.json +++ b/messages/it.json @@ -7636,8 +7636,8 @@ "error": "Qualcosa è andato storto. Riprova.", "considerProfessional": "Il tuo punteggio è in un intervallo in cui parlare con un professionista sanitario può aiutare. È un suggerimento gentile, non una diagnosi.", "instrument": { - "phq9": "PHQ-9 — umore", - "gad7": "GAD-7 — preoccupazione" + "phq9": "PHQ-9 · umore", + "gad7": "GAD-7 · preoccupazione" }, "instrumentSub": { "phq9": "Screening della depressione, 9 domande", @@ -7745,6 +7745,7 @@ "questionAria": "Domanda {current} di {total}", "next": "Avanti", "lastResult": "Ultimo test", + "lastScore": "Ultimo risultato", "noResultYet": "Ancora nessun check-in", "backToList": "Panoramica", "jumpFirst": "Vai alla prima domanda", diff --git a/messages/pl.json b/messages/pl.json index d36985dbc..2ac2c9d69 100644 --- a/messages/pl.json +++ b/messages/pl.json @@ -7636,8 +7636,8 @@ "error": "Coś poszło nie tak. Spróbuj ponownie.", "considerProfessional": "Twój wynik mieści się w zakresie, w którym rozmowa ze specjalistą może pomóc. To życzliwa sugestia, a nie diagnoza.", "instrument": { - "phq9": "PHQ-9 — nastrój", - "gad7": "GAD-7 — lęk" + "phq9": "PHQ-9 · nastrój", + "gad7": "GAD-7 · lęk" }, "instrumentSub": { "phq9": "Przesiew depresji, 9 pytań", @@ -7745,6 +7745,7 @@ "questionAria": "Pytanie {current} z {total}", "next": "Dalej", "lastResult": "Ostatni test", + "lastScore": "Ostatni wynik", "noResultYet": "Brak check-inów", "backToList": "Przegląd", "jumpFirst": "Przejdź do pierwszego pytania", diff --git a/src/components/mental-health/__tests__/mental-wellbeing.test.tsx b/src/components/mental-health/__tests__/mental-wellbeing.test.tsx index a20c42337..8ddfcdfa1 100644 --- a/src/components/mental-health/__tests__/mental-wellbeing.test.tsx +++ b/src/components/mental-health/__tests__/mental-wellbeing.test.tsx @@ -200,14 +200,42 @@ describe("history rendering", () => { }); }); -describe("instrument card (v1.27.6 — no trend-detail target)", () => { - it("renders the card body as plain content with Start as the single action", () => { +describe("instrument card (v1.27.6 — med-/Vorsorge card anatomy)", () => { + const lastRow: AssessmentRow = { + id: "l1", + instrument: "PHQ9", + locale: "en", + totalScore: 8, + severityBand: "mild", + item9Flagged: false, + crisisShownAt: null, + takenAt: "2026-06-20T00:00:00.000Z", + }; + + it("renders the shared med-card header (title + category badge), no trend target", () => { const html = withProviders( {}} />, ); + // The med-card header primitive paints the bold name + category badge. + expect(html).toContain(mh.instrument.phq9); + expect(html).toContain(mh.instrumentSub.phq9); // The former trend-detail button is gone… expect(html).not.toContain('data-slot="instrument-card-open"'); - // …and the Start action remains. + // …and the Start action remains the single bottom-pinned action. expect(html).toContain(mh.start); + // No history yet → the calm no-check-in line, no fabricated dashes. + expect(html).toContain(mh.noResultYet); + }); + + it("shows last test (relative) and last result (score + band word)", () => { + const html = withProviders( + {}} />, + ); + expect(html).toContain(mh.lastResult); + expect(html).toContain(mh.lastScore); + // Score + band word ride one value slot ("8 · Mild"). + expect(html).toContain('data-slot="instrument-card-last-score"'); + expect(html).toContain(mh.band.PHQ9.mild); + expect(html).not.toContain(mh.noResultYet); }); }); diff --git a/src/components/mental-health/instrument-card.tsx b/src/components/mental-health/instrument-card.tsx index bb8751403..3f0858500 100644 --- a/src/components/mental-health/instrument-card.tsx +++ b/src/components/mental-health/instrument-card.tsx @@ -3,14 +3,17 @@ /** * v1.25.3 — one neutral card per instrument on the landing. * - * Mirrors the Vorsorge / medication card grammar: a header (title + sub), - * a discreet "last result" line when history exists (band badge + relative - * date), and a single bottom-pinned Start action. The surface stays NEUTRAL + * v1.27.6 — rebuilt onto the shared med-/Vorsorge card anatomy so the two + * test cards read exactly like their peers: `MedicationCardHeader` (bold + * name + outline category badge), a label/value block in the next-last + * grammar ("last test" → relative day, "last result" → score + band word), + * and a single bottom-pinned Start action. The surface stays NEUTRAL * regardless of the last band — no severity tint (house rule: status reads - * through a discreet badge only). + * through discreet text only, never a card wash). */ import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; +import { MedicationCardHeader } from "@/components/medications/medication-card-header"; import { useFormatters, useTranslations } from "@/lib/i18n/context"; import { relativeCalendarDate } from "@/lib/i18n/relative-time"; @@ -36,36 +39,48 @@ export function InstrumentCard({ const title = t(`mentalHealth.instrument.${key}`); return ( - - - {/* v1.27.6 — the card body is no longer a trend-detail target (the - trend chart left this surface); the card informs, the Start button - below is the single action. */} -
-
- {title} - - {t(`mentalHealth.instrumentSub.${key}`)} - + + + + {/* Label/value block in the Vorsorge card's next-last grammar. With + no history yet, one calm line replaces the pair — no dashes + pretending a value exists. */} + {last ? ( +
+
+ + {t("mentalHealth.lastResult")} + + + {relativeCalendarDate(last.takenAt, t, formatDate)} + +
+
+ + {t("mentalHealth.lastScore")} + + + {last.totalScore} + {" · "} + {t(`mentalHealth.band.${last.instrument}.${last.severityBand}`)} + +
- - {/* Last-test line in the medication-card grammar: label left, the - relative day (today / yesterday / date) right-aligned. */} -
- {last ? ( - <> - {t("mentalHealth.lastResult")} - - {relativeCalendarDate(last.takenAt, t, formatDate)} - - - ) : ( - {t("mentalHealth.noResultYet")} - )} + ) : ( +
+ {t("mentalHealth.noResultYet")}
-
+ )} -
+ {/* Bottom-pinned single primary action — the med-/Vorsorge card slot. */} +