Rebuild TextField and CalendarField

This commit is contained in:
Ben Grant 2023-05-21 21:34:06 +10:00
parent 1e77205518
commit 12004b8584
28 changed files with 783 additions and 845 deletions

View file

@ -0,0 +1,8 @@
.form {
margin: 0 0 60px;
}
.buttonWrapper {
display: flex;
justify-content: center;
}

View file

@ -0,0 +1,172 @@
'use client'
import { useEffect, useState } from 'react'
import { SubmitHandler, useForm } from 'react-hook-form'
import { useRouter } from 'next/navigation'
import Button from '/src/components/Button/Button'
import CalendarField from '/src/components/CalendarField/CalendarField'
import { default as ErrorAlert } from '/src/components/Error/Error'
import TextField from '/src/components/TextField/TextField'
import ToggleField from '/src/components/ToggleField/ToggleField'
import { API_BASE } from '/src/config/api'
import dayjs from '/src/config/dayjs'
import { useTranslation } from '/src/i18n/client'
import timezones from '/src/res/timezones.json'
import styles from './CreateForm.module.scss'
interface Fields {
name: string
dates: string[]
time: {
start: number
end: number
}
timezone: string
}
const defaultValues: Fields = {
name: '',
dates: [],
time: { start: 9, end: 17 },
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
}
const CreateForm = () => {
const { t } = useTranslation('home')
const { push } = useRouter()
const {
register,
handleSubmit,
control,
} = useForm({ defaultValues })
const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState<React.ReactNode>()
const onSubmit: SubmitHandler<Fields> = async values => {
console.log({values})
setIsLoading(true)
setError(undefined)
const { name, dates, time, timezone } = values
try {
if (dates.length === 0) {
return setError(t('form.errors.no_dates'))
}
const isSpecificDates = typeof dates[0] === 'string' && dates[0].length === 8
if (time.start === time.end) {
return setError(t('form.errors.same_times'))
}
const times = dates.reduce((times, date) => {
const day = []
for (let i = time.start; i < (time.start > time.end ? 24 : time.end); i++) {
if (isSpecificDates) {
day.push(
dayjs.tz(date, 'DDMMYYYY', timezone)
.hour(i).minute(0).utc().format('HHmm-DDMMYYYY')
)
} else {
day.push(
dayjs().tz(timezone)
.day(date).hour(i).minute(0).utc().format('HHmm-d')
)
}
}
if (time.start > time.end) {
for (let i = 0; i < time.end; i++) {
if (isSpecificDates) {
day.push(
dayjs.tz(date, 'DDMMYYYY', timezone)
.hour(i).minute(0).utc().format('HHmm-DDMMYYYY')
)
} else {
day.push(
dayjs().tz(timezone)
.day(date).hour(i).minute(0).utc().format('HHmm-d')
)
}
}
}
return [...times, ...day]
}, [])
if (times.length === 0) {
return setError(t('form.errors.no_time'))
}
const res = await fetch(new URL('/event', API_BASE), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name,
times,
timezone,
}),
})
if (!res.ok) {
console.error(res)
throw new Error('Failed to create event')
}
const { id } = await res.json()
// Navigate to the new event
push(`/${id}`)
} catch (e) {
setError(t('form.errors.unknown'))
console.error(e)
} finally {
setIsLoading(false)
}
}
return <form className={styles.form} onSubmit={handleSubmit(onSubmit)} id="create">
<TextField
label={t('form.name.label')}
description={t('form.name.sublabel')}
type="text"
{...register('name')}
/>
<CalendarField
label={t('form.dates.label')}
description={t('form.dates.sublabel')}
control={control}
name="dates"
/>
{/* <TimeRangeField
label={t('form.times.label')}
subLabel={t('form.times.sublabel')}
required
setValue={setValue}
{...register('time')}
/>
<SelectField
label={t('form.timezone.label')}
options={timezones}
required
{...register('timezone')}
defaultOption={t('form.timezone.defaultOption')}
/> */}
<ErrorAlert onClose={() => setError(undefined)}>{error}</ErrorAlert>
<div className={styles.buttonWrapper}>
<Button
type="submit"
isLoading={isLoading}
disabled={isLoading}
>{t('form.button')}</Button>
</div>
</form>
}
export default CreateForm