Skip to content

Commit

Permalink
Merge pull request #40 from fga-eps-mds/128-realizar-login
Browse files Browse the repository at this point in the history
128 - criação da tela de realizar login
  • Loading branch information
suzaneduarte authored Jun 14, 2023
2 parents 3d81b2e + 536fe03 commit c620b5a
Show file tree
Hide file tree
Showing 8 changed files with 312 additions and 141 deletions.
13 changes: 8 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { theme } from '@/styles/theme';

import '@/styles/react-datepicker.scss';
import { Router } from '@/config/routes/Routes';
import { AuthProvider } from './contexts/AuthContext';

const { ToastContainer } = createStandaloneToast();

Expand All @@ -24,11 +25,13 @@ export function App() {
return (
<BrowserRouter>
<ChakraProvider resetCSS theme={theme}>
<QueryClientProvider client={queryClient}>
<Router />
<ToastContainer />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
<AuthProvider>
<QueryClientProvider client={queryClient}>
<Router />
<ToastContainer />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</AuthProvider>
</ChakraProvider>
</BrowserRouter>
);
Expand Down
34 changes: 22 additions & 12 deletions src/components/side-bar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import React, { memo } from 'react';
import { Box, Text } from '@chakra-ui/react';
import { Box, Button, Text } from '@chakra-ui/react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '@/contexts/AuthContext';

export const SideBar = memo(() => {
// Mocked
// TODO: create an AuthContext and get it using useAuth

// Mocked
// TODO: get function from authContext

const { signOut, user } = useAuth();
const navigate = useNavigate();

const options = [
Expand All @@ -30,6 +26,9 @@ export const SideBar = memo(() => {
color="#fff"
padding="20px"
height="100%"
display="flex"
flexDirection="column"
gap="40px"
>
<Text fontSize="2.8vw" fontWeight="bold">
Alectrion
Expand All @@ -39,18 +38,29 @@ export const SideBar = memo(() => {
key={option.name}
fontSize="4xs"
fontWeight="bold"
marginTop="10"
_hover={{ cursor: 'pointer', color: 'orange.500' }}
onClick={() => navigate(option.link)}
>
{option.name}
</Text>
))}
<Box position="absolute" bottom="20px" fontSize="4xs">
<Box
display="flex"
flexDirection="column"
marginTop="auto"
gap="10px"
fontSize="4xs"
>
<Text fontWeight="bold">Cadastro Usuário</Text>
<Text fontWeight="bold" marginTop="2">
Admin
</Text>
<Text fontWeight="bold">{user?.name}</Text>
<Button
onClick={signOut}
variant="link"
textColor="white"
justifyContent="unset"
>
Sair
</Button>
</Box>
</Box>
);
Expand Down
57 changes: 33 additions & 24 deletions src/config/routes/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,50 @@
*/
import { Routes, Route } from 'react-router-dom';
import { Login } from '@/pages/login';


import { MovementsTable } from '@/pages/movements/MovementControl';
import { EquipmentTable } from '@/pages/equipments/EquipmentsControl';
import { OrderServiceTable } from '@/pages/order-service/OrderServiceControl';
import { RequireAuth } from './require-auth';

export function Router() {
return (
<Routes>
{/* ROTAS PRIVADAS */}
<Route path="/" element={<EquipmentTable />}>
{/* <Route
index
element={
<RequireAuth>
<Chamados />
</RequireAuth>
}
/>
<Route
path="chamados"
element={
<RequireAuth>
<Chamados />
</RequireAuth>
}
/> */}
</Route>
<Route
path="/"
element={
<RequireAuth>
<EquipmentTable />
</RequireAuth>
}
/>

{/* ROTAS PUBLICAS */}
<Route path="/login" element={<Login />} />
<Route path="/equipaments" element={<EquipmentTable />} />
<Route path="/movements" element={<MovementsTable />} />
<Route path="/equipments" element={<EquipmentTable />} />
<Route path="/order-services" element={<OrderServiceTable />} />
<Route
path="/movements"
element={
<RequireAuth>
<MovementsTable />
</RequireAuth>
}
/>
<Route
path="/equipments"
element={
<RequireAuth>
<EquipmentTable />
</RequireAuth>
}
/>
<Route
path="/order-services"
element={
<RequireAuth>
<OrderServiceTable />
</RequireAuth>
}
/>
<Route path="*" element={<p>404</p>} />
</Routes>
);
Expand Down
5 changes: 2 additions & 3 deletions src/config/routes/require-auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@
*/
import { ReactElement } from 'react';
import { Navigate, useLocation } from 'react-router-dom';
// import { useAuth } from '@/contexts/AuthContext';
import { useAuth } from '@/contexts/AuthContext';

export function RequireAuth({ children }: { children: ReactElement }) {
// TODO: create an AuthContext and get it using useAuth
const isAuthenticated = true;
const { isAuthenticated } = useAuth();
const location = useLocation();

if (!isAuthenticated) {
Expand Down
104 changes: 104 additions & 0 deletions src/contexts/AuthContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import {
createContext,
ReactNode,
useCallback,
useContext,
useMemo,
useState,
} from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { toast } from '@/utils/toast';
import { api } from '@/config/lib/axios';
import { SignedUser, SignInCredentials, AuthResponse } from '@/types/auth';

interface AuthContextData {
signOut(): void;
signIn(credentials: SignInCredentials): Promise<void>;
isAuthenticated: boolean;
user: SignedUser | null;
}

const AuthContext = createContext({} as AuthContextData);

interface AuthProviderProps {
children: ReactNode;
}

export function AuthProvider({ children }: AuthProviderProps) {
const navigate = useNavigate();
const location = useLocation();
const [user, setUser] = useState<SignedUser | null>(() => {
const loadedUser = localStorage.getItem('@alectrion:user');

if (!loadedUser) return {} as SignedUser;

return JSON.parse(loadedUser);
});
const isAuthenticated = !!user?.token;

const signIn = useCallback(
async ({ username, password }: SignInCredentials) => {
try {
const response = await api.post('user/login', {
username,
password,
});

const { email, expireIn, job, name, role, token } = response.data;

localStorage.setItem('@alectrion:token', token);
localStorage.setItem(
'@alectrion:user',
JSON.stringify({
name,
email,
expireIn,
token,
job,
role,
})
);

setUser({ email, expireIn, job, name, role, token });

api.defaults.headers.common.Authorization = `Bearer ${token}`;

const from = location.state?.from?.pathname || '/';

navigate(from, { replace: true });
} catch (err) {
toast.error(
'Não foi possível realizar o login! Verifique o nome de usuário e a senha e tente novamente.'
);
}
},
[navigate, location.state?.from?.pathname]
);

const signOut = useCallback(() => {
localStorage.removeItem('@alectrion:token');
localStorage.removeItem('@alectrion:user');

setUser(null);

navigate('/login');
}, [navigate]);

const value = useMemo(
() => ({
signIn,
signOut,
isAuthenticated,
user,
}),
[signIn, signOut, isAuthenticated, user]
);

return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

export function useAuth(): AuthContextData {
const context = useContext(AuthContext);

return context;
}
21 changes: 21 additions & 0 deletions src/pages/login/AlectrionIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Icon, IconProps } from '@chakra-ui/react';

export function AlectrionIcon(props: IconProps) {
return (
<Icon
width="672"
height="654"
viewBox="0 0 672 654"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M328.57 4.34284C331.546 -1.44761 339.824 -1.44761 342.8 4.34283L670.474 641.843C673.21 647.167 669.345 653.5 663.359 653.5H8.01059C2.02454 653.5 -1.84099 647.167 0.895506 641.843L328.57 4.34284ZM331.45 180.727C333.403 176.764 338.199 175.135 342.162 177.088L342.653 177.33C344.721 177.591 346.657 178.654 347.981 180.364C349.184 181.512 349.983 182.997 350.301 184.59L491.304 459.723C493.258 463.535 491.857 468.183 488.186 470.299C486.733 472.301 484.374 473.605 481.707 473.605L307.685 473.605L341.857 454.367C343.055 453.693 344.406 453.339 345.781 453.339H465.257L340.074 209.075L159.901 574.631C157.948 578.594 153.152 580.223 149.189 578.27L145.36 576.383C141.397 574.43 139.768 569.633 141.721 565.67L331.45 180.727ZM341.185 375.5C351.678 375.5 360.185 366.994 360.185 356.5C360.185 346.007 351.678 337.5 341.185 337.5C330.691 337.5 322.185 346.007 322.185 356.5C322.185 366.994 330.691 375.5 341.185 375.5Z"
fill="#F49320"
/>
</Icon>
);
}
Loading

0 comments on commit c620b5a

Please sign in to comment.