diff --git a/package-lock.json b/package-lock.json index dbcb56f..7300e4a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "@types/react-router-dom": "^5.1.7", "axios": "^0.26.1", "ionicons": "^5.4.0", + "lodash.isequal": "^4.5.0", "react": "^17.0.1", "react-dom": "^17.0.1", "react-hook-form": "^7.30.0", @@ -50,6 +51,7 @@ "devDependencies": { "@capacitor/cli": "3.4.3", "@types/axios": "^0.14.0", + "@types/lodash.isequal": "^4.5.6", "react-scripts": "5.0.1" } }, @@ -3829,6 +3831,21 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "node_modules/@types/lodash": { + "version": "4.14.182", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", + "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==", + "dev": true + }, + "node_modules/@types/lodash.isequal": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@types/lodash.isequal/-/lodash.isequal-4.5.6.tgz", + "integrity": "sha512-Ww4UGSe3DmtvLLJm2F16hDwEQSv7U0Rr8SujLUA2wHI2D2dm8kPu6Et+/y303LfjTIwSBKXB/YTUcAKpem/XEg==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -10665,6 +10682,11 @@ "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -19387,6 +19409,21 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "@types/lodash": { + "version": "4.14.182", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", + "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==", + "dev": true + }, + "@types/lodash.isequal": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@types/lodash.isequal/-/lodash.isequal-4.5.6.tgz", + "integrity": "sha512-Ww4UGSe3DmtvLLJm2F16hDwEQSv7U0Rr8SujLUA2wHI2D2dm8kPu6Et+/y303LfjTIwSBKXB/YTUcAKpem/XEg==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, "@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -24566,6 +24603,11 @@ "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", diff --git a/package.json b/package.json index 39fd73e..39f79ee 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@types/react-router-dom": "^5.1.7", "axios": "^0.26.1", "ionicons": "^5.4.0", + "lodash.isequal": "^4.5.0", "react": "^17.0.1", "react-dom": "^17.0.1", "react-hook-form": "^7.30.0", @@ -69,6 +70,7 @@ "devDependencies": { "@capacitor/cli": "3.4.3", "@types/axios": "^0.14.0", + "@types/lodash.isequal": "^4.5.6", "react-scripts": "5.0.1" }, "description": "An Ionic project" diff --git a/src/App.tsx b/src/App.tsx index ac4cb85..ffa29b8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -30,6 +30,7 @@ import '@ionic/react/css/display.css'; /* Theme variables */ import './theme/variables.css'; import Perfil from './pages/Perfil'; +import PerfilEditar from './pages/PerfilEditar'; setupIonicReact(); @@ -42,7 +43,7 @@ const App: React.FC = () => ( - {/* TODO */} + diff --git a/src/constants/routes/usersRoutes.ts b/src/constants/routes/usersRoutes.ts index b3cf0c1..45c8a7e 100644 --- a/src/constants/routes/usersRoutes.ts +++ b/src/constants/routes/usersRoutes.ts @@ -5,6 +5,9 @@ const usersRoutes = { }, get: { url: `${usersRoutesDefault}` + }, + update: { + url: `${usersRoutesDefault}/edit` } } diff --git a/src/pages/Perfil.tsx b/src/pages/Perfil.tsx index 9a745fc..e242598 100644 --- a/src/pages/Perfil.tsx +++ b/src/pages/Perfil.tsx @@ -31,64 +31,63 @@ const Perfil: React.FC = () => { const [inputValues, setInputValues] = useReducer( (state: any, newState: any) => ({ ...state, ...newState }), { - fullname: '', - bio: '' + name: '', + bio: '', + email: '' } ); 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) { + const redirectUserToLogin = () => { // 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 loadUserData = async () => { + let userId = '' + + await sessionRoutes.refresh().then(response => { + if (response.status === 'error') { + setMessageToast(response.message); + setShowToast(true); + + return + } + + userId = response.userId + }).catch(() => { + redirectUserToLogin() + }) + + await usersRoutes.getById(userId).then(response => { + if (response.status === 'error') { + setMessageToast(response.message.data) + setShowToast(true); + + return + } + + const userData = response.data + + setInputValues({'name': userData.name, 'bio': userData.bio, 'email': userData.email}); + }).catch(() => { + redirectUserToLogin() + }) + } + + const userToken = LocalStorage.getToken() + + if (!userToken) { + redirectUserToLogin() + } // const refreshResponse = refreshSession() loadUserData() - }, []); - - const handleEditProfile = () => { - alert('oi') - } + }, [history]); return ( @@ -116,7 +115,7 @@ const Perfil: React.FC = () => { - {inputValues.fullname} + {inputValues.name} @@ -130,8 +129,8 @@ const Perfil: React.FC = () => { - - + + history.push({ pathname: '/perfil/editar', state: { userData: inputValues } })}> diff --git a/src/pages/PerfilEditar.tsx b/src/pages/PerfilEditar.tsx index 1610169..2ca0cd8 100644 --- a/src/pages/PerfilEditar.tsx +++ b/src/pages/PerfilEditar.tsx @@ -1,8 +1,6 @@ import { - IonCard, - IonCardContent, - IonCardHeader, - IonCardTitle, + IonBackButton, + IonButtons, IonContent, IonFab, IonFabButton, @@ -13,20 +11,77 @@ import { IonItem, IonLabel, IonPage, + IonTextarea, IonTitle, + IonToast, IonToolbar } from "@ionic/react"; -import React, { useState } from "react"; +import React, { useEffect, useReducer, useState } from "react"; import { IonRow, IonCol } from "@ionic/react"; -import { createOutline } from "ionicons/icons"; import './Perfil.css' +import { useHistory, useLocation } from "react-router"; +import { saveOutline } from "ionicons/icons"; -const Perfil: React.FC = () => { - const [email, setEmail] = useState("matheusalb3213@gmail.com"); +import isEqual from 'lodash.isequal'; - const handleEditProfile = () => { - alert('oi') +import * as usersRoutes from '../services/users'; + +interface userData { + name: string; + bio: string; + email: string; +} + +interface LocationState { + userData: userData +} + +const PerfilEditar: React.FC = () => { + const history = useHistory(); + const location = useLocation(); + + const [showToast, setShowToast] = useState(false); + const [messageToast, setMessageToast] = useState(''); + + const [userData, setUserData] = useState({ + name: '', + bio: '', + email: '' + }); + + const [inputValues, setInputValues] = useReducer( + (state: any, newState: any) => ({ ...state, ...newState }), + { + name: '', + bio: '', + email: '' + } + ); + + useEffect(() => { + setUserData(location.state.userData) + setInputValues({'name': userData.name, 'email': userData.email, 'bio': userData.bio}); + }, [userData]); + + const handleUpdateUserData = () => { + usersRoutes.update(inputValues).then(response => { + if (response.status === 'error') { + setMessageToast(response.message); + setShowToast(true); + + return + } + + console.log(response) + }).catch((err) => { + setMessageToast(err); + setShowToast(true); + }) + } + + const hasChangedSinceInitialState = () => { + return isEqual(userData, inputValues) } return ( @@ -34,6 +89,9 @@ const Perfil: React.FC = () => { Editar perfil + + + @@ -48,19 +106,48 @@ const Perfil: React.FC = () => { - Email + Nome completo + setInputValues({'name': e.detail.value!})} + > + + + Email setEmail(e.detail.value!)} + value={inputValues.email} + onIonChange={(e) => setInputValues({'email': e.detail.value!})} > + + Biografia + setInputValues({'bio': e.detail.value!})} + > + + + + + + + + + setShowToast(false)} + message={messageToast} + duration={2500} + /> ); }; -export default Perfil; +export default PerfilEditar; diff --git a/src/services/users.ts b/src/services/users.ts index a8c47e6..29c6e7b 100644 --- a/src/services/users.ts +++ b/src/services/users.ts @@ -29,10 +29,16 @@ export interface CadastroResponse { } export interface CadastroRequest { - name: string; - email: string; - birth_date: string; - password: string; + name: string; + email: string; + birth_date: string; + password: string; +} + +export interface UpdateUserRequest { + name: string; + email: string; + bio: string; } // export async function get(cpf) { @@ -54,4 +60,11 @@ export async function getById(userId: string) { const response = await instance.get(userRoutes.get.url + `/${userId}`, { headers: header }); return response.data; +} + +export async function update(userData: UpdateUserRequest) { + updateHeader(); + + const response = await instance.patch(userRoutes.update.url, userData, { headers: header }); + return response.data; } \ No newline at end of file