mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
fix(dashboard): paint the dose ring in the medication hue, not green
The 'Doses today' ring pinned the ring system's green arc — a colour that vocabulary reserves for band semantics. Every medication surface in Insights paints --primary (the compliance progress bars, the compliance trend line, the drug-level and dose-strength curves), so the ring now rides a new constant 'meds' hue on that token: flat by design (both gradient stops on --primary), never a band gradient over pending morning doses. Contrast, computed: dark #bd93f9 — 6.78:1 card / 5.90:1 bg; light #644ac9 — 6.00:1 card / 5.60:1 bg; both clear the 3:1 graphics floor with room. The guard now windows the assertion to the dose ring's own SVG and pins primary present, ring-green absent.
This commit is contained in:
1 parent
72ad228f3e
commit
ec586ba75c
3 files changed
+44
-13
No files matched your search
@@ -395,12 +395,20 @@ describe("<DashboardHero> — ring row (v1.27.7)", () => {
|
||||
expect(rings).toHaveLength(3);
|
||||
// Labels (de locale): the derived ring reuses its wellness-strip
|
||||
// title; the dose ring names today's tally and shows it as
|
||||
// taken/scheduled over the constant green arc — never the band
|
||||
// gradient (a pending morning dose is not an alert state).
|
||||
// taken/scheduled over the constant med-family arc (`--primary`,
|
||||
// the hue the medication surfaces in Insights paint) — never the
|
||||
// band gradient (a pending morning dose is not an alert state) and
|
||||
// never the ring system's green (reserved for band semantics).
|
||||
expect(html).toContain("Bereitschaft");
|
||||
expect(html).toContain("Dosen heute");
|
||||
expect(html).toContain(">1/3<");
|
||||
expect(html).toContain("var(--ring-green-from)");
|
||||
// Window the assertion to the dose ring's own SVG (its gradient defs
|
||||
// close with the svg) so the trailing health-score ring's band-green
|
||||
// gradient can't mask a regression.
|
||||
const medIdx = html.indexOf('data-ring="MED_COMPLIANCE"');
|
||||
const doseRing = html.slice(medIdx, html.indexOf("</svg>", medIdx));
|
||||
expect(doseRing).toContain("var(--primary)");
|
||||
expect(doseRing).not.toContain("var(--ring-green-from)");
|
||||
expect(html).not.toContain("var(--ring-yellow-from)");
|
||||
});
|
||||
|
||||
|
||||
@@ -101,16 +101,18 @@ const CTA_LABEL_KEY: Partial<Record<DashboardVerdictVariant, string>> = {
|
||||
/**
|
||||
* Per-ring hue for the selected score rings — the wellness-strip
|
||||
* vocabulary, so every hero ring paints EXACTLY the hue its insights
|
||||
* sibling paints. MED_COMPLIANCE carries no per-metric hue entry: the
|
||||
* dose ring pins the ring system's green arc (`band="green"`, constant)
|
||||
* — the same green family the medication compliance surfaces in
|
||||
* Insights paint for a taken dose — instead of a band gradient that
|
||||
* would flash yellow/red over pending morning doses.
|
||||
* sibling paints. MED_COMPLIANCE rides the `meds` hue: the medication
|
||||
* family in Insights paints `--primary` on every surface (compliance
|
||||
* bars, compliance trend line, drug-level / dose-strength curves), so
|
||||
* the dose ring holds that one constant tone — never a band gradient
|
||||
* that would flash yellow/red over pending morning doses, and not the
|
||||
* green arc the ring system reserves for band semantics.
|
||||
*/
|
||||
const RING_HUE_BY_ID: Partial<Record<ScoreRingId, RingHue>> = {
|
||||
READINESS: "readiness",
|
||||
RECOVERY_SCORE: "recovery",
|
||||
SLEEP_SCORE: "sleep",
|
||||
MED_COMPLIANCE: "meds",
|
||||
};
|
||||
|
||||
/** Per-ring label key — reuses the existing score labels; the dose ring
|
||||
@@ -328,13 +330,19 @@ export function DashboardHero({
|
||||
className="flex shrink-0 items-center"
|
||||
>
|
||||
{/* Dose ring — today's tally ("1/3") over the constant
|
||||
green arc; the arc still sweeps on the 0..100
|
||||
progress `score`. Falls through to the score render
|
||||
when a cached pre-doses snapshot carries no tally. */}
|
||||
med-family arc (`hue="meds"` = --primary, the tone
|
||||
every medication surface in Insights paints); the arc
|
||||
still sweeps on the 0..100 progress `score`.
|
||||
`band="green"` stays as the stable data-band anchor —
|
||||
a pending morning dose is not an alert state — while
|
||||
the hue owns the paint. Falls through to the score
|
||||
render when a cached pre-doses snapshot carries no
|
||||
tally. */}
|
||||
{ring.id === "MED_COMPLIANCE" && ring.doses ? (
|
||||
<ScoreRing
|
||||
score={ring.score}
|
||||
band="green"
|
||||
hue="meds"
|
||||
valueText={`${ring.doses.taken}/${ring.doses.scheduled}`}
|
||||
ariaLabel={t("dashboard.hero.ringDosesAria", {
|
||||
taken: ring.doses.taken,
|
||||
|
||||
@@ -22,8 +22,17 @@
|
||||
|
||||
import type { ScoreBand } from "./band-tokens";
|
||||
|
||||
/** The per-metric hue keys the wellness strip passes to `<ScoreRing>`. */
|
||||
export type RingHue = "readiness" | "sleep" | "recovery" | "stress" | "strain";
|
||||
/** The per-metric hue keys the wellness strip passes to `<ScoreRing>`.
|
||||
* `meds` is the dashboard dose ring: the medication family in Insights
|
||||
* paints `--primary` everywhere (the compliance Progress bars, the
|
||||
* compliance trend line, the drug-level and dose-strength curves), so
|
||||
* the ring rides the same token — constant, never a band gradient.
|
||||
* Contrast (computed): dark #bd93f9 — 6.78:1 card / 5.90:1 bg; light
|
||||
* #644ac9 — 6.00:1 card / 5.60:1 bg — far above the 3:1 graphics
|
||||
* floor in both themes, and a future `--primary` retune carries the
|
||||
* ring along. */
|
||||
export type RingHue =
|
||||
"readiness" | "sleep" | "recovery" | "stress" | "strain" | "meds";
|
||||
|
||||
/**
|
||||
* Near-flat single-hue arc `[from, to]` per metric, plus a band fallback for
|
||||
@@ -38,6 +47,9 @@ export const RING_GRADIENT: Record<RingHue | ScoreBand, [string, string]> = {
|
||||
sleep: ["var(--ring-sleep-from)", "var(--ring-sleep-to)"],
|
||||
stress: ["var(--ring-stress-from)", "var(--ring-stress-to)"],
|
||||
strain: ["var(--ring-strain-from)", "var(--ring-strain-to)"],
|
||||
// Perfectly flat by design (both stops on the one token) — the med
|
||||
// family's `--primary`, not a hand-tuned from/to pair.
|
||||
meds: ["var(--primary)", "var(--primary)"],
|
||||
// Band fallback for the anatomy detail view (no per-metric hue passed):
|
||||
green: ["var(--ring-green-from)", "var(--ring-green-to)"],
|
||||
yellow: ["var(--ring-yellow-from)", "var(--ring-yellow-to)"],
|
||||
@@ -54,4 +66,7 @@ export const TILE_HUE: Record<RingHue, string> = {
|
||||
recovery: "var(--tile-recovery)",
|
||||
stress: "var(--tile-stress)",
|
||||
strain: "var(--tile-strain)",
|
||||
// No wellness tile carries the meds hue; the dose ring lives on the
|
||||
// dashboard hero only. Primary keeps the record total.
|
||||
meds: "var(--primary)",
|
||||
};
|
||||
Reference in new issue
Block a user