1
Fork 0
mirror of https://github.com/Steffo99/festa.git synced 2024-10-16 15:07:27 +00:00

Fix datetime inputs

This commit is contained in:
Steffo 2022-06-10 05:21:02 +02:00
parent 870396c4cf
commit 3c15bdb80f
Signed by: steffo
GPG key ID: 6965406171929D01
6 changed files with 114 additions and 8 deletions

View file

@ -28,7 +28,11 @@ export function ActionEventList(props: HTMLProps<HTMLFormElement>) {
</> </>
} }
else if (!data) { else if (!data) {
contents = <Loading text={t("eventListLoading")} /> contents = <>
<p>
<Loading text={t("eventListLoading")} />
</p>
</>
} }
else { else {
if (data.length === 0) { if (data.length === 0) {

View file

@ -1,12 +1,23 @@
import { HTMLProps } from "react"; import { HTMLProps } from "react";
import { toDatetimeLocal } from "../../utils/dateFields";
import { FestaMoment } from "../extensions/FestaMoment"; import { FestaMoment } from "../extensions/FestaMoment";
import { Editable } from "./Editable"; import { Editable } from "./Editable";
export function EditableDateTimeLocal(props: HTMLProps<HTMLInputElement> & { value: Date }) {
export type EditableDateTimeLocalProps = Omit<HTMLProps<HTMLInputElement>, "value" | "max" | "min"> & { value: Date | null, max?: Date, min?: Date }
export function EditableDateTimeLocal(props: EditableDateTimeLocalProps) {
return ( return (
<Editable <Editable
editing={ editing={
<input type="datetime-local" {...props} value={props.value.toISOString()} /> <input
type="datetime-local"
{...props}
value={props.value ? toDatetimeLocal(props.value) : undefined}
min={props.min ? toDatetimeLocal(props.min) : undefined}
max={props.max ? toDatetimeLocal(props.max) : undefined}
/>
} }
preview={ preview={
<FestaMoment date={props.value} /> <FestaMoment date={props.value} />

View file

@ -0,0 +1,43 @@
import { faCalendar, faChevronRight } from "@fortawesome/free-solid-svg-icons";
import { useDefinedContext } from "../../utils/definedContext";
import { FestaIcon } from "../extensions/FestaIcon";
import { FormFromTo } from "../form/FormFromTo";
import { EditableDateTimeLocal, EditableDateTimeLocalProps } from "./EditableDateTimeLocal";
import { EditingContext } from "./EditingContext";
type EditableEventDurationProps = {
startProps: EditableDateTimeLocalProps,
endProps: EditableDateTimeLocalProps,
}
export function EditableEventDuration({ startProps, endProps }: EditableEventDurationProps) {
const [editing,] = useDefinedContext(EditingContext)
return (
<FormFromTo
preview={!editing}
icon={
<FestaIcon icon={faCalendar} />
}
start={
<EditableDateTimeLocal
max={endProps.value ?? undefined}
{...startProps}
/>
}
connector={
<FestaIcon
icon={faChevronRight}
/>
}
end={
<EditableDateTimeLocal
min={startProps.value ?? undefined}
{...endProps}
/>
}
/>
)
}

View file

@ -1,7 +1,7 @@
import { useTranslation } from "next-i18next" import { useTranslation } from "next-i18next"
type FestaMomentProps = { type FestaMomentProps = {
date: Date, date: Date | null,
} }
/** /**
@ -10,7 +10,7 @@ type FestaMomentProps = {
export function FestaMoment({ date }: FestaMomentProps) { export function FestaMoment({ date }: FestaMomentProps) {
const { t } = useTranslation() const { t } = useTranslation()
if (Number.isNaN(date.getTime())) { if (!date || Number.isNaN(date.getTime())) {
return ( return (
<span className="disabled"> <span className="disabled">
{t("dateNaN")} {t("dateNaN")}
@ -18,9 +18,22 @@ export function FestaMoment({ date }: FestaMomentProps) {
) )
} }
const now = new Date()
const machine = date.toISOString()
let human
// If the date is less than 24 hours away, display just the time
if (date.getTime() - now.getTime() < 86_400_000) {
human = date.toLocaleTimeString()
}
// Otherwise, display the full date
else {
human = date.toLocaleString()
}
return ( return (
<time dateTime={date.toISOString()}> <time dateTime={machine}>
{date.toLocaleString()} {human}
</time> </time>
) )
} }

View file

@ -16,6 +16,8 @@ import { ToolToggleVisible } from "../../components/tools/ToolToggleVisible";
import { WorkInProgress } from "../../components/WorkInProgress"; import { WorkInProgress } from "../../components/WorkInProgress";
import { usePostcardImage } from "../../components/postcard/usePostcardImage"; import { usePostcardImage } from "../../components/postcard/usePostcardImage";
import defaultPostcard from "../../public/postcards/adi-goldstein-Hli3R6LKibo-unsplash.jpg" import defaultPostcard from "../../public/postcards/adi-goldstein-Hli3R6LKibo-unsplash.jpg"
import { EditableEventDuration } from "../../components/editable/EditableEventDuration";
import { fromDatetimeLocal } from "../../utils/dateFields";
export async function getServerSideProps(context: NextPageContext) { export async function getServerSideProps(context: NextPageContext) {
@ -54,6 +56,8 @@ export default function PageEventDetail({ initialEvent }: PageEventDetailProps)
const displayedPostcard = event.postcard || defaultPostcard.src const displayedPostcard = event.postcard || defaultPostcard.src
usePostcardImage(`url(${displayedPostcard})`) usePostcardImage(`url(${displayedPostcard})`)
console.debug("Event:", event)
return <> return <>
<Head> <Head>
<title key="title">{initialEvent.name} - {t("siteTitle")}</title> <title key="title">{initialEvent.name} - {t("siteTitle")}</title>
@ -85,7 +89,18 @@ export default function PageEventDetail({ initialEvent }: PageEventDetailProps)
placeholder={t("eventDetailsDescriptionPlaceholder")} placeholder={t("eventDetailsDescriptionPlaceholder")}
/> />
} }
daterange={<></>} daterange={
<EditableEventDuration {...{
startProps: {
value: event.startingAt,
onChange: (e: ChangeEvent<HTMLInputElement>) => setEvent({ ...event, startingAt: fromDatetimeLocal(e.target.value) }),
},
endProps: {
value: event.endingAt,
onChange: (e: ChangeEvent<HTMLInputElement>) => setEvent({ ...event, endingAt: fromDatetimeLocal(e.target.value) }),
}
}} />
}
/> />
</EditingContext.Provider> </EditingContext.Provider>
</> </>

20
utils/dateFields.ts Normal file
View file

@ -0,0 +1,20 @@
export function toDatetimeLocal(date: Date | null | undefined): string | undefined {
if (date === undefined) {
return undefined
}
else if (date === null) {
return ""
}
else {
return date.toISOString().match(/(.+)[Z]$/)![1]
}
}
export function fromDatetimeLocal(str: string): Date | null {
if (str === "") {
return null
}
else {
return new Date(`${str}Z`)
}
}