91 lines
2.4 KiB
TypeScript
91 lines
2.4 KiB
TypeScript
import { h, type FunctionComponent, type TargetedSubmitEvent } from 'preact'
|
|
import { useCallback } from 'preact/hooks'
|
|
import rek, { type FetchError } from 'rek'
|
|
|
|
import useRequestState from '../../shared/hooks/use_request_state.ts'
|
|
import serializeForm from '../../shared/utils/serialize_form.ts'
|
|
import Button from './button.tsx'
|
|
import Checkbox from './checkbox.tsx'
|
|
import Input from './input.tsx'
|
|
import Message from './message.tsx'
|
|
import sutil from './utility.module.scss'
|
|
|
|
const AdmissionForm: FunctionComponent<{
|
|
admission?: ANY
|
|
onCancel?: ANY
|
|
onCreate?: ANY
|
|
onUpdate?: ANY
|
|
roles?: ANY[]
|
|
}> = ({ admission, onCancel, onCreate, onUpdate, roles }) => {
|
|
const [{ error, pending, success }, actions] = useRequestState<FetchError>()
|
|
|
|
const create = useCallback(async (e: TargetedSubmitEvent<HTMLFormElement>) => {
|
|
e.preventDefault()
|
|
|
|
actions.pending()
|
|
|
|
try {
|
|
const form = e.currentTarget
|
|
|
|
const result = await rek[admission ? 'patch' : 'post'](
|
|
`/api/admissions${admission ? '/' + admission.id : ''}`,
|
|
serializeForm(form),
|
|
)
|
|
|
|
actions.success()
|
|
|
|
if (admission) {
|
|
onUpdate?.(result)
|
|
} else {
|
|
form.reset()
|
|
onCreate?.(result)
|
|
}
|
|
} catch (err) {
|
|
actions.error(err as FetchError)
|
|
}
|
|
}, [])
|
|
|
|
return (
|
|
<form onSubmit={create}>
|
|
{success && (
|
|
<Message type='success' dismiss={actions.reset}>
|
|
Admission {admission ? 'updated' : 'created'}!
|
|
</Message>
|
|
)}
|
|
{error && (
|
|
<Message type='error' dismiss={actions.reset}>
|
|
{error.status || 500} {error.body?.message || error.message}
|
|
</Message>
|
|
)}
|
|
|
|
<Input name='regex' label='Regex' type='text' defaultValue={admission?.regex} required />
|
|
{roles && (
|
|
<div>
|
|
{roles.map((role) => (
|
|
<Checkbox
|
|
key={role.id}
|
|
name='roles'
|
|
label={role.name}
|
|
value={role.id}
|
|
defaultChecked={!!admission?.roles.find((r: ANY) => r.id === role.id)}
|
|
/>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
<div className={sutil.row}>
|
|
<Button disabled={pending} type='submit'>
|
|
{admission ? 'Update' : 'Create'}
|
|
</Button>
|
|
{onCancel && (
|
|
<Button disabled={pending} onClick={onCancel} type='button'>
|
|
Cancel
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</form>
|
|
)
|
|
}
|
|
|
|
export default AdmissionForm
|