mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
fix(vorsorge): match the medication-card grammar on the reminder card
Mirror the medication card's name + cadence + status layout:
- the cadence ("alle 7 Tage") renders as a chip directly to the right of the
metric name via a new MedicationCardHeader nameChip slot, instead of on the
state-badge row below the category;
- the due / overdue status renders as plain text, not a chip;
- the "zuletzt erledigt" line always renders, falling back to an em dash when
there is no last-done value, instead of being hidden.
The green action button is unchanged. Also drop the per-module tour trigger
from this surface (the tour is first-time-only now).
This commit is contained in:
1 parent
3ba542f797
commit
8234427a94
2 files changed
+44
-29
No files matched your search
@@ -41,7 +41,6 @@ import {
|
||||
import { useFormatters, useTranslations } from "@/lib/i18n/context";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { applyOrder, useModuleListPrefs } from "@/lib/module-list-prefs";
|
||||
import { ModuleTourTrigger } from "@/components/onboarding/module-tour-trigger";
|
||||
import { SettingsCardHeader } from "@/components/settings/_card-header";
|
||||
import {
|
||||
AlertDialog,
|
||||
@@ -387,7 +386,6 @@ export function VorsorgeSection({
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex shrink-0 items-center gap-2">
|
||||
<ModuleTourTrigger stopId="vorsorge" />
|
||||
{wrenchButton}
|
||||
{addButton}
|
||||
</div>
|
||||
@@ -766,12 +764,17 @@ function VorsorgeCard({
|
||||
? t(`measurementReminders.types.${reminder.measurementType}`)
|
||||
: t("measurementReminders.selfPlanned");
|
||||
|
||||
// v1.18.6 (MOD-06) — the cadence renders as a chip beside the item name
|
||||
// (the med-card cadence-chip convention), alongside the provenance /
|
||||
// disabled state badges.
|
||||
const stateBadges = (
|
||||
// v1.18.6.1 — the cadence renders as a chip DIRECTLY to the right of the
|
||||
// metric name (the med-card convention: cadence sits next to the name).
|
||||
const cadenceChip = cadence ? (
|
||||
<Badge variant="secondary">{cadence}</Badge>
|
||||
) : null;
|
||||
|
||||
// Provenance / disabled state badges keep their own row below the category.
|
||||
// Omit the row entirely when neither applies (don't render an empty band).
|
||||
const hasStateBadges = isCoach || !reminder.enabled;
|
||||
const stateBadges = hasStateBadges ? (
|
||||
<>
|
||||
{cadence && <Badge variant="secondary">{cadence}</Badge>}
|
||||
{isCoach && (
|
||||
<Badge variant="outline">{t("measurementReminders.originCoach")}</Badge>
|
||||
)}
|
||||
@@ -781,7 +784,7 @@ function VorsorgeCard({
|
||||
</Badge>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
) : undefined;
|
||||
|
||||
// Single med-style kebab: Edit + Delete. The Delete item is the shared
|
||||
// confirm-on-delete control rendered as a full-width menu row.
|
||||
@@ -872,17 +875,17 @@ function VorsorgeCard({
|
||||
<Card>
|
||||
<CardContent className="flex items-center justify-between gap-3 px-4 py-2.5">
|
||||
<div className="min-w-0 space-y-0.5">
|
||||
<div className="flex flex-wrap items-baseline gap-x-2 text-sm">
|
||||
<div className="flex flex-wrap items-center gap-x-2 text-sm">
|
||||
<span className="truncate font-medium">
|
||||
{resolveReminderLabel(reminder, t)}
|
||||
</span>
|
||||
{cadence && <Badge variant="secondary">{cadence}</Badge>}
|
||||
{cadenceChip}
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-x-2 text-xs">
|
||||
<Badge variant="outline">
|
||||
<div className="text-muted-foreground flex flex-wrap items-center gap-x-2 text-xs">
|
||||
<span className="text-foreground">
|
||||
{t(`measurementReminders.${due.key}`, { days: due.days })}
|
||||
</Badge>
|
||||
<span className="text-muted-foreground">{categoryLabel}</span>
|
||||
</span>
|
||||
<span>{categoryLabel}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex shrink-0 items-center gap-1">
|
||||
@@ -913,29 +916,29 @@ function VorsorgeCard({
|
||||
// (MOD-06: never "Einnahme" / intake — a measurement is not an intake). The
|
||||
// "next" value carries the discreet neutral due badge; the "last" value is
|
||||
// the last satisfied date.
|
||||
// v1.18.6.1 — the due/overdue status renders as plain TEXT (not a chip),
|
||||
// and the "zuletzt erledigt" line ALWAYS renders, falling back to "—" when
|
||||
// there is no last-done value — mirroring the medication card's next/last
|
||||
// text rows.
|
||||
const lastValue = reminder.lastSatisfiedAt
|
||||
? fmt.date(new Date(reminder.lastSatisfiedAt))
|
||||
: null;
|
||||
: "—";
|
||||
const nextLastSlot = (
|
||||
<div className="min-h-[2.75rem] space-y-1.5 text-sm">
|
||||
<div className="text-muted-foreground flex items-baseline justify-between gap-3">
|
||||
<span className="min-w-0 flex-shrink truncate font-medium">
|
||||
{t("measurementReminders.nextDueLabel")}
|
||||
</span>
|
||||
<span className="text-right">
|
||||
<Badge variant="secondary">
|
||||
{t(`measurementReminders.${due.key}`, { days: due.days })}
|
||||
</Badge>
|
||||
<span className="text-foreground text-right">
|
||||
{t(`measurementReminders.${due.key}`, { days: due.days })}
|
||||
</span>
|
||||
</div>
|
||||
{lastValue && (
|
||||
<div className="text-muted-foreground flex items-baseline justify-between gap-3">
|
||||
<span className="min-w-0 flex-shrink truncate font-medium">
|
||||
{t("measurementReminders.lastDoneLabel")}
|
||||
</span>
|
||||
<span className="text-foreground text-right">{lastValue}</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="text-muted-foreground flex items-baseline justify-between gap-3">
|
||||
<span className="min-w-0 flex-shrink truncate font-medium">
|
||||
{t("measurementReminders.lastDoneLabel")}
|
||||
</span>
|
||||
<span className="text-foreground text-right">{lastValue}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -949,6 +952,7 @@ function VorsorgeCard({
|
||||
name={resolveReminderLabel(reminder, t)}
|
||||
dose=""
|
||||
categoryLabel={categoryLabel}
|
||||
nameChip={cadenceChip}
|
||||
stateBadges={stateBadges}
|
||||
actions={headerActions}
|
||||
/>
|
||||
|
||||
@@ -36,6 +36,13 @@ export interface MedicationCardHeaderProps {
|
||||
name: string;
|
||||
dose: string;
|
||||
categoryLabel: string;
|
||||
/**
|
||||
* v1.18.6.1 — an inline chip rendered DIRECTLY to the right of the name on
|
||||
* line 1 (e.g. the Vorsorge cadence chip "alle 7 Tage"), mirroring how the
|
||||
* medication card surfaces its cadence next to the drug name. Kept distinct
|
||||
* from `stateBadges` (which ride their own row below the category).
|
||||
*/
|
||||
nameChip?: ReactNode;
|
||||
stateBadges?: ReactNode;
|
||||
actions?: ReactNode;
|
||||
/**
|
||||
@@ -52,6 +59,7 @@ export function MedicationCardHeader({
|
||||
name,
|
||||
dose,
|
||||
categoryLabel,
|
||||
nameChip,
|
||||
stateBadges,
|
||||
actions,
|
||||
href,
|
||||
@@ -59,8 +67,11 @@ export function MedicationCardHeader({
|
||||
}: MedicationCardHeaderProps) {
|
||||
const body = (
|
||||
<>
|
||||
<CardTitle className="text-lg">
|
||||
{name} {dose}
|
||||
<CardTitle className="flex flex-wrap items-center gap-x-2 gap-y-1 text-lg">
|
||||
<span>
|
||||
{name} {dose}
|
||||
</span>
|
||||
{nameChip}
|
||||
</CardTitle>
|
||||
{/* D-H6 — state badges (without-notification, paused-since,
|
||||
inactive) used to share line 2 with the category badge
|
||||
|
||||
Reference in new issue
Block a user