Skip to content

Commit 3c2ecbe

Browse files
committed
fix: login page and added session infos and logout
1 parent 3e09b9f commit 3c2ecbe

File tree

12 files changed

+291
-242
lines changed

12 files changed

+291
-242
lines changed

src/App.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
import { BrowserRouter } from "react-router-dom";
1+
import { Fragment } from 'react';
2+
import { BrowserRouter } from 'react-router-dom';
23

3-
import { Routes } from "./routes/Routes";
4-
import { SessionProvider } from "./contexts";
4+
import { Routes } from './routes/Routes';
5+
import { SessionProvider } from './contexts';
6+
import { Toaster } from './components/ui/toaster';
57

68
const App = () => {
79
return (
8-
<BrowserRouter>
9-
<SessionProvider>
10-
<Routes />;
11-
</SessionProvider>
12-
</BrowserRouter>
10+
<Fragment>
11+
<Toaster />
12+
<BrowserRouter>
13+
<SessionProvider>
14+
<Routes />
15+
</SessionProvider>
16+
</BrowserRouter>
17+
</Fragment>
1318
);
1419
};
1520

src/api/api.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,26 @@
1-
import axios from 'axios';
2-
3-
console.log(import.meta.env.VITE_API_URL);
1+
import axios, { AxiosRequestHeaders } from 'axios';
42

53
const api = axios.create({
64
baseURL: import.meta.env.VITE_API_URL ?? 'https://api.sos-rs.com',
75
});
86

7+
api.interceptors.request.use((config) => {
8+
if (!config.headers) config.headers = {} as AxiosRequestHeaders;
9+
const token = localStorage.getItem('token');
10+
if (token) config.headers.Authorization = `Bearer ${token}`;
11+
return config;
12+
});
13+
14+
api.interceptors.response.use(
15+
(config) => {
16+
return config;
17+
},
18+
(error) => {
19+
if (error.response && error.response.status === 401) {
20+
localStorage.removeItem('token');
21+
}
22+
return Promise.reject(error);
23+
}
24+
);
25+
926
export { api };

src/contexts/SessionContext/types.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,4 @@
1-
export interface ISession {
2-
id: string;
3-
userId: string;
4-
ip: string;
5-
userAgent: string;
6-
active: string;
7-
createdAt: string;
8-
updatedAt: string;
9-
}
10-
11-
export enum LoginType {
12-
User = "user",
13-
}
1+
import { ISession } from '@/service/sessions/types';
142

153
export interface ISessionContext {
164
session: ISession | null;

src/pages/CreateShelter/CreateShelter.tsx

Lines changed: 59 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -15,50 +15,61 @@ import { Button } from '@/components/ui/button';
1515
import { ICreateShelter } from '@/service/shelter/types';
1616
import { toast } from '@/components/ui/use-toast';
1717
import { ShelterServices } from '@/service';
18+
import { withAuth } from '@/hocs';
1819

19-
const CreateShelter = () => {
20+
const CreateShelterComponent = () => {
2021
const navigate = useNavigate();
2122

22-
const verifySelected = (selected: string) => {
23-
if (selected === 'sim') return true;
24-
return false;
25-
};
26-
27-
const { errors, getFieldProps, isSubmitting, setFieldValue, handleSubmit } =
28-
useFormik<ICreateShelter>({
29-
initialValues: {
30-
name: '',
31-
address: '',
32-
shelteredPeople: 0,
33-
capacity: 0,
34-
petFriendly: false,
35-
contact: '',
36-
pix: '',
37-
},
38-
enableReinitialize: true,
39-
validateOnBlur: false,
40-
validateOnChange: false,
41-
validateOnMount: false,
42-
validationSchema: Yup.object().shape({
43-
name: Yup.string().required('Este campo deve ser preenchido'),
44-
address: Yup.string().required('Este campo deve ser preenchido'),
45-
}),
46-
onSubmit: async (values) => {
47-
try {
48-
await ShelterServices.create(values);
49-
toast({
50-
title: 'Cadastro feita com sucesso',
51-
});
52-
navigate(`/abrigo/cadastrar`);
53-
} catch (err: any) {
54-
toast({
55-
variant: 'destructive',
56-
title: 'Ocorreu um erro ao tentar cadastrar',
57-
description: `${err?.response?.data?.message ?? err}`,
58-
});
59-
}
60-
},
61-
});
23+
const {
24+
errors,
25+
getFieldProps,
26+
isSubmitting,
27+
setFieldValue,
28+
handleSubmit,
29+
values,
30+
} = useFormik<ICreateShelter>({
31+
initialValues: {
32+
name: '',
33+
address: '',
34+
shelteredPeople: 0,
35+
capacity: 0,
36+
petFriendly: false,
37+
contact: null,
38+
pix: null,
39+
},
40+
enableReinitialize: true,
41+
validateOnBlur: false,
42+
validateOnChange: false,
43+
validateOnMount: false,
44+
validationSchema: Yup.object().shape({
45+
name: Yup.string().required('Este campo deve ser preenchido'),
46+
address: Yup.string().required('Este campo deve ser preenchido'),
47+
shelteredPeople: Yup.number()
48+
.min(0, 'O valor mínimo para este campo é 0')
49+
.nullable(),
50+
capacity: Yup.number()
51+
.min(1, 'O valor mínimo para este campo é 1')
52+
.nullable(),
53+
petFriendly: Yup.bool().nullable(),
54+
contact: Yup.string().nullable(),
55+
pix: Yup.string().nullable(),
56+
}),
57+
onSubmit: async (values, { resetForm }) => {
58+
try {
59+
await ShelterServices.create(values);
60+
toast({
61+
title: 'Cadastro feita com sucesso',
62+
});
63+
resetForm();
64+
} catch (err: any) {
65+
toast({
66+
variant: 'destructive',
67+
title: 'Ocorreu um erro ao tentar cadastrar',
68+
description: `${err?.response?.data?.message ?? err}`,
69+
});
70+
}
71+
},
72+
});
6273

6374
return (
6475
<div className="flex flex-col h-screen items-center">
@@ -69,7 +80,7 @@ const CreateShelter = () => {
6980
<Button
7081
variant="ghost"
7182
className="[&_svg]:stroke-blue-500"
72-
onClick={() => navigate(-1)}
83+
onClick={() => navigate('/')}
7384
>
7485
<ChevronLeft size={20} />
7586
</Button>
@@ -88,21 +99,18 @@ const CreateShelter = () => {
8899
error={!!errors.name}
89100
helperText={errors.name}
90101
/>
91-
92102
<TextField
93103
label="Endereço do abrigo"
94104
{...getFieldProps('address')}
95105
error={!!errors.address}
96106
helperText={errors.address}
97107
/>
98-
99108
<TextField
100109
label="Contato"
101110
{...getFieldProps('contact')}
102111
error={!!errors.contact}
103112
helperText={errors.contact}
104113
/>
105-
106114
<TextField
107115
type="number"
108116
min="0"
@@ -111,7 +119,6 @@ const CreateShelter = () => {
111119
error={!!errors.shelteredPeople}
112120
helperText={errors.shelteredPeople}
113121
/>
114-
115122
<TextField
116123
type="number"
117124
min="0"
@@ -120,24 +127,23 @@ const CreateShelter = () => {
120127
error={!!errors.capacity}
121128
helperText={errors.capacity}
122129
/>
123-
124130
<label className="text-muted-foreground">
125131
O abrigo aceita animais
126132
</label>
127133
<Select
134+
value={values.petFriendly ? 'true' : 'false'}
128135
onValueChange={(v) => {
129-
setFieldValue('petFriendly', verifySelected(v));
136+
setFieldValue('petFriendly', v === 'true');
130137
}}
131138
>
132139
<SelectTrigger className="w-full">
133140
<SelectValue className="text-muted-foreground" />
134141
</SelectTrigger>
135142
<SelectContent>
136-
<SelectItem value="sim">Sim</SelectItem>
137-
<SelectItem value="nao">Não</SelectItem>
143+
<SelectItem value="true">Sim</SelectItem>
144+
<SelectItem value="false">Não</SelectItem>
138145
</SelectContent>
139146
</Select>
140-
141147
<TextField
142148
label="Chave pix"
143149
{...getFieldProps('pix')}
@@ -160,4 +166,6 @@ const CreateShelter = () => {
160166
);
161167
};
162168

169+
const CreateShelter = withAuth(CreateShelterComponent);
170+
163171
export { CreateShelter };

src/pages/Home/Home.tsx

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,28 @@
1-
import { Fragment, useCallback, useMemo, useState } from 'react';
2-
import { RotateCw, CircleAlert, Search, Loader } from 'lucide-react';
1+
import { Fragment, useCallback, useContext, useMemo, useState } from 'react';
2+
import {
3+
RotateCw,
4+
CircleAlert,
5+
Search,
6+
Loader,
7+
LogOutIcon,
8+
} from 'lucide-react';
39

410
import { Alert, Header, NoFoundSearch, ShelterListItem } from '@/components';
511
import { Input } from '@/components/ui/input';
612
import { useShelters, useThrottle } from '@/hooks';
713
import { Button } from '@/components/ui/button';
14+
import { SessionContext } from '@/contexts';
815

916
const alertDescription =
1017
'Você pode consultar a lista de abrigos disponíveis. Ver e editar os itens que necessitam de doações.';
1118

1219
const Home = () => {
1320
const { data: shelters, loading, refresh } = useShelters();
21+
const {
22+
loading: loadingSession,
23+
refreshSession,
24+
session,
25+
} = useContext(SessionContext);
1426
const [searchValue, setSearchValue] = useState<string>('');
1527
const [, setSearch] = useThrottle<string>(
1628
{
@@ -57,15 +69,36 @@ const Home = () => {
5769
<Header
5870
title="SOS Rio Grande do Sul"
5971
endAdornment={
60-
<Button
61-
loading={loading}
62-
variant="ghost"
63-
size="sm"
64-
onClick={() => refresh()}
65-
className="disabled:bg-red-500 hover:bg-red-400"
66-
>
67-
<RotateCw size={20} className="stroke-white" />
68-
</Button>
72+
<div className="flex gap-2 items-center">
73+
{session && (
74+
<h3 className="text-gray-300 font-thin">
75+
Bem vindo, {session.name}
76+
</h3>
77+
)}
78+
<Button
79+
loading={loading}
80+
variant="ghost"
81+
size="sm"
82+
onClick={() => refresh()}
83+
className="disabled:bg-red-500 hover:bg-red-400"
84+
>
85+
<RotateCw size={20} className="stroke-white" />
86+
</Button>
87+
{session && (
88+
<Button
89+
loading={loadingSession}
90+
variant="ghost"
91+
size="sm"
92+
onClick={() => {
93+
localStorage.removeItem('token');
94+
refreshSession();
95+
}}
96+
className="disabled:bg-red-500 hover:bg-red-400"
97+
>
98+
<LogOutIcon size={20} className="stroke-white" />
99+
</Button>
100+
)}
101+
</div>
69102
}
70103
/>
71104
<div className="p-5 gap-3 flex flex-col w-full max-w-5xl">

src/pages/Shelter/Shelter.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const Shelter = () => {
6363
<Button
6464
variant="ghost"
6565
className="font-medium text-[16px] text-blue-600 flex gap-2 items-center hover:text-blue-500 active:text-blue-700"
66-
onClick={() => navigate(`/abrigo/atualizar/${id}`)}
66+
onClick={() => navigate(`/abrigo/${id}/atualizar`)}
6767
>
6868
Editar abrigo
6969
<Pencil size={17} className="stroke-blue-600" />

0 commit comments

Comments
 (0)