Rebuild TextField and CalendarField
This commit is contained in:
parent
1e77205518
commit
12004b8584
28 changed files with 783 additions and 845 deletions
|
|
@ -0,0 +1,8 @@
|
|||
.form {
|
||||
margin: 0 0 60px;
|
||||
}
|
||||
|
||||
.buttonWrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
172
frontend/src/components/CreateForm/CreateForm.tsx
Normal file
172
frontend/src/components/CreateForm/CreateForm.tsx
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue