mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
A medication's dose is stored as free text the wizard composes from an
amount and a unit token ("1 pieces", "2 tablets"), and the card rendered
that token verbatim glued onto the name — so the unit showed in English
on every locale and the title read "Test ABC 1 pieces".
Translate the dose at display time: a formatDose helper splits the stored
string and runs a known unit token through the existing unit messages, so
"1 pieces" reads "1 Stück" / "1 piece(s)" per locale while a custom
free-text dose passes through untouched. The card header now carries the
name alone on its title line with the dose on a muted line beneath it,
above the category badge; the detail view, table and intake dialogs
localise the same way. Vorsorge and lab rows pass an empty dose so they
render no extra line.
46 lines
1.6 KiB
TypeScript
46 lines
1.6 KiB
TypeScript
import { DOSE_UNIT_KEYS } from "./dose-units";
|
|
|
|
/**
|
|
* Display-time dose formatter.
|
|
*
|
|
* The wizard composes `Medication.dose` as a free-text string
|
|
* `"{amount} {unitKey}"` storing the RAW unit key (e.g. "1 pieces",
|
|
* "5 mg"). Rendered verbatim that leaks the untranslated English key onto
|
|
* the card — "Test ABC 1 pieces" even on a German UI. This helper splits
|
|
* the amount from the unit and, when the unit is one of the canonical
|
|
* {@link DOSE_UNIT_KEYS}, swaps it for the localised label
|
|
* (`medications.wizard.steps.step3.unit.<key>`). A custom free-text dose
|
|
* the wizard never produced (e.g. "1 puff morning") passes through
|
|
* unchanged.
|
|
*
|
|
* Pure + SSR-safe: takes the `t` accessor as a parameter, no React hook.
|
|
*/
|
|
|
|
// Mirrors `parseDoseExpression` in wizard-payload.ts — split on a leading
|
|
// number ("5 mg" → {amount:"5", unit:"mg"}); no number → {amount:"", unit:raw}.
|
|
const DOSE_EXPR_RE = /^\s*(\d+(?:[.,]\d+)?)\s*(.*)$/;
|
|
|
|
const KNOWN_UNITS = new Set<string>(DOSE_UNIT_KEYS);
|
|
|
|
export function formatDose(
|
|
raw: string | null | undefined,
|
|
t: (key: string) => string,
|
|
): string {
|
|
if (!raw) return "";
|
|
const trimmed = raw.trim();
|
|
if (!trimmed) return "";
|
|
|
|
const match = DOSE_EXPR_RE.exec(trimmed);
|
|
const amount = match ? (match[1] ?? "") : "";
|
|
const unit = match ? (match[2] ?? "").trim() : trimmed;
|
|
|
|
const key = unit.toLowerCase();
|
|
if (KNOWN_UNITS.has(key)) {
|
|
const label = t(`medications.wizard.steps.step3.unit.${key}`);
|
|
return amount ? `${amount} ${label}` : label;
|
|
}
|
|
|
|
// Custom free-text dose (the wizard never minted this unit) — leave it be.
|
|
return raw;
|
|
}
|