Página de perfil mostra dados do banco de dados do usuário autenticado

This commit is contained in:
Matheus Albino Brunhara
2022-05-16 20:11:15 -05:00
parent f848e20492
commit 453c763f6d
9 changed files with 265 additions and 44 deletions

View File

@@ -29,7 +29,7 @@ import '@ionic/react/css/display.css';
/* Theme variables */
import './theme/variables.css';
// import Tabs from './components/Tabs';
import Perfil from './pages/Perfil';
setupIonicReact();
@@ -41,6 +41,8 @@ const App: React.FC = () => (
<Route exact path="/mainpages" component={MainPages}></Route>
<Route exact path="/cadastro" component={Cadastro}></Route>
<Route exact path="/login" component={Login}></Route>
<Route exact path="/perfil" component={Perfil}></Route>
{/* <Route exact path="/perfil/edit" component={Perfil}></Route> TODO */}
<Route exact path="/">
<Redirect to="/cadastro" />
</Route>

View File

@@ -2,16 +2,22 @@ const tokenId = 'token';
const productDetails = '@productDetails';
const LocalStorage = {
getToken: (): string | null => {
return localStorage.getItem(tokenId)
getToken: (): string => {
const tokenId = localStorage.getItem('tokenId')
if (!tokenId) {
return ''
}
return tokenId
},
setToken: (token: string) => {
localStorage.setItem(tokenId, token)
localStorage.setItem('tokenId', token)
},
clearToken: () => {
localStorage.setItem(tokenId, '');
localStorage.removeItem('tokenId')
}
}

View File

@@ -0,0 +1,11 @@
const usersRoutesDefault = '/users';
const usersRoutes = {
create: {
url: `${usersRoutesDefault}/create`
},
get: {
url: `${usersRoutesDefault}`
}
}
export default usersRoutes;

View File

@@ -7,15 +7,12 @@ import {
} from "@ionic/react";
import React, { useState } from "react";
import { IonGrid, IonRow, IonCol, IonToast } from "@ionic/react";
import { personCircle } from "ionicons/icons";
import { useHistory } from "react-router-dom";
import {
IonItem,
IonLabel,
IonInput,
IonButton,
IonIcon,
IonAlert,
} from "@ionic/react";
import * as sessionRoutes from '../services/session';
@@ -29,11 +26,10 @@ const Page: React.FC = () => {
const history = useHistory();
const [email, setEmail] = useState<string>("matheusalb3213@gmail.com");
const [password, setPassword] = useState<string>("123456");
const [isError, setIsError] = useState<boolean>(false);
const [message, setMessage] = useState<string>("");
function validateEmail(email: string) {
const re =
// eslint-disable-next-line no-control-regex
/^((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))$/;
return re.test(String(email).toLowerCase());
}
@@ -107,15 +103,6 @@ const Page: React.FC = () => {
</IonToolbar>
</IonHeader>
<IonRow>
<IonCol>
<IonIcon
style={{ fontSize: "70px", color: "#0040ff" }}
icon={personCircle}
/>
</IonCol>
</IonRow>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
@@ -124,19 +111,6 @@ const Page: React.FC = () => {
</IonHeader>
<IonGrid>
<IonRow>
<IonCol>
<IonAlert
isOpen={isError}
onDidDismiss={() => setIsError(false)}
cssClass="my-custom-class"
header={"Error!"}
message={message}
buttons={["Dismiss"]}
/>
</IonCol>
</IonRow>
<IonRow>
<IonCol>
<IonItem>
@@ -165,10 +139,6 @@ const Page: React.FC = () => {
<IonRow>
<IonCol>
<p style={{ fontSize: "small" }}>
Clicando no botão de "Login", você concorda com a nossa{" "}
<a href="#">política de termos e serviços</a>
</p>
<IonButton expand="block" onClick={handleLogin}>
Login
</IonButton>

3
src/pages/Perfil.css Normal file
View File

@@ -0,0 +1,3 @@
#avatar {
border-radius: 50%;
}

151
src/pages/Perfil.tsx Normal file
View File

@@ -0,0 +1,151 @@
import {
IonCard,
IonCardContent,
IonCardHeader,
IonCardTitle,
IonContent,
IonFab,
IonFabButton,
IonHeader,
IonIcon,
IonPage,
IonTitle,
IonToast,
IonToolbar,
} from "@ionic/react";
import { useHistory } from "react-router-dom";
import React, { useState, useEffect, useReducer } from "react";
import { IonRow, IonCol } from "@ionic/react";
import { createOutline } from "ionicons/icons";
import * as sessionRoutes from '../services/session';
import * as usersRoutes from '../services/users';
import './Perfil.css'
import LocalStorage from "../LocalStorage";
const Perfil: React.FC = () => {
const [showToast, setShowToast] = useState(false);
const [messageToast, setMessageToast ] = useState('');
const [inputValues, setInputValues] = useReducer(
(state: any, newState: any) => ({ ...state, ...newState }),
{
fullname: '',
bio: ''
}
);
const history = useHistory();
const loadUserData = async () => {
let userId = ''
await sessionRoutes.refresh().then(response => {
if (response.status === 'error') {
setMessageToast(response.message);
setShowToast(true);
return
}
userId = response.userId
}).catch(error => {
console.dir('Houve um erro: ', { error })
alert('Houve um erro')
})
await usersRoutes.getById(userId).then(response => {
if (response.status === 'error') {
setMessageToast(response.message.data)
setShowToast(true);
return
}
const userData = response.data
setInputValues({'fullname': userData.name, 'bio': userData.bio});
}).catch(error => {
console.dir('Houve um erro: ', { error })
alert('Houve um erro')
})
}
useEffect(() => {
const userToken = LocalStorage.getToken()
if (!userToken) {
// TODO, não impede o usuário de retornar a página de login
history.push({ pathname: '/login' });
setMessageToast("Por favor, autentique-se!");
setShowToast(true);
}
// const refreshResponse = refreshSession()
loadUserData()
}, []);
const handleEditProfile = () => {
alert('oi')
}
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Seu perfil</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Seu perfil</IonTitle>
</IonToolbar>
</IonHeader>
<IonCard>
<IonCardContent>
<IonRow>
<IonCol></IonCol>
<IonCol>
<img src="https://static.generated.photos/vue-static/home/feed/adult.png" alt="avatar" className='avatar' id='avatar'/>
</IonCol>
<IonCol></IonCol>
</IonRow>
<IonCardHeader>
<IonCardTitle class="ion-text-center">{inputValues.fullname}</IonCardTitle>
</IonCardHeader>
</IonCardContent>
</IonCard>
<IonCard>
<IonCardHeader>
<IonCardTitle>Biografia</IonCardTitle>
</IonCardHeader>
<IonCardContent>
{inputValues.bio ? inputValues.bio : 'Sem biografia.'}
</IonCardContent>
</IonCard>
<IonFab vertical="bottom" horizontal="end" slot="fixed" onClick={handleEditProfile}>
<IonFabButton>
<IonIcon icon={createOutline} />
</IonFabButton>
</IonFab>
<IonToast
color='danger'
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
message={messageToast}
duration={2500}
/>
</IonContent>
</IonPage>
);
};
export default Perfil;

View File

@@ -0,0 +1,66 @@
import {
IonCard,
IonCardContent,
IonCardHeader,
IonCardTitle,
IonContent,
IonFab,
IonFabButton,
IonGrid,
IonHeader,
IonIcon,
IonInput,
IonItem,
IonLabel,
IonPage,
IonTitle,
IonToolbar
} from "@ionic/react";
import React, { useState } from "react";
import { IonRow, IonCol } from "@ionic/react";
import { createOutline } from "ionicons/icons";
import './Perfil.css'
const Perfil: React.FC = () => {
const [email, setEmail] = useState<string>("matheusalb3213@gmail.com");
const handleEditProfile = () => {
alert('oi')
}
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Editar perfil</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Editar perfil</IonTitle>
</IonToolbar>
</IonHeader>
<IonGrid>
<IonRow>
<IonCol>
<IonItem>
<IonLabel position="floating"> Email</IonLabel>
<IonInput
type="email"
value={email}
onIonChange={(e) => setEmail(e.detail.value!)}
></IonInput>
</IonItem>
</IonCol>
</IonRow>
</IonGrid>
</IonContent>
</IonPage>
);
};
export default Perfil;

View File

@@ -14,8 +14,8 @@ interface createData {
function updateHeader() {
token = LocalStorage.getToken();
header = {
Accept: 'application/json',
'Content-Type': 'application/json',
"Accept": 'application/json',
"Content-Type": 'application/json',
"Authorization": 'Bearer ' + token
}
}

View File

@@ -1,16 +1,21 @@
import instance from '../services/api';
// import LocalStorage from '../LocalStorage';
let token:string;
let header:string;
import userRoutes from '../constants/routes/usersRoutes';
import { AxiosRequestHeaders } from 'axios';
import LocalStorage from '../LocalStorage';
let token: string;
let header: AxiosRequestHeaders;
function updateHeader() {
// token = LocalStorage.getToken();
header = `{
token = LocalStorage.getToken();
header = {
"Accept": 'application/json',
"Content-Type": 'application/json',
"Authorization": 'Bearer ' + token
}`
}
}
export interface CadastroResponse {
@@ -40,6 +45,13 @@ export interface CadastroRequest {
export async function create(CadastroRequest: any) {
updateHeader();
const response = await instance.post("http://localhost:3333/users/", CadastroRequest);
const response = await instance.post(userRoutes.create.url, CadastroRequest);
return response.data;
}
export async function getById(userId: string) {
updateHeader();
const response = await instance.get(userRoutes.get.url + `/${userId}`, { headers: header });
return response.data;
}