update to js
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
export default function Component() {
|
||||
return <>users single</>
|
||||
return <>passcode index</>
|
||||
}
|
||||
173
dashboard_js/app/routes/auth/signin/_password.jsx
Normal file
173
dashboard_js/app/routes/auth/signin/_password.jsx
Normal 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>
|
||||
</>
|
||||
)
|
||||
}
|
||||
104
dashboard_js/app/routes/auth/signin/index.jsx
Normal file
104
dashboard_js/app/routes/auth/signin/index.jsx
Normal 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>
|
||||
)
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
5
dashboard_js/app/routes/auth/support/index.jsx
Normal file
5
dashboard_js/app/routes/auth/support/index.jsx
Normal file
@@ -0,0 +1,5 @@
|
||||
import { Heading } from '../../../components/heading'
|
||||
|
||||
export default function Component() {
|
||||
return <>...</>
|
||||
}
|
||||
7
dashboard_js/app/routes/enrollments/$id.jsx
Normal file
7
dashboard_js/app/routes/enrollments/$id.jsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import { useParams } from 'react-router'
|
||||
|
||||
export default function Component() {
|
||||
const { id } = useParams()
|
||||
|
||||
return <>enrollments single {id}</>
|
||||
}
|
||||
12
dashboard_js/app/routes/home.jsx
Normal file
12
dashboard_js/app/routes/home.jsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Welcome } from "../welcome/welcome";
|
||||
|
||||
export function meta() {
|
||||
return [
|
||||
{ title: "New React Router App" },
|
||||
{ name: "description", content: "Welcome to React Router!" },
|
||||
];
|
||||
}
|
||||
|
||||
export default function Home() {
|
||||
return <Welcome />;
|
||||
}
|
||||
7
dashboard_js/app/routes/orders/$id.jsx
Normal file
7
dashboard_js/app/routes/orders/$id.jsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import { useParams } from 'react-router'
|
||||
|
||||
export default function Component() {
|
||||
const { id } = useParams()
|
||||
|
||||
return <>order single {id}</>
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
export default function Component() {
|
||||
return (
|
||||
<>
|
||||
<title>Pagamentos</title>
|
||||
<p>orders single</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
export default function Component() {
|
||||
return <>enrollments single</>
|
||||
return <>settings index</>
|
||||
}
|
||||
7
dashboard_js/app/routes/users/$id.jsx
Normal file
7
dashboard_js/app/routes/users/$id.jsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import { useParams } from 'react-router'
|
||||
|
||||
export default function Component() {
|
||||
const { id } = useParams()
|
||||
|
||||
return <>user single {id}</>
|
||||
}
|
||||
Reference in New Issue
Block a user