mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 04:50:59 +00:00
Merge v1.25.3: v1253-insights-ui
This commit is contained in:
commit
0e21210263
4 files changed
+60
-55
No files matched your search
@@ -120,7 +120,7 @@ function CoachConversationsBody() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx-auto flex h-full min-h-0 w-full max-w-2xl flex-col gap-4 px-4 pt-6 pb-4 md:px-6">
|
||||
<div className="mx-auto flex h-full min-h-0 w-full max-w-screen-xl flex-col gap-4 px-4 pt-6 pb-4 md:px-6">
|
||||
<header className="flex flex-col gap-3">
|
||||
<h1
|
||||
data-slot="coach-conversations-heading"
|
||||
|
||||
@@ -56,9 +56,15 @@ describe("<ScoreAnatomyView>", () => {
|
||||
expect(html).toContain('data-contributor="respiratory"');
|
||||
expect(html).toContain('data-present="false"');
|
||||
expect(html).toContain('data-slot="provenance-explainer-method"');
|
||||
expect(html).toContain("A blend of deviation components.");
|
||||
// v1.15.12 F4 — the "keine klinische Bewertung" footer line is removed;
|
||||
// the non-clinical framing now lives in the inline provenance method.
|
||||
expect(html).not.toContain('data-slot="score-anatomy-disclaimer"');
|
||||
// Regression guard: `ProvenanceExplainer` renders its full method body
|
||||
// inline (the v1.22 refactor dropped the ⓘ glyph), so it must sit in
|
||||
// normal flow — never pulled out via `absolute top-3 right-3`, which
|
||||
// painted the whole paragraph over the title, ring and contributor rows.
|
||||
expect(html).not.toContain("absolute top-3 right-3");
|
||||
});
|
||||
|
||||
it("tints the card + leans the ring hue when a hue is passed (F1)", () => {
|
||||
|
||||
@@ -126,24 +126,12 @@ export function ScoreAnatomyView({
|
||||
: undefined
|
||||
}
|
||||
className={cn(
|
||||
"relative flex flex-col gap-5 rounded-xl border p-5",
|
||||
"flex flex-col gap-5 rounded-xl border p-5",
|
||||
hue ? "wellness-detail-card" : "border-border bg-card",
|
||||
className,
|
||||
)}
|
||||
aria-label={typeof title === "string" ? title : undefined}
|
||||
>
|
||||
{/* v1.15.12 F5 — the ⓘ explainer is pinned TOP-right at heading height
|
||||
(it used to trail the card at bottom-right). Absolute so it never
|
||||
shifts the centred hero title; the trigger keeps its 44px touch
|
||||
target + popover/sheet behaviour. */}
|
||||
<div className="absolute top-3 right-3 z-10">
|
||||
<ProvenanceExplainer
|
||||
provenance={provenance}
|
||||
method={method}
|
||||
standard={standard}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Hero: title + ring + caption */}
|
||||
<div className="flex flex-col items-center gap-3 text-center">
|
||||
<h2
|
||||
@@ -199,10 +187,18 @@ export function ScoreAnatomyView({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* v1.15.12 F4 — the "Richtwert — keine klinische Bewertung" footer line
|
||||
is gone; the method + cited standard live behind the provenance
|
||||
explainer (now top-right, F5), which carries the non-clinical framing
|
||||
where it belongs. The composition (contributor rows above) stays. */}
|
||||
{/* The plain-language method caption closes the card, in normal flow.
|
||||
`ProvenanceExplainer` (v1.22) is no longer a top-right ⓘ glyph — it
|
||||
renders its full method body inline as a muted caption, so it must
|
||||
sit in the document flow at the foot of the surface. The earlier
|
||||
`absolute top-right` wrapper yanked the whole paragraph out of flow
|
||||
and painted it over the centred title, ring and contributor rows on
|
||||
every breakpoint; rendering it here keeps the spine readable. */}
|
||||
<ProvenanceExplainer
|
||||
provenance={provenance}
|
||||
method={method}
|
||||
standard={standard}
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { useAuth } from "@/hooks/use-auth";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { SectionHeading } from "@/components/insights/section-heading";
|
||||
import { AskCoachAction } from "@/components/insights/ask-coach-action";
|
||||
import { AskCoachIconButton } from "@/components/insights/ask-coach-action";
|
||||
import { ProseBlocks } from "@/components/insights/prose-blocks";
|
||||
import { apiGet } from "@/lib/api/api-fetch";
|
||||
|
||||
@@ -142,29 +142,45 @@ export function PeriodNarrativeCard({
|
||||
data-period={period}
|
||||
className={SHELL}
|
||||
>
|
||||
{/* Week / month toggle. Calm segmented control, no chart. */}
|
||||
<div className="flex gap-1 self-start">
|
||||
{(["week", "month"] as const).map((p) => {
|
||||
const active = period === p;
|
||||
return (
|
||||
<button
|
||||
key={p}
|
||||
type="button"
|
||||
aria-pressed={active}
|
||||
onClick={() => setPeriod(p)}
|
||||
className={cn(
|
||||
"focus-visible:ring-ring inline-flex min-h-11 items-center rounded-md px-2.5 py-1 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none",
|
||||
active
|
||||
? "bg-muted text-foreground"
|
||||
: "text-muted-foreground hover:text-foreground",
|
||||
)}
|
||||
>
|
||||
{p === "week"
|
||||
? t("insights.narrativeWeek")
|
||||
: t("insights.narrativeMonth")}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
{/* Header row: week / month toggle on the left, the icon-only Coach
|
||||
hand-off pinned top-right. Matches the assessment cards, which carry
|
||||
the same single `<AskCoachIconButton>` in their header's right slot
|
||||
(no text label, tooltip + accessible name). The summary spans the
|
||||
whole picture for the window, so no scope: the default snapshot
|
||||
reads best. */}
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
{/* Calm segmented control, no chart. */}
|
||||
<div className="flex gap-1">
|
||||
{(["week", "month"] as const).map((p) => {
|
||||
const active = period === p;
|
||||
return (
|
||||
<button
|
||||
key={p}
|
||||
type="button"
|
||||
aria-pressed={active}
|
||||
onClick={() => setPeriod(p)}
|
||||
className={cn(
|
||||
"focus-visible:ring-ring inline-flex min-h-11 items-center rounded-md px-2.5 py-1 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none",
|
||||
active
|
||||
? "bg-muted text-foreground"
|
||||
: "text-muted-foreground hover:text-foreground",
|
||||
)}
|
||||
>
|
||||
{p === "week"
|
||||
? t("insights.narrativeWeek")
|
||||
: t("insights.narrativeMonth")}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<AskCoachIconButton
|
||||
question={t(
|
||||
period === "week"
|
||||
? "insights.coach.seed.periodWeek"
|
||||
: "insights.coach.seed.periodMonth",
|
||||
)}
|
||||
className="shrink-0"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* v1.22 (W6) — real paragraphs via the shared ProseBlocks helper
|
||||
@@ -184,19 +200,6 @@ export function PeriodNarrativeCard({
|
||||
user?.timezone,
|
||||
)}
|
||||
</p>
|
||||
|
||||
{/* v1.21.0 (C4 H2) — hand the period summary to the Coach. It spans
|
||||
the whole picture for the window, so no scope: the default
|
||||
snapshot reads best. */}
|
||||
<div className="flex justify-end">
|
||||
<AskCoachAction
|
||||
question={t(
|
||||
period === "week"
|
||||
? "insights.coach.seed.periodWeek"
|
||||
: "insights.coach.seed.periodMonth",
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user