update to js

This commit is contained in:
2025-02-21 19:34:56 -03:00
parent 0187f770c7
commit a557ee6e34
44 changed files with 1015 additions and 2463 deletions

View File

@@ -0,0 +1,3 @@
export default function Component() {
return <>passcode index</>
}

View File

@@ -0,0 +1,173 @@
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'
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 formError = (message) => {
setError('password', {
type: 'manual',
message,
})
}
const onSubmit = async ({ password }) => {
const username = searchParams.get('username')
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">
{searchParams.get('username')}
</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>
</>
)
}

View File

@@ -0,0 +1,104 @@
import { useNavigate, 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 Password from './_password'
import * as yup from 'yup'
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()
if (searchParams.get('username')) {
return <Password />
}
return <SignIn />
}
function SignIn() {
const [searchParams, setSearchParams] = useSearchParams()
const { handleSubmit, formState, setError, register } = useForm({
resolver: yupResolver(schema),
})
const onSubmit = async ({ username }) => {
setSearchParams((searchParams) => {
searchParams.set('username', username)
return searchParams
})
}
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>
)
}

View File

@@ -1,42 +0,0 @@
import type { SubmitHandler } from 'react-hook-form'
import type { AuthContextType } from '~/hooks/use-auth'
import { useForm } from 'react-hook-form'
import { useAuth } from '~/hooks/use-auth'
import { Card } from '~/layouts/auth'
import { Control, Label, Input, Button } from '~/components/form'
import { useNavigate } from 'react-router'
type Input = {
username: string
password: string
}
export default function Signin() {
const navigate = useNavigate()
const { register, handleSubmit, formState } = useForm<Input>()
const { signIn } = useAuth()
const onSubmit: SubmitHandler<Input> = async (data) => {
const { nextStep } = await signIn(data)
return navigate('/')
}
return (
<Card>
<form onSubmit={handleSubmit(onSubmit)}>
<Control>
<Label>Email ou CPF</Label>
<Input {...register('username')} />
</Control>
<Control>
<Label>Senha</Label>
<Input type="password" {...register('password')} />
</Control>
<Button type="submit" isLoading={formState.isSubmitting}>
Entrar
</Button>
</form>
</Card>
)
}

View File

@@ -0,0 +1,5 @@
import { Heading } from '../../../components/heading'
export default function Component() {
return <>...</>
}