From 9bc701d8440beeeca196dc919f35fb3378b6e844 Mon Sep 17 00:00:00 2001 From: Matheusafonsouza Date: Sun, 8 Dec 2024 18:23:26 -0300 Subject: [PATCH] feat: login page Co-authored-by: Bruno Cruz --- src/App.tsx | 2 + src/PrivateRoute.tsx | 2 +- src/hooks/useApi/index.tsx | 14 +++++ src/hooks/useAuth.tsx | 30 ++++++++- src/pages/SignIn/SignInForm/index.tsx | 82 +++++++++++++++++++++++++ src/pages/SignIn/SignInHeader/index.tsx | 12 ++++ src/pages/SignIn/SignUpButton/index.tsx | 20 ++++++ src/pages/SignIn/index.tsx | 20 ++++++ 8 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 src/pages/SignIn/SignInForm/index.tsx create mode 100644 src/pages/SignIn/SignInHeader/index.tsx create mode 100644 src/pages/SignIn/SignUpButton/index.tsx create mode 100644 src/pages/SignIn/index.tsx diff --git a/src/App.tsx b/src/App.tsx index 0314c5b..6edfc25 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,6 +11,7 @@ import Warnings from "./pages/Warnings" import Loans from "./pages/Loans" import { Toaster } from "./components/ui/toaster" import PrivateRoute from './PrivateRoute'; +import SignIn from "./pages/SignIn" function App() { return ( @@ -19,6 +20,7 @@ function App() { } /> + } /> } /> } /> } /> diff --git a/src/PrivateRoute.tsx b/src/PrivateRoute.tsx index 02c55af..caf38f0 100644 --- a/src/PrivateRoute.tsx +++ b/src/PrivateRoute.tsx @@ -8,7 +8,7 @@ const PrivateRoute = ({ children }: { children: any }) => { useEffect(() => { if (token) return; - navigate('/cadastro'); + navigate('/login'); }) return children; diff --git a/src/hooks/useApi/index.tsx b/src/hooks/useApi/index.tsx index 16e343f..15a2712 100644 --- a/src/hooks/useApi/index.tsx +++ b/src/hooks/useApi/index.tsx @@ -57,6 +57,20 @@ const useApi = () => { .catch((err) => resolve(getDefaultErrorUseAPIMessage(err))); }); }, + signIn: (data: { + email: string; + password: string + }): Promise<{ data: { + accessToken: string; + refreshToken: string; + } }> => { + return new Promise((resolve) => { + api + .post('/auth/signin', data) + .then((res) => resolve(res)) + .catch((err) => resolve(getDefaultErrorUseAPIMessage(err))); + }); + }, editProfile: async (id: string, data: { firstName: string; lastName: string; diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx index afec0e3..e2628c7 100644 --- a/src/hooks/useAuth.tsx +++ b/src/hooks/useAuth.tsx @@ -13,6 +13,11 @@ interface SignUpParams { password: string; } +interface SignInParams { + email: string; + password: string; +} + interface EditProfileParams { firstName: string; lastName: string; @@ -27,13 +32,18 @@ type AuthContextType = { token: string | null; signOut: () => void; signUp: (userToSignUp: SignUpParams) => Promise; + signIn: (userToSignIn: SignInParams) => Promise; editProfile: (id: string, profileToEdit: EditProfileParams) => Promise; }; const AuthContext = createContext({} as AuthContextType); export const AuthProvider = ({ children }: { children: ReactNode }) => { - const { signUp: authSignUp, editProfile: authEditProfile } = useApi(); + const { + signUp: authSignUp, + signIn: authSignIn, + editProfile: authEditProfile, + } = useApi(); const localToken = typeof window !== 'undefined' @@ -60,6 +70,23 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => { return true; } + async function signIn(userToSignIn: SignInParams): Promise { + const { data } = await authSignIn(userToSignIn); + if (!data.accessToken) { + toaster.create({ + title: 'Erro ao realizar login', + description: 'Verifique os campos e tente novamente.', + type: 'error', + }) + return false; + }; + setToken(data.accessToken); + if (typeof window !== 'undefined') { + localStorage.setItem('@livrolivre:token', data.accessToken); + } + return true; + } + async function editProfile(id: string, profileToEdit: EditProfileParams): Promise { const { data } = await authEditProfile(id, profileToEdit); if (data.id) { @@ -92,6 +119,7 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => { signOut, signUp, editProfile, + signIn, }} > {children} diff --git a/src/pages/SignIn/SignInForm/index.tsx b/src/pages/SignIn/SignInForm/index.tsx new file mode 100644 index 0000000..a5e1571 --- /dev/null +++ b/src/pages/SignIn/SignInForm/index.tsx @@ -0,0 +1,82 @@ +import { useEffect, useState } from 'react'; +import { useAuth } from '../../../hooks/useAuth'; +import { useNavigate } from 'react-router'; +import { Input, Stack } from '@chakra-ui/react'; +import { useForm } from 'react-hook-form'; +import { PasswordInput } from '../../../components/ui/password-input'; +import { Button } from '../../../components/ui/button'; +import { Field } from '../../../components/ui/field'; + +interface FormValues { + email: string; + password: string; +} + +function SignInForm() { + const [loading, setLoading] = useState(false); + const navigate = useNavigate(); + + const { + register, + handleSubmit, + formState: { errors, isValid }, + } = useForm(); + + const { signIn, token } = useAuth(); + + const onSubmit = handleSubmit(async (data: FormValues) => { + setLoading(true); + await signIn({ + email: data.email, + password: data.password, + }); + setLoading(false); + }) + + useEffect(() => { + if (!token) return; + navigate('/inicio'); + }, [token]) + + return ( +
+ + + + + + + + + + + +
+ ); +} + +export default SignInForm diff --git a/src/pages/SignIn/SignInHeader/index.tsx b/src/pages/SignIn/SignInHeader/index.tsx new file mode 100644 index 0000000..4a46674 --- /dev/null +++ b/src/pages/SignIn/SignInHeader/index.tsx @@ -0,0 +1,12 @@ +import { Stack, Text } from '@chakra-ui/react'; + +function SignUpHeader() { + return ( + + Bem vindo ao Livro Livre + Insira seus dados para fazer o login e começar a ajudar utilizar o Livro Livre + + ); +} + +export default SignUpHeader diff --git a/src/pages/SignIn/SignUpButton/index.tsx b/src/pages/SignIn/SignUpButton/index.tsx new file mode 100644 index 0000000..12c94ea --- /dev/null +++ b/src/pages/SignIn/SignUpButton/index.tsx @@ -0,0 +1,20 @@ +import { Link } from 'react-router'; +import { Center, Link as ChakraLink, Separator, Stack, Text } from '@chakra-ui/react'; + +function SignUpButton() { + return ( +
+ + + + Não possuí uma conta? Faça seu cadastro aqui + + +
+ ); +} + +export default SignUpButton diff --git a/src/pages/SignIn/index.tsx b/src/pages/SignIn/index.tsx new file mode 100644 index 0000000..42de716 --- /dev/null +++ b/src/pages/SignIn/index.tsx @@ -0,0 +1,20 @@ +import { Box, Center, Stack } from '@chakra-ui/react'; +import SignInForm from './SignInForm'; +import SignUpButton from './SignUpButton'; +import SignInHeader from './SignInHeader'; + +function SignIn() { + return ( + +
+ + + + + +
+
+ ); +} + +export default SignIn