brf/client/admin/components/login_form.tsx
2025-12-18 07:31:37 +01:00

70 lines
1.8 KiB
TypeScript

import { h, type FunctionComponent, type TargetedSubmitEvent } from 'preact'
import type { FetchError } from 'rek'
import { useCallback } from 'preact/hooks'
import { useCurrentUser } from '../contexts/current_user.ts'
import rek from 'rek'
import useRequestState from '../../shared/hooks/use_request_state.ts'
import Button from './button.tsx'
import Input from './input.tsx'
import Message from './message.tsx'
import s from './login_form.module.scss'
const LoginForm: FunctionComponent = () => {
const [{ error, pending }, actions] = useRequestState<FetchError>()
const { setUser } = useCurrentUser()
const login = useCallback(async (e: TargetedSubmitEvent<HTMLFormElement>) => {
e.preventDefault()
actions.pending()
const form = e.currentTarget
try {
const result = await rek.post('/auth/login', {
email: form.email.value,
password: form.password.value,
})
actions.success()
setUser(result)
} catch (err) {
actions.error(err as FetchError)
}
}, [])
return (
<form onSubmit={login}>
{error && <Message type='error'>Error: {error.body?.message || error.message}</Message>}
<Input name='email' label='Email' placeholder='Email' type='email' autoFocus required />
<Input
type='password'
label='Password'
name='password'
placeholder='Password'
autoComplete='current-password'
required
/>
<div className={s.footer}>
<ul className={s.links}>
<li>
<a href='/admin/forgot-password'>Forgot your password?</a>
</li>
<li>
<a href='/admin/register'>No account? Register a new</a>
</li>
</ul>
<Button type='submit' disabled={pending}>
Login
</Button>
</div>
</form>
)
}
export default LoginForm