mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 21:32:18 +00:00
fix(forms): hint browser locale on date and datetime inputs
Native `<input type="date">` and `<input type="datetime-local">`
were rendering `mm/dd/yyyy` even when the German locale was
active, because Chromium picks the input's locale from the
nearest `lang` attribute on the element rather than from
`<html lang>`. Pass `lang={locale}` on every date/datetime input
in the app — onboarding DOB, account DOB, export filters,
doctor-report range, measurement / medication / mood timestamp
fields — so DE users now see `TT.MM.JJJJ`. Display formatting
already routed through `useFormatters()`; this closes the form
half of the same gap.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
7a6bc812c9
commit
ff6e18473a
9 files changed
+21
-7
No files matched your search
@@ -304,6 +304,7 @@ export default function OnboardingPage() {
|
||||
<Input
|
||||
id="ob-dob"
|
||||
type="date"
|
||||
lang={locale}
|
||||
value={dateOfBirth}
|
||||
onChange={(e) => setDateOfBirth(e.target.value)}
|
||||
max={new Date().toISOString().slice(0, 10)}
|
||||
|
||||
@@ -80,7 +80,7 @@ export function DoctorReportDialog({
|
||||
defaultPracticeName,
|
||||
onSubmit,
|
||||
}: DoctorReportDialogProps) {
|
||||
const { t } = useTranslations();
|
||||
const { t, locale } = useTranslations();
|
||||
const [startDate, setStartDate] = useState<string>(defaultStartIso);
|
||||
const [endDate, setEndDate] = useState<string>(todayIso);
|
||||
const [practiceName, setPracticeName] = useState<string>("");
|
||||
@@ -194,6 +194,7 @@ export function DoctorReportDialog({
|
||||
<Input
|
||||
id="dr-start"
|
||||
type="date"
|
||||
lang={locale}
|
||||
value={startDate}
|
||||
max={endDate || todayIso()}
|
||||
onChange={(e) => {
|
||||
@@ -210,6 +211,7 @@ export function DoctorReportDialog({
|
||||
<Input
|
||||
id="dr-end"
|
||||
type="date"
|
||||
lang={locale}
|
||||
value={endDate}
|
||||
min={startDate}
|
||||
max={todayIso()}
|
||||
|
||||
@@ -117,7 +117,7 @@ export function MeasurementForm({
|
||||
onCancel,
|
||||
defaultType,
|
||||
}: MeasurementFormProps) {
|
||||
const { t } = useTranslations();
|
||||
const { t, locale } = useTranslations();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
// Normalize legacy BP types to combined mode
|
||||
@@ -361,6 +361,7 @@ export function MeasurementForm({
|
||||
<Input
|
||||
id="measuredAt"
|
||||
type="datetime-local"
|
||||
lang={locale}
|
||||
value={measuredAt}
|
||||
onChange={(e) => setMeasuredAt(e.target.value)}
|
||||
required
|
||||
|
||||
@@ -105,7 +105,7 @@ function toDateTimeLocalValue(isoString: string): string {
|
||||
}
|
||||
|
||||
export function MeasurementList({ onEdit, onAddFirst }: MeasurementListProps) {
|
||||
const { t } = useTranslations();
|
||||
const { t, locale } = useTranslations();
|
||||
const fmt = useFormatters();
|
||||
const { isAuthenticated } = useAuth();
|
||||
const queryClient = useQueryClient();
|
||||
@@ -562,6 +562,7 @@ export function MeasurementList({ onEdit, onAddFirst }: MeasurementListProps) {
|
||||
<Input
|
||||
id="edit-measuredAt"
|
||||
type="datetime-local"
|
||||
lang={locale}
|
||||
value={editMeasuredAt}
|
||||
onChange={(e) => setEditMeasuredAt(e.target.value)}
|
||||
required
|
||||
|
||||
@@ -95,7 +95,7 @@ export function IntakeHistoryList({
|
||||
}: IntakeHistoryListProps) {
|
||||
const { isAuthenticated } = useAuth();
|
||||
const queryClient = useQueryClient();
|
||||
const { t } = useTranslations();
|
||||
const { t, locale } = useTranslations();
|
||||
|
||||
const sourceLabels: Record<string, string> = {
|
||||
WEB: t("medications.sourceWeb"),
|
||||
@@ -545,6 +545,7 @@ export function IntakeHistoryList({
|
||||
<Input
|
||||
id="edit-scheduledFor"
|
||||
type="datetime-local"
|
||||
lang={locale}
|
||||
value={editScheduledFor}
|
||||
onChange={(e) => setEditScheduledFor(e.target.value)}
|
||||
required
|
||||
@@ -558,6 +559,7 @@ export function IntakeHistoryList({
|
||||
<Input
|
||||
id="edit-takenAt"
|
||||
type="datetime-local"
|
||||
lang={locale}
|
||||
value={editTakenAt}
|
||||
onChange={(e) => setEditTakenAt(e.target.value)}
|
||||
disabled={editSkipped}
|
||||
@@ -689,6 +691,7 @@ export function IntakeHistoryList({
|
||||
<Input
|
||||
id="create-scheduledFor"
|
||||
type="datetime-local"
|
||||
lang={locale}
|
||||
value={createScheduledFor}
|
||||
onChange={(e) => setCreateScheduledFor(e.target.value)}
|
||||
required
|
||||
@@ -702,6 +705,7 @@ export function IntakeHistoryList({
|
||||
<Input
|
||||
id="create-takenAt"
|
||||
type="datetime-local"
|
||||
lang={locale}
|
||||
value={createTakenAt}
|
||||
onChange={(e) => setCreateTakenAt(e.target.value)}
|
||||
disabled={createSkipped}
|
||||
|
||||
@@ -37,7 +37,7 @@ function getDefaultMoodLoggedAtValue() {
|
||||
}
|
||||
|
||||
export function MoodForm({ onSuccess, onCancel }: MoodFormProps) {
|
||||
const { t } = useTranslations();
|
||||
const { t, locale } = useTranslations();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const [mood, setMood] = useState("");
|
||||
@@ -135,6 +135,7 @@ export function MoodForm({ onSuccess, onCancel }: MoodFormProps) {
|
||||
<Input
|
||||
id="mood-logged-at"
|
||||
type="datetime-local"
|
||||
lang={locale}
|
||||
value={moodLoggedAt}
|
||||
onChange={(e) => setMoodLoggedAt(e.target.value)}
|
||||
required
|
||||
|
||||
@@ -117,7 +117,7 @@ interface MoodListProps {
|
||||
}
|
||||
|
||||
export function MoodList({ onAddFirst }: MoodListProps = {}) {
|
||||
const { t } = useTranslations();
|
||||
const { t, locale } = useTranslations();
|
||||
const fmt = useFormatters();
|
||||
const { isAuthenticated } = useAuth();
|
||||
const queryClient = useQueryClient();
|
||||
@@ -572,6 +572,7 @@ export function MoodList({ onAddFirst }: MoodListProps = {}) {
|
||||
<Input
|
||||
id="edit-mood-logged-at"
|
||||
type="datetime-local"
|
||||
lang={locale}
|
||||
value={editMoodLoggedAt}
|
||||
onChange={(e) => setEditMoodLoggedAt(e.target.value)}
|
||||
required
|
||||
|
||||
@@ -386,6 +386,7 @@ export function AccountSection() {
|
||||
<Input
|
||||
id="dob"
|
||||
type="date"
|
||||
lang={locale}
|
||||
value={dateOfBirth}
|
||||
onChange={(e) => setDateOfBirth(e.target.value)}
|
||||
max={new Date().toISOString().slice(0, 10)}
|
||||
|
||||
@@ -253,7 +253,7 @@ function DateRangeFields({
|
||||
setUntil,
|
||||
idPrefix,
|
||||
}: DateRangeFieldsProps) {
|
||||
const { t } = useTranslations();
|
||||
const { t, locale } = useTranslations();
|
||||
return (
|
||||
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
||||
<div className="space-y-1.5">
|
||||
@@ -263,6 +263,7 @@ function DateRangeFields({
|
||||
<Input
|
||||
id={`${idPrefix}-since`}
|
||||
type="date"
|
||||
lang={locale}
|
||||
value={since}
|
||||
onChange={(e) => setSince(e.target.value)}
|
||||
max={until || undefined}
|
||||
@@ -275,6 +276,7 @@ function DateRangeFields({
|
||||
<Input
|
||||
id={`${idPrefix}-until`}
|
||||
type="date"
|
||||
lang={locale}
|
||||
value={until}
|
||||
onChange={(e) => setUntil(e.target.value)}
|
||||
min={since || undefined}
|
||||
|
||||
Reference in new issue
Block a user