mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 05:12:14 +00:00
fix(dashboard): clarify dose field is informational only in medication quick-add
The dose field on the medication-intake quick-add sheet was rendered editable but the POST body has no `dose` slot — any user edit was silently dropped, so a user typing "5 mg" for a half-pill day saw the catalogue dose recorded instead. The previous hint copy did not warn about the constraint, leaving the user's mental model out of sync with the persisted data. Render the field read-only with a muted background, drop the tab order on the input, and rewrite the hint copy across all six locales so the user knows that variable doses are coming in a later version and the standard dose is recorded for now. The setDoseOverride state holder stays so the reset-on-medication-switch keeps working when the v1.4.38 doseOverride schema lands.
This commit is contained in:
1 parent
ac46f8f9c8
commit
bd841aee99
7 files changed
+29
-25
No files matched your search
+1
-1
@@ -252,7 +252,7 @@
|
||||
"medicationPlaceholder": "Medikament auswählen",
|
||||
"doseLabel": "Dosis",
|
||||
"dosePlaceholder": "z. B. 5 mg",
|
||||
"doseHint": "Vorbelegt mit der Standarddosis. Bei Bedarf anpassen.",
|
||||
"doseHint": "Aktuell wird die Standarddosis erfasst. Abweichende Dosen kommen in einer kommenden Version.",
|
||||
"timeLabel": "Zeitpunkt",
|
||||
"saveError": "Einnahme konnte nicht gespeichert werden.",
|
||||
"emptyTitle": "Noch keine Medikamente angelegt",
|
||||
|
||||
+1
-1
@@ -252,7 +252,7 @@
|
||||
"medicationPlaceholder": "Select a medication",
|
||||
"doseLabel": "Dose",
|
||||
"dosePlaceholder": "e.g. 5 mg",
|
||||
"doseHint": "Pre-filled with the default dose. Adjust if needed.",
|
||||
"doseHint": "Currently the standard dose is recorded. Variable doses are coming in a later version.",
|
||||
"timeLabel": "Time taken",
|
||||
"saveError": "Could not save medication intake.",
|
||||
"emptyTitle": "No medications yet",
|
||||
|
||||
+1
-1
@@ -252,7 +252,7 @@
|
||||
"medicationPlaceholder": "Select a medication",
|
||||
"doseLabel": "Dose",
|
||||
"dosePlaceholder": "e.g. 5 mg",
|
||||
"doseHint": "Pre-filled with the default dose. Adjust if needed.",
|
||||
"doseHint": "Currently the standard dose is recorded. Variable doses are coming in a later version.",
|
||||
"timeLabel": "Time taken",
|
||||
"saveError": "Could not save medication intake.",
|
||||
"emptyTitle": "No medications yet",
|
||||
|
||||
+1
-1
@@ -252,7 +252,7 @@
|
||||
"medicationPlaceholder": "Select a medication",
|
||||
"doseLabel": "Dose",
|
||||
"dosePlaceholder": "e.g. 5 mg",
|
||||
"doseHint": "Pre-filled with the default dose. Adjust if needed.",
|
||||
"doseHint": "Currently the standard dose is recorded. Variable doses are coming in a later version.",
|
||||
"timeLabel": "Time taken",
|
||||
"saveError": "Could not save medication intake.",
|
||||
"emptyTitle": "No medications yet",
|
||||
|
||||
+1
-1
@@ -252,7 +252,7 @@
|
||||
"medicationPlaceholder": "Select a medication",
|
||||
"doseLabel": "Dose",
|
||||
"dosePlaceholder": "e.g. 5 mg",
|
||||
"doseHint": "Pre-filled with the default dose. Adjust if needed.",
|
||||
"doseHint": "Currently the standard dose is recorded. Variable doses are coming in a later version.",
|
||||
"timeLabel": "Time taken",
|
||||
"saveError": "Could not save medication intake.",
|
||||
"emptyTitle": "No medications yet",
|
||||
|
||||
+1
-1
@@ -252,7 +252,7 @@
|
||||
"medicationPlaceholder": "Select a medication",
|
||||
"doseLabel": "Dose",
|
||||
"dosePlaceholder": "e.g. 5 mg",
|
||||
"doseHint": "Pre-filled with the default dose. Adjust if needed.",
|
||||
"doseHint": "Currently the standard dose is recorded. Variable doses are coming in a later version.",
|
||||
"timeLabel": "Time taken",
|
||||
"saveError": "Could not save medication intake.",
|
||||
"emptyTitle": "No medications yet",
|
||||
|
||||
@@ -46,15 +46,14 @@ import {
|
||||
* sheet body renders an EmptyState-style hint instead of an
|
||||
* unusable form.
|
||||
* 2. Dose. Pre-filled from the medication's catalogue dose for
|
||||
* visual confirmation ("this is the strength I'm logging"); the
|
||||
* field is editable but the POST body does NOT carry the dose
|
||||
* override yet — the intake event always references the
|
||||
* medication's current catalogue dose. The boundary lives in the
|
||||
* `intakeSchema` (no `dose` field), so when the user wants to
|
||||
* record a half/double dose they still edit the medication
|
||||
* itself on `/medications`. Keeping the input editable preserves
|
||||
* the visual contract Marc asked for ("show me what I'm
|
||||
* logging") without misrepresenting the wire shape.
|
||||
* visual confirmation ("this is the strength I'm logging").
|
||||
* v1.4.37 W10 — rendered read-only because the POST body has no
|
||||
* `dose` field; any user edit would be silently dropped. When
|
||||
* the user wants to record a half/double dose they still edit
|
||||
* the medication itself on `/medications` until the v1.4.38
|
||||
* schema grows a `doseOverride` slot. Hint copy below the
|
||||
* field warns about the constraint so the user's mental model
|
||||
* tracks what the server persists.
|
||||
* 3. Time taken. Defaults to `now` (local datetime-local format
|
||||
* shaped the same as `MoodForm`).
|
||||
*
|
||||
@@ -190,11 +189,13 @@ export function MedicationIntakeQuickAdd({
|
||||
const [medicationOverride, setMedicationOverride] = useState<string | null>(
|
||||
null,
|
||||
);
|
||||
// User-driven dose override; `null` means "use the medication's
|
||||
// default". The picker auto-prefills the dose input by deriving it
|
||||
// from the selected medication during render — keeping it state-free
|
||||
// until the user actually types so we don't fight the linter's
|
||||
// `react-hooks/set-state-in-effect` guard.
|
||||
// v1.4.37 W10 — the dose field is informational only. The intake
|
||||
// POST body has no `dose` slot, so any user edit would be silently
|
||||
// dropped on submit. Until the v1.4.38 schema grows a `doseOverride`
|
||||
// field, render the input as read-only so the user's mental model
|
||||
// tracks what the server actually persists. The state holder is
|
||||
// kept (as `null`) so the medication-switch handler still resets
|
||||
// the slot cleanly if the schema ever grows the field.
|
||||
const [doseOverride, setDoseOverride] = useState<string | null>(null);
|
||||
const [takenAt, setTakenAt] = useState<string>(getDefaultIntakeAtValue);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -215,8 +216,10 @@ export function MedicationIntakeQuickAdd({
|
||||
function handleMedicationChange(value: string) {
|
||||
setMedicationOverride(value);
|
||||
// Reset the dose override when the medication changes so the new
|
||||
// default flows through on the next render. The user can still
|
||||
// override it after the selection by typing into the dose field.
|
||||
// default flows through on the next render. The dose field is
|
||||
// currently read-only (see v1.4.37 W10 note above), but the reset
|
||||
// stays in place so the slot is ready to switch back to editable
|
||||
// when the v1.4.38 doseOverride schema lands.
|
||||
setDoseOverride(null);
|
||||
}
|
||||
|
||||
@@ -401,14 +404,15 @@ export function MedicationIntakeQuickAdd({
|
||||
id="medication-intake-dose"
|
||||
data-testid="medication-intake-quick-add-dose"
|
||||
value={dose}
|
||||
onChange={(e) => setDoseOverride(e.target.value)}
|
||||
readOnly
|
||||
aria-readonly="true"
|
||||
tabIndex={-1}
|
||||
placeholder={
|
||||
selectedMedication?.dose ??
|
||||
t("dashboard.medicationIntakeQuickAdd.dosePlaceholder")
|
||||
}
|
||||
enterKeyHint="done"
|
||||
autoComplete="off"
|
||||
className="min-h-11"
|
||||
className="min-h-11 bg-muted/40"
|
||||
/>
|
||||
<p className="text-muted-foreground text-xs">
|
||||
{t("dashboard.medicationIntakeQuickAdd.doseHint")}
|
||||
|
||||
Reference in new issue
Block a user