Files
saladeaula.digital/dashboard_js/app/routes/auth/login/index.jsx
2025-02-22 11:57:18 -03:00

137 lines
3.6 KiB
JavaScript

import { useSearchParams, Link } from 'react-router'
import { useForm } from 'react-hook-form'
import { ErrorMessage } from '@hookform/error-message'
import { isValidCPF } from '@brazilian-utils/brazilian-utils'
import { yupResolver } from '@hookform/resolvers/yup'
import { Card } from '~/layouts/auth/layout'
import { Control, Label, Input, Button, Error } from '~/components/form'
import { Heading } from '~/components/heading'
import { useMutation } from '@tanstack/react-query'
import * as yup from 'yup'
import { encode, parse } from '../_base64state'
import axios from '~/axios'
import Password from './_password'
yup.addMethod(yup.string, 'username', function (message) {
return this.test(
'username',
message,
(x) => isValidCPF(x) || yup.string().email().isValid(x),
)
})
export const schema = yup.object({
username: yup
.string()
.trim()
.lowercase()
.username('Deve ser um Email ou CPF válido')
.transform((x) => (isValidCPF(x) ? x.replace(/\D/g, '') : x))
.required('Digite um Email ou CPF'),
})
export default function Component() {
const [searchParams] = useSearchParams()
const state = parse(searchParams.get('state'))
if (state?.['cognito:sub']) {
return <Password />
}
return <SignIn />
}
function SignIn() {
const [searchParams, setSearchParams] = useSearchParams()
const { handleSubmit, formState, setError, register } = useForm({
resolver: yupResolver(schema),
})
const { mutateAsync } = useMutation({
mutationFn: async ({ username }) => {
const { data } = await axios.get(`/search/lookup/${username}`)
return data
},
onSuccess: (data) => {
setSearchParams((searchParams) => {
searchParams.set('state', encode(data))
return searchParams
})
},
})
const formError = (message) => {
setError('username', {
type: 'manual',
message,
})
}
const onSubmit = async ({ username }) => {
try {
await mutateAsync({ username })
} catch ({ message }) {
switch (message) {
case 'User not found.':
return formError(
'Não encontramos sua conta. Por favor, verifique se seu Email ou CPF estão corretos.',
)
default:
return formError(message)
}
}
}
return (
<Card>
<Heading>Digite o seu email ou cpf para continuar</Heading>
{/* Sign in */}
<form onSubmit={handleSubmit(onSubmit)} className="space-y-2.5">
<Control
className="space-y-0.5"
aria-invalid={'username' in formState.errors}
>
<Label aria-required={true}>Email ou CPF</Label>
<Input
className="w-full"
autoFocus={true}
{...register('username')}
/>
<ErrorMessage
errors={formState.errors}
name="username"
render={({ message }) => <Error>{message}</Error>}
/>
</Control>
<Button
type="submit"
className="w-full"
isLoading={formState.isSubmitting}
>
Continuar
</Button>
</form>
<div className="flex justify-center items-center gap-4">
<span className="flex-1 h-px bg-yellow-secondary dark:bg-gray-700" />
<span>ou</span>
<span className="flex-1 h-px bg-yellow-secondary dark:bg-gray-700" />
</div>
<Button
as={Link}
to={{
pathname: './passcode',
search: searchParams.toString(),
}}
relative="path"
className="flex justify-center items-center !bg-yellow-primary w-full"
>
Entrar com código de acesso
</Button>
</Card>
)
}