174 lines
5.0 KiB
JavaScript
174 lines
5.0 KiB
JavaScript
import {
|
|
Button,
|
|
Control,
|
|
Input,
|
|
Checkbox,
|
|
Label,
|
|
Error,
|
|
} from '~/components/form'
|
|
import { useForm } from 'react-hook-form'
|
|
import { ErrorMessage } from '@hookform/error-message'
|
|
import { yupResolver } from '@hookform/resolvers/yup'
|
|
import { Link as RouterLink, useNavigate, useSearchParams } from 'react-router'
|
|
import { useAuth } from '~/hooks/use-auth'
|
|
import { useToggle } from '@uidotdev/usehooks'
|
|
import { Heading } from '~/components/heading'
|
|
import { Link } from '~/layouts/auth/_link'
|
|
import { Card } from '~/layouts/auth/layout'
|
|
import * as yup from 'yup'
|
|
import { parse } from '../_base64state'
|
|
|
|
const schema = yup.object({
|
|
password: yup
|
|
.string()
|
|
.trim()
|
|
.min(6, 'A senha deve ter pelo menos 6 caracteres')
|
|
.required('Você deve digitar uma senha'),
|
|
})
|
|
|
|
export default function Password() {
|
|
const navigate = useNavigate()
|
|
const [searchParams] = useSearchParams()
|
|
const [on, toggle] = useToggle()
|
|
const { signIn } = useAuth()
|
|
const { register, formState, setError, handleSubmit } = useForm({
|
|
resolver: yupResolver(schema),
|
|
})
|
|
const state = parse(searchParams.get('state'))
|
|
|
|
const formError = (message) => {
|
|
setError('password', {
|
|
type: 'manual',
|
|
message,
|
|
})
|
|
}
|
|
|
|
const onSubmit = async ({ password }) => {
|
|
const username = state?.email
|
|
const redirectTo = searchParams.get('redirect') ?? '/'
|
|
|
|
try {
|
|
const { nextStep } = await signIn({ username, password })
|
|
|
|
if (nextStep.signInStep === 'CONFIRM_SIGN_UP') {
|
|
return navigate({
|
|
pathname: '../signup/confirm',
|
|
search: searchParams.toString(),
|
|
})
|
|
}
|
|
|
|
// User is required to set a new password after temporary password login
|
|
if (
|
|
nextStep.signInStep === 'CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED'
|
|
) {
|
|
return navigate({
|
|
pathname: '../reset',
|
|
search: searchParams.toString(),
|
|
})
|
|
}
|
|
|
|
// User needs to reset their password due to a forgot password request
|
|
if (nextStep.signInStep === 'RESET_PASSWORD') {
|
|
return navigate({
|
|
pathname: '../forgot',
|
|
search: searchParams.toString(),
|
|
})
|
|
}
|
|
|
|
return navigate(redirectTo)
|
|
} catch (err) {
|
|
const { message } = err
|
|
|
|
switch (message) {
|
|
case 'Incorrect username or password.':
|
|
return formError(
|
|
'A senha está incorreta, tente novamente. Tente redefinir a senha clicando em "Esqueceu sua senha".',
|
|
)
|
|
case 'Password attempts exceeded':
|
|
return formError(
|
|
'Tentativas excedidas. Espere alguns minutos para tentar novamente.',
|
|
)
|
|
case 'Temporary password has expired and must be reset by an administrator.':
|
|
return formError(
|
|
'A senha temporária expirou. Entre em contato conosco para pedir uma nova.',
|
|
)
|
|
case 'User does not exist.':
|
|
return navigate({
|
|
pathname: '../signup',
|
|
search: searchParams.toString(),
|
|
})
|
|
case 'There is already a signed in user.':
|
|
// If the user is already signed in, redirect them.
|
|
return navigate(redirectTo)
|
|
default:
|
|
return formError(message)
|
|
}
|
|
}
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Card>
|
|
<div className="space-y-1.5">
|
|
<Heading as="h2" size="lg">
|
|
Digite sua senha
|
|
</Heading>
|
|
|
|
<p className="break-all">
|
|
Entre na sua conta usando o email{' '}
|
|
<span className="font-semibold">{state?.email}</span>{' '}
|
|
<Link to="." as={RouterLink}>
|
|
(editar)
|
|
</Link>
|
|
</p>
|
|
</div>
|
|
|
|
<form onSubmit={handleSubmit(onSubmit)} className="space-y-2.5">
|
|
<div className="space-y-1">
|
|
<Control
|
|
className="space-y-0.5"
|
|
aria-invalid={'password' in formState.errors}
|
|
>
|
|
<Label aria-required={true}>Senha</Label>
|
|
<Input
|
|
type={on ? 'text' : 'password'}
|
|
className="w-full"
|
|
autoComplete="off"
|
|
autoFocus={true}
|
|
{...register('password')}
|
|
/>
|
|
<ErrorMessage
|
|
errors={formState.errors}
|
|
name="password"
|
|
render={({ message }) => <Error>{message}</Error>}
|
|
/>
|
|
</Control>
|
|
|
|
<Control className="flex items-center gap-1.5">
|
|
<Checkbox onChange={toggle} />
|
|
<Label>Mostrar senha</Label>
|
|
</Control>
|
|
</div>
|
|
|
|
<Button
|
|
type="submit"
|
|
className="w-full"
|
|
isLoading={formState.isSubmitting}
|
|
>
|
|
Entrar
|
|
</Button>
|
|
</form>
|
|
</Card>
|
|
|
|
<div className="text-center">
|
|
<Link
|
|
to={{ pathname: '../forgot', search: searchParams.toString() }}
|
|
as={RouterLink}
|
|
>
|
|
Esqueceu sua senha?
|
|
</Link>
|
|
</div>
|
|
</>
|
|
)
|
|
}
|