70 lines
1.8 KiB
TypeScript
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
|