Fix time inputs

This commit is contained in:
jude
2024-03-01 16:54:56 +00:00
parent 8c2296b9c8
commit 0e0ab053f3
3 changed files with 113 additions and 56 deletions

View File

@ -43,11 +43,11 @@ export const Settings = () => {
<label class="label collapses">
Time*
<TimeInput
defaultValue={reminder.utc_time.setZone(timezone)}
defaultValue={reminder.utc_time}
onInput={(time: DateTime) => {
setReminder((reminder) => ({
...reminder,
utc_time: time.toUTC(),
utc_time: time,
}));
}}
/>
@ -98,11 +98,11 @@ export const Settings = () => {
<label class="label">
Expiration
<TimeInput
defaultValue={reminder.expires?.setZone(timezone)}
defaultValue={reminder.expires}
onInput={(time: DateTime) => {
setReminder((reminder) => ({
...reminder,
expires: time?.toUTC(),
expires: time,
}));
}}
/>

View File

@ -1,14 +1,42 @@
import { useEffect, useRef, useState } from "preact/hooks";
import { useCallback, useEffect, useRef, useState } from "preact/hooks";
import { DateTime } from "luxon";
import { useFlash } from "../App/FlashContext";
import { useTimezone } from "../App/TimezoneProvider";
type TimeUpdate = {
year?: number | null;
month?: number;
day?: number;
hour?: number;
minute?: number;
second?: number;
};
export const TimeInput = ({ defaultValue, onInput }) => {
const ref = useRef(null);
const [time, setTime] = useState(defaultValue);
const [timezone] = useTimezone();
const [time, setTime] = useState(
defaultValue ? DateTime.fromISO(defaultValue).setZone(timezone) : null,
);
const updateTime = useCallback(
(upd: TimeUpdate) => {
if (upd === null) {
setTime(null);
}
let newTime = time;
if (newTime === null) {
newTime = DateTime.now().setZone(timezone);
}
setTime(newTime.set(upd));
},
[time, timezone],
);
useEffect(() => {
onInput(time);
onInput(time?.toFormat("yyyy-LL-dd'T'HH:mm:ss"));
}, [time]);
const flash = useFlash();
@ -54,12 +82,20 @@ export const TimeInput = ({ defaultValue, onInput }) => {
pattern="\d*"
maxlength={4}
placeholder="YYYY"
value={time?.year.toLocaleString("en-US", {
minimumIntegerDigits: 4,
useGrouping: false,
})}
value={
time
? time.year.toLocaleString("en-US", {
minimumIntegerDigits: 4,
useGrouping: false,
})
: ""
}
onBlur={(ev) => {
setTime(time.set({ year: ev.currentTarget.value }));
ev.currentTarget.value
? updateTime({
year: parseInt(ev.currentTarget.value),
})
: updateTime(null);
}}
></input>{" "}
</label>
@ -77,9 +113,19 @@ export const TimeInput = ({ defaultValue, onInput }) => {
pattern="\d*"
maxlength={2}
placeholder="MM"
value={time?.month.toLocaleString("en-US", { minimumIntegerDigits: 2 })}
value={
time
? time.month.toLocaleString("en-US", {
minimumIntegerDigits: 2,
})
: ""
}
onBlur={(ev) => {
setTime(time.set({ month: ev.currentTarget.value }));
ev.currentTarget.value
? updateTime({
month: parseInt(ev.currentTarget.value),
})
: updateTime(null);
}}
></input>{" "}
</label>
@ -97,9 +143,17 @@ export const TimeInput = ({ defaultValue, onInput }) => {
pattern="\d*"
maxlength={2}
placeholder="DD"
value={time?.day.toLocaleString("en-US", { minimumIntegerDigits: 2 })}
value={
time
? time.day.toLocaleString("en-US", { minimumIntegerDigits: 2 })
: ""
}
onBlur={(ev) => {
setTime(time.set({ day: ev.currentTarget.value }));
ev.currentTarget.value
? updateTime({
day: parseInt(ev.currentTarget.value),
})
: updateTime(null);
}}
></input>{" "}
</label>
@ -116,9 +170,17 @@ export const TimeInput = ({ defaultValue, onInput }) => {
pattern="\d*"
maxlength={2}
placeholder="hh"
value={time?.hour.toLocaleString("en-US", { minimumIntegerDigits: 2 })}
value={
time
? time.hour.toLocaleString("en-US", { minimumIntegerDigits: 2 })
: ""
}
onBlur={(ev) => {
setTime(time.set({ hour: ev.currentTarget.value }));
ev.currentTarget.value
? updateTime({
hour: parseInt(ev.currentTarget.value),
})
: updateTime(null);
}}
></input>{" "}
</label>
@ -136,11 +198,19 @@ export const TimeInput = ({ defaultValue, onInput }) => {
pattern="\d*"
maxlength={2}
placeholder="mm"
value={time?.minute.toLocaleString("en-US", {
minimumIntegerDigits: 2,
})}
value={
time
? time.minute.toLocaleString("en-US", {
minimumIntegerDigits: 2,
})
: ""
}
onBlur={(ev) => {
setTime(time.set({ minute: ev.currentTarget.value }));
ev.currentTarget.value
? updateTime({
minute: parseInt(ev.currentTarget.value),
})
: updateTime(null);
}}
></input>{" "}
</label>
@ -158,11 +228,19 @@ export const TimeInput = ({ defaultValue, onInput }) => {
pattern="\d*"
maxlength={2}
placeholder="ss"
value={time?.second.toLocaleString("en-US", {
minimumIntegerDigits: 2,
})}
value={
time
? time.second.toLocaleString("en-US", {
minimumIntegerDigits: 2,
})
: ""
}
onBlur={(ev) => {
setTime(time.set({ second: ev.currentTarget.value }));
ev.currentTarget.value
? updateTime({
second: parseInt(ev.currentTarget.value),
})
: updateTime(null);
}}
></input>{" "}
</label>
@ -200,7 +278,9 @@ export const TimeInput = ({ defaultValue, onInput }) => {
}
ref={ref}
onInput={(ev) => {
setTime(DateTime.fromISO(ev.currentTarget.value));
ev.currentTarget.value === ""
? setTime(null)
: setTime(DateTime.fromISO(ev.currentTarget.value));
}}
></input>
</>