mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 13:22:14 +00:00
merge(DF2): v1.21.0
This commit is contained in:
commit
a5031607d8
10 files changed
+44
-38
No files matched your search
@@ -59,6 +59,9 @@ test.describe("medication wizard — daily", () => {
|
||||
|
||||
// Step 4 — course window (today by default).
|
||||
await expectStep(page, 4);
|
||||
// `DateField` keeps the ISO value on a hidden native date input
|
||||
// (data-slot), while the visible overlay paints the locale-formatted
|
||||
// string. Assert the committed ISO value on the hidden input.
|
||||
await expect(
|
||||
page.locator('[data-slot="course-window-starts"]'),
|
||||
).toHaveValue(/^\d{4}-\d{2}-\d{2}$/);
|
||||
|
||||
@@ -62,7 +62,15 @@ test.describe("medication wizard — one-shot", () => {
|
||||
// Step 4 — course window. Set startsOn to a deterministic date so
|
||||
// the post body assertion below is stable.
|
||||
await expectStep(page, 4);
|
||||
await page.locator('[data-slot="course-window-starts"]').fill("2026-10-15");
|
||||
// `DateField` rides a visible text overlay (the data-testid) that parses
|
||||
// a typed ISO string back to the canonical value; the hidden native input
|
||||
// (data-slot) carries the committed ISO. Type into the overlay, then blur
|
||||
// so the parse commits.
|
||||
await page.getByTestId("course-window-starts-field").fill("2026-10-15");
|
||||
await page.getByTestId("course-window-starts-field").blur();
|
||||
await expect(
|
||||
page.locator('[data-slot="course-window-starts"]'),
|
||||
).toHaveValue("2026-10-15");
|
||||
await clickNext(page);
|
||||
|
||||
// Step 5 — pick Einmalig. The path compresses to 5 steps the
|
||||
|
||||
@@ -19,6 +19,7 @@ import { Activity, CalendarDays, NotebookPen, Thermometer } from "lucide-react";
|
||||
import { ResponsiveSheet } from "@/components/ui/responsive-sheet";
|
||||
import { SheetSection, SheetSectionCount } from "@/components/ui/sheet-section";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { DateField } from "@/components/ui/date-field";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
@@ -266,14 +267,13 @@ export function LogDaySheet({
|
||||
<Label htmlFor="illness-log-date" className="sr-only">
|
||||
{t("illness.sheet.day")}
|
||||
</Label>
|
||||
<Input
|
||||
<DateField
|
||||
id="illness-log-date"
|
||||
type="date"
|
||||
value={selectedDate}
|
||||
min={onsetDate}
|
||||
max={date}
|
||||
onChange={(e) => {
|
||||
if (e.target.value) setSelectedDate(e.target.value);
|
||||
onChange={(value) => {
|
||||
if (value) setSelectedDate(value);
|
||||
}}
|
||||
className="max-w-44"
|
||||
/>
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useState } from "react";
|
||||
|
||||
import { ResponsiveSheet } from "@/components/ui/responsive-sheet";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { DateField } from "@/components/ui/date-field";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
@@ -230,12 +231,11 @@ export function NewEpisodeSheet({
|
||||
|
||||
<div className="space-y-1.5">
|
||||
<Label htmlFor="illness-onset">{t("illness.new.onset")}</Label>
|
||||
<Input
|
||||
<DateField
|
||||
id="illness-onset"
|
||||
type="date"
|
||||
value={onset}
|
||||
max={today}
|
||||
onChange={(e) => setOnset(e.target.value)}
|
||||
onChange={setOnset}
|
||||
className="max-w-44"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { DateField } from "@/components/ui/date-field";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { useTranslations } from "@/lib/i18n/context";
|
||||
@@ -178,13 +179,10 @@ export function OcrRowEditor({
|
||||
<Label htmlFor={`${fieldId}-date`} className="text-xs">
|
||||
{t("labs.ocr.dateLabel")}
|
||||
</Label>
|
||||
<Input
|
||||
<DateField
|
||||
id={`${fieldId}-date`}
|
||||
type="date"
|
||||
value={row.takenAt ?? ""}
|
||||
onChange={(e) =>
|
||||
onChange({ ...row, takenAt: e.target.value || null })
|
||||
}
|
||||
onChange={(value) => onChange({ ...row, takenAt: value || null })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -64,6 +64,7 @@ import {
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { DateField } from "@/components/ui/date-field";
|
||||
import { EmptyState } from "@/components/ui/empty-state";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
@@ -598,12 +599,11 @@ export function VorsorgeSection({
|
||||
<Label htmlFor="vorsorge-anchor">
|
||||
{t("measurementReminders.form.firstDue")}
|
||||
</Label>
|
||||
<Input
|
||||
<DateField
|
||||
id="vorsorge-anchor"
|
||||
type="date"
|
||||
value={form.anchorDate}
|
||||
onChange={(e) =>
|
||||
setForm((f) => ({ ...f, anchorDate: e.target.value }))
|
||||
onChange={(value) =>
|
||||
setForm((f) => ({ ...f, anchorDate: value }))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
|
||||
import { useCallback, useId, useMemo } from "react";
|
||||
|
||||
import { DateField } from "@/components/ui/date-field";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { useTranslations } from "@/lib/i18n/context";
|
||||
@@ -602,13 +603,11 @@ function YearlyDate({
|
||||
<Label htmlFor={id} className="text-sm">
|
||||
{t(`${i18nPrefix}.yearly.date.label`)}
|
||||
</Label>
|
||||
<Input
|
||||
<DateField
|
||||
id={id}
|
||||
type="date"
|
||||
value={value}
|
||||
disabled={disabled}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
className="h-11"
|
||||
onChange={onChange}
|
||||
data-slot="cadence-yearly-date"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
import { useCallback, useId, useMemo } from "react";
|
||||
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { DateField } from "@/components/ui/date-field";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { useTranslations } from "@/lib/i18n/context";
|
||||
@@ -135,15 +135,15 @@ export function CourseWindowRow({
|
||||
<Label htmlFor={startId} className="text-sm">
|
||||
{t(`${i18nPrefix}.startsOn.label`)}
|
||||
</Label>
|
||||
<Input
|
||||
<DateField
|
||||
id={startId}
|
||||
type="date"
|
||||
value={startsIso}
|
||||
disabled={disabled}
|
||||
onChange={(e) => onStartsChange(e.target.value)}
|
||||
className="h-11 w-full"
|
||||
onChange={onStartsChange}
|
||||
className="w-full"
|
||||
aria-label={t(`${i18nPrefix}.startsOn.label`)}
|
||||
data-slot="course-window-starts"
|
||||
data-testid="course-window-starts-field"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -152,17 +152,16 @@ export function CourseWindowRow({
|
||||
<Label htmlFor={endId} className="text-sm">
|
||||
{t(`${i18nPrefix}.endsOn.label`)}
|
||||
</Label>
|
||||
<Input
|
||||
<DateField
|
||||
id={endId}
|
||||
type="date"
|
||||
value={endsIso}
|
||||
disabled={disabled || noEndDate || lockEndsToStart}
|
||||
readOnly={lockEndsToStart}
|
||||
onChange={(e) => onEndsChange(e.target.value)}
|
||||
className="h-11 w-full"
|
||||
onChange={onEndsChange}
|
||||
className="w-full"
|
||||
aria-label={t(`${i18nPrefix}.endsOn.label`)}
|
||||
aria-invalid={!valid || undefined}
|
||||
data-slot="course-window-ends"
|
||||
data-testid="course-window-ends-field"
|
||||
/>
|
||||
{lockEndsToStart && (
|
||||
<p
|
||||
|
||||
@@ -56,6 +56,7 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { DateField } from "@/components/ui/date-field";
|
||||
import { EmptyState } from "@/components/ui/empty-state";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import {
|
||||
@@ -649,12 +650,10 @@ export function AddInventoryDialog({
|
||||
>
|
||||
{t("medications.detail.bestand.addExpiryLabel")}
|
||||
</label>
|
||||
<Input
|
||||
<DateField
|
||||
id="inventory-add-expiry"
|
||||
type="date"
|
||||
autoComplete="off"
|
||||
value={expiry}
|
||||
onChange={(e) => setExpiry(e.target.value)}
|
||||
onChange={setExpiry}
|
||||
/>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { DateInput } from "@/components/ui/date-input";
|
||||
import { DateField } from "@/components/ui/date-field";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { NativeSelect } from "@/components/ui/native-select";
|
||||
import { PasswordInput } from "@/components/ui/password-input";
|
||||
@@ -373,10 +373,10 @@ export function AccountSection() {
|
||||
<div className="grid gap-4 sm:grid-cols-2">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="dob">{t("settings.dateOfBirth")}</Label>
|
||||
<DateInput
|
||||
<DateField
|
||||
id="dob"
|
||||
value={dateOfBirth}
|
||||
onChange={(e) => setDateOfBirth(e.target.value)}
|
||||
onChange={setDateOfBirth}
|
||||
max={new Date().toISOString().slice(0, 10)}
|
||||
/>
|
||||
<p className="text-muted-foreground text-xs">
|
||||
|
||||
Reference in new issue
Block a user