From fb9b5f4d000157d2080afc43ac637ee310540dce Mon Sep 17 00:00:00 2001 From: Matheus Albino Brunhara Date: Tue, 7 Jun 2022 19:20:18 -0500 Subject: [PATCH 1/9] =?UTF-8?q?Incluindo=20exibi=C3=A7=C3=A3o=20de=20infor?= =?UTF-8?q?ma=C3=A7=C3=B5es=20de=20contato=20no=20perfil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/routes/usersRoutes.ts | 3 + src/pages/Cadastro/Cadastro.tsx | 11 ++- src/pages/CadastroCompletar.tsx | 5 +- src/pages/Home.tsx | 34 ++++++++- src/pages/Perfil.tsx | 96 +++++++++++++++++++++++++- src/services/api/users.ts | 8 +++ src/services/functions/usersService.ts | 38 +++++++++- 7 files changed, 184 insertions(+), 11 deletions(-) diff --git a/src/constants/routes/usersRoutes.ts b/src/constants/routes/usersRoutes.ts index 4ebe2d0..18216e9 100644 --- a/src/constants/routes/usersRoutes.ts +++ b/src/constants/routes/usersRoutes.ts @@ -8,6 +8,9 @@ const usersRoutes = { }, update: { url: `${usersRoutesDefault}/edit` + }, + getSocialInfo: { + url: `${usersRoutesDefault}/social` } } diff --git a/src/pages/Cadastro/Cadastro.tsx b/src/pages/Cadastro/Cadastro.tsx index 184691a..debc61a 100644 --- a/src/pages/Cadastro/Cadastro.tsx +++ b/src/pages/Cadastro/Cadastro.tsx @@ -1,14 +1,18 @@ import { IonToast, IonProgressBar, IonItem, IonLabel, IonInput, IonBackButton, IonButton, IonButtons, IonCardTitle, IonCol, IonContent, IonGrid, IonHeader, IonPage, IonRow, IonToolbar } from '@ionic/react'; import { arrowBack, logoFacebook, mail } from 'ionicons/icons'; import { Action } from '../../components/Action'; -import { useEffect, useState } from 'react'; +import { useContext, useEffect, useState } from 'react'; import { useHistory, useParams } from 'react-router'; import './Cadastro.css'; import ModalExample from '../../components/Email'; import * as UsersService from '../../services/api/users' +import LocalStorage from '../../LocalStorage'; +import { UserContext } from '../../App'; const Cadastro: React.FC = () => { const history = useHistory(); + + const user = useContext(UserContext); const [showToast, setShowToast] = useState(false); const [messageToast, setMessageToast ] = useState(''); @@ -87,6 +91,11 @@ const Cadastro: React.FC = () => { // if(signIn.token) { // await AsyncStorage.setItem('token', signIn.token); // await AsyncStorage.setItem('cpf', retorno.cpf); + + LocalStorage.setToken(retorno.token.token); + + user.setIsLoggedIn(true); + history.push('home'); } else { diff --git a/src/pages/CadastroCompletar.tsx b/src/pages/CadastroCompletar.tsx index f1b6654..c068491 100644 --- a/src/pages/CadastroCompletar.tsx +++ b/src/pages/CadastroCompletar.tsx @@ -1,6 +1,5 @@ import { IonBackButton, -IonButton, IonButtons, IonCard, IonCardContent, @@ -17,9 +16,7 @@ import React, { useEffect, useReducer, useState } from "react"; import './Perfil.css' import { useHistory, useLocation } from "react-router"; -import { bookOutline, callOutline, documentTextOutline, homeOutline, logoWhatsapp } from "ionicons/icons"; - -import isEqual from 'lodash.isequal'; +import { bookOutline, callOutline, documentTextOutline, homeOutline } from "ionicons/icons"; import * as usersRoutes from '../services/api/users'; diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 1134d4d..b8b835c 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -1,9 +1,39 @@ -import { IonItem, IonLabel, IonInput, IonButton, IonCardTitle, IonCol, IonContent, IonGrid, IonPage, IonRow } from '@ionic/react'; +import { IonButton, IonContent, IonPage } from '@ionic/react'; +import { useContext, useEffect } from 'react'; import { useHistory } from 'react-router'; -import { Action } from '../components/Action'; + +import { UserContext } from '../App'; + +import * as sessionRoutes from '../services/api/session'; const Home: React.FC = () => { const history = useHistory() + + const user = useContext(UserContext); + + useEffect(() => { + const refreshUserToken = async () => { + await sessionRoutes.refresh().then(response => { + if (response.status === 'error') { + // setMessageToast(response.message); + // setShowToast(true); + + return + } + + user.setIsLoggedIn(true); + }).catch(error => { + // if (!error.response) return + + // se o backend retornou uma mensagem de erro customizada + // if (error.response.data.message) { + console.dir('Houve um erro: ', { error }) + alert('Houve um erro') + }) + } + + refreshUserToken() + }) return ( diff --git a/src/pages/Perfil.tsx b/src/pages/Perfil.tsx index f01d39e..ea2dcfd 100644 --- a/src/pages/Perfil.tsx +++ b/src/pages/Perfil.tsx @@ -1,4 +1,6 @@ import { + IonBackButton, + IonButtons, IonCard, IonCardContent, IonCardHeader, @@ -18,7 +20,7 @@ import { } from "@ionic/react"; import { useHistory } from "react-router-dom"; import React, { useState, useEffect, useReducer, useContext } from "react"; -import { cardOutline, carOutline, createOutline, exitOutline, shieldCheckmarkOutline, starOutline } from "ionicons/icons"; +import { callOutline, cardOutline, carOutline, createOutline, exitOutline, logoFacebook, logoWhatsapp, shieldCheckmarkOutline, starOutline } from "ionicons/icons"; import './Perfil.css' import LocalStorage from "../LocalStorage"; @@ -54,6 +56,16 @@ const Perfil: React.FC = (props) => { } ); + const [inputSocialInformationValues, setInputSocialInformationValues] = useReducer( + (state: any, newState: any) => ({ ...state, ...newState }), + { + phone: '', + whatsapp: '', + facebook: '', + telegram: '', + } + ); + const history = useHistory(); const redirectUserToLogin = () => { @@ -122,6 +134,34 @@ const Perfil: React.FC = (props) => { } } } + // get user social info + const getUserSocialInfoRes = await usersService.getUserSocialInfo(userId) + + if (getUserSocialInfoRes.error) { + if (isVisitor && props.match.params.id) { + setMessageToast('Usuário não existe!') + setShowToast(true) + history.push({ pathname: '/home' }) + } else { + setMessageToast(getUserSocialInfoRes.error.errorMessage) + setShowToast(true) + } + + return + } + + if (getUserSocialInfoRes.data) { + const userSocialData = getUserSocialInfoRes.data + + if (isMounted) { + setInputSocialInformationValues({ + 'phone': userSocialData.phone, + 'whatsapp': userSocialData.whatsapp, + 'facebook': userSocialData.facebook, + 'telegram': userSocialData.telegram, + }); + } + } } let isMounted = true; @@ -142,6 +182,9 @@ const Perfil: React.FC = (props) => { Seu perfil + + + @@ -174,11 +217,58 @@ const Perfil: React.FC = (props) => { Biografia - {inputValues.bio ? inputValues.bio : 'Sem biografia.' } + {inputValues.bio ? inputValues.bio : 'Sem biografia.' } - {/* // TODO, card de informações de contato */} + + + Informações de contato + + + { !inputSocialInformationValues.phone && !inputSocialInformationValues.whatsapp && !inputSocialInformationValues.facebook && !inputSocialInformationValues.telegram ? + <>Sem informações de contato. + : <> + { + inputSocialInformationValues.phone ? + <> + + + {inputSocialInformationValues.phone} + + : <> + } + + { inputSocialInformationValues.whatsapp ? + <> + + + {inputSocialInformationValues.whatsapp} + + : <> + } + + { inputSocialInformationValues.facebook ? + <> + + + {inputSocialInformationValues.facebook} + + : <> + } + + { inputSocialInformationValues.telegram ? + <> + + + {inputSocialInformationValues.telegram} + + : <> + } + + } + + { !isVisitor ? diff --git a/src/services/api/users.ts b/src/services/api/users.ts index 424190a..fd6cd27 100644 --- a/src/services/api/users.ts +++ b/src/services/api/users.ts @@ -68,4 +68,12 @@ export async function update(userData: UpdateUserRequest) { const response = await instance.patch(userRoutes.update.url, userData, { headers: header }); return response.data; +} + +// TODO, continuar +export async function getSocialInfo(userId: string) { + updateHeader(); + + const response = await instance.get(userRoutes.getSocialInfo.url + `/${userId}`, { headers: header }); + return response.data; } \ No newline at end of file diff --git a/src/services/functions/usersService.ts b/src/services/functions/usersService.ts index 4bb9a56..1fef5cb 100644 --- a/src/services/functions/usersService.ts +++ b/src/services/functions/usersService.ts @@ -50,4 +50,40 @@ const getById = async (userId: string): Promise => { } }; -export default { getById } \ No newline at end of file +interface getByIdReturn { + data?: { + phone: '', + whatsapp: '', + facebook: '', + telegram: '', + }, + error?: { + errorMessage: string; + } +} + +const getUserSocialInfo = async (userId: string): Promise => { + try { + let res: getByIdRes = await usersRoutes.getSocialInfo(userId) + + if (res.status === "error") { + return { + error: { + errorMessage: res.message, + } + }; + } + + return { + userData: res.data, + }; + } catch(err) { + return { + error: { + errorMessage: "Por favor, autentique-se.", + } + }; + } +}; + +export default { getById, getUserSocialInfo } \ No newline at end of file From 8be0d3840769946d56e61d813fc21755c164491d Mon Sep 17 00:00:00 2001 From: Matheus Albino Brunhara Date: Tue, 7 Jun 2022 19:23:51 -0500 Subject: [PATCH 2/9] =?UTF-8?q?Mudando=20p=C3=A1gina=20CadastroCompletar?= =?UTF-8?q?=20de=20diret=C3=B3rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 2 +- src/pages/{ => CadastroCompletar}/CadastroCompletar.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/pages/{ => CadastroCompletar}/CadastroCompletar.tsx (96%) diff --git a/src/App.tsx b/src/App.tsx index daa740e..8a4dcab 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -17,7 +17,7 @@ import Login from './pages/Login'; import Home from './pages/Home'; import Perfil from './pages/Perfil'; import PerfilEditar from './pages/PerfilEditar'; -import CadastroCompletar from './pages/CadastroCompletar'; +import CadastroCompletar from './pages/CadastroCompletar/CadastroCompletar'; import CadastroVan from './pages/CadastroVan'; /* Core CSS required for Ionic components to work properly */ diff --git a/src/pages/CadastroCompletar.tsx b/src/pages/CadastroCompletar/CadastroCompletar.tsx similarity index 96% rename from src/pages/CadastroCompletar.tsx rename to src/pages/CadastroCompletar/CadastroCompletar.tsx index c068491..234aa19 100644 --- a/src/pages/CadastroCompletar.tsx +++ b/src/pages/CadastroCompletar/CadastroCompletar.tsx @@ -14,13 +14,13 @@ IonToolbar } from "@ionic/react"; import React, { useEffect, useReducer, useState } from "react"; -import './Perfil.css' +import '../Perfil.css' import { useHistory, useLocation } from "react-router"; import { bookOutline, callOutline, documentTextOutline, homeOutline } from "ionicons/icons"; -import * as usersRoutes from '../services/api/users'; +import * as usersRoutes from '../../services/api/users'; -import './Cadastro/Cadastro.css' +import '../Cadastro/Cadastro.css' interface userData { name: string; From ee5c4b0307cb78a63dbd0528ac77479391113644 Mon Sep 17 00:00:00 2001 From: Matheus Albino Brunhara Date: Tue, 7 Jun 2022 19:31:17 -0500 Subject: [PATCH 3/9] =?UTF-8?q?Revert=20"Mudando=20p=C3=A1gina=20CadastroC?= =?UTF-8?q?ompletar=20de=20diret=C3=B3rio"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 8be0d3840769946d56e61d813fc21755c164491d. --- src/App.tsx | 2 +- src/pages/{CadastroCompletar => }/CadastroCompletar.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/pages/{CadastroCompletar => }/CadastroCompletar.tsx (96%) diff --git a/src/App.tsx b/src/App.tsx index 8a4dcab..daa740e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -17,7 +17,7 @@ import Login from './pages/Login'; import Home from './pages/Home'; import Perfil from './pages/Perfil'; import PerfilEditar from './pages/PerfilEditar'; -import CadastroCompletar from './pages/CadastroCompletar/CadastroCompletar'; +import CadastroCompletar from './pages/CadastroCompletar'; import CadastroVan from './pages/CadastroVan'; /* Core CSS required for Ionic components to work properly */ diff --git a/src/pages/CadastroCompletar/CadastroCompletar.tsx b/src/pages/CadastroCompletar.tsx similarity index 96% rename from src/pages/CadastroCompletar/CadastroCompletar.tsx rename to src/pages/CadastroCompletar.tsx index 234aa19..c068491 100644 --- a/src/pages/CadastroCompletar/CadastroCompletar.tsx +++ b/src/pages/CadastroCompletar.tsx @@ -14,13 +14,13 @@ IonToolbar } from "@ionic/react"; import React, { useEffect, useReducer, useState } from "react"; -import '../Perfil.css' +import './Perfil.css' import { useHistory, useLocation } from "react-router"; import { bookOutline, callOutline, documentTextOutline, homeOutline } from "ionicons/icons"; -import * as usersRoutes from '../../services/api/users'; +import * as usersRoutes from '../services/api/users'; -import '../Cadastro/Cadastro.css' +import './Cadastro/Cadastro.css' interface userData { name: string; From 6d8e9180740a30b1b32a1f06995b8cf01f46f4f6 Mon Sep 17 00:00:00 2001 From: Matheus Albino Brunhara Date: Tue, 7 Jun 2022 20:04:56 -0500 Subject: [PATCH 4/9] =?UTF-8?q?Revert=20"Revert=20"Mudando=20p=C3=A1gina?= =?UTF-8?q?=20CadastroCompletar=20de=20diret=C3=B3rio""?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit ee5c4b0307cb78a63dbd0528ac77479391113644. --- src/App.tsx | 2 +- src/pages/{ => CadastroCompletar}/CadastroCompletar.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/pages/{ => CadastroCompletar}/CadastroCompletar.tsx (96%) diff --git a/src/App.tsx b/src/App.tsx index daa740e..8a4dcab 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -17,7 +17,7 @@ import Login from './pages/Login'; import Home from './pages/Home'; import Perfil from './pages/Perfil'; import PerfilEditar from './pages/PerfilEditar'; -import CadastroCompletar from './pages/CadastroCompletar'; +import CadastroCompletar from './pages/CadastroCompletar/CadastroCompletar'; import CadastroVan from './pages/CadastroVan'; /* Core CSS required for Ionic components to work properly */ diff --git a/src/pages/CadastroCompletar.tsx b/src/pages/CadastroCompletar/CadastroCompletar.tsx similarity index 96% rename from src/pages/CadastroCompletar.tsx rename to src/pages/CadastroCompletar/CadastroCompletar.tsx index c068491..234aa19 100644 --- a/src/pages/CadastroCompletar.tsx +++ b/src/pages/CadastroCompletar/CadastroCompletar.tsx @@ -14,13 +14,13 @@ IonToolbar } from "@ionic/react"; import React, { useEffect, useReducer, useState } from "react"; -import './Perfil.css' +import '../Perfil.css' import { useHistory, useLocation } from "react-router"; import { bookOutline, callOutline, documentTextOutline, homeOutline } from "ionicons/icons"; -import * as usersRoutes from '../services/api/users'; +import * as usersRoutes from '../../services/api/users'; -import './Cadastro/Cadastro.css' +import '../Cadastro/Cadastro.css' interface userData { name: string; From c368324747380256aee979027a6ba2d7d2e9d643 Mon Sep 17 00:00:00 2001 From: Matheus Albino Brunhara Date: Mon, 20 Jun 2022 00:51:08 -0500 Subject: [PATCH 5/9] =?UTF-8?q?Cadastro=20de=20van=20agora=20faz=20requisi?= =?UTF-8?q?=C3=A7=C3=B5es=20ao=20backend?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 8 +- src/constants/routes/vansLocatorsRoutes.ts | 17 ++ src/constants/routes/vansRoutes.ts | 17 ++ src/pages/CadastroVan.tsx | 205 +++++++++------------ src/services/api/users.ts | 8 +- src/services/api/vans.ts | 63 +++++++ src/services/functions/usersService.ts | 4 + src/services/validateCpf.ts | 25 +++ 8 files changed, 222 insertions(+), 125 deletions(-) create mode 100644 src/constants/routes/vansLocatorsRoutes.ts create mode 100644 src/constants/routes/vansRoutes.ts create mode 100644 src/services/api/vans.ts create mode 100644 src/services/validateCpf.ts diff --git a/src/App.tsx b/src/App.tsx index 8a4dcab..7b60766 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -17,8 +17,9 @@ import Login from './pages/Login'; import Home from './pages/Home'; import Perfil from './pages/Perfil'; import PerfilEditar from './pages/PerfilEditar'; -import CadastroCompletar from './pages/CadastroCompletar/CadastroCompletar'; import CadastroVan from './pages/CadastroVan'; +import CadastroCompletar from './pages/CadastroCompletar/CadastroCompletar'; +import CompletarDocumentos from './pages/CadastroCompletar/CompletarDocumentos'; /* Core CSS required for Ionic components to work properly */ import '@ionic/react/css/core.css'; @@ -48,11 +49,16 @@ const routes = ( <> + + + + + diff --git a/src/constants/routes/vansLocatorsRoutes.ts b/src/constants/routes/vansLocatorsRoutes.ts new file mode 100644 index 0000000..1f57945 --- /dev/null +++ b/src/constants/routes/vansLocatorsRoutes.ts @@ -0,0 +1,17 @@ +const vansRoutesDefault = '/vans/locator'; +const vansRoutes = { + list: { + url: `${vansRoutesDefault}/list` + }, + getById: { + url: `${vansRoutesDefault}/` + }, + create: { + url: `${vansRoutesDefault}/` + }, + update: { + url: `${vansRoutesDefault}/edit` + } +} + +export default vansRoutes; \ No newline at end of file diff --git a/src/constants/routes/vansRoutes.ts b/src/constants/routes/vansRoutes.ts new file mode 100644 index 0000000..a4e241c --- /dev/null +++ b/src/constants/routes/vansRoutes.ts @@ -0,0 +1,17 @@ +const vansRoutesDefault = '/vans'; +const vansRoutes = { + list: { + url: `${vansRoutesDefault}/list` + }, + getById: { + url: `${vansRoutesDefault}/` + }, + create: { + url: `${vansRoutesDefault}/` + }, + update: { + url: `${vansRoutesDefault}/` + } +} + +export default vansRoutes; \ No newline at end of file diff --git a/src/pages/CadastroVan.tsx b/src/pages/CadastroVan.tsx index 7862f9d..5218d7c 100644 --- a/src/pages/CadastroVan.tsx +++ b/src/pages/CadastroVan.tsx @@ -20,12 +20,12 @@ import { import React, { useEffect, useReducer, useState } from "react"; -import * as yup from 'yup'; - -import { ApiClient } from "../services/api-client.service"; +// import * as yup from 'yup'; import carsService from '../services/functions/carsService' +import * as vansRoutes from '../services/api/vans'; + import "./CadastroVan.css"; const CadastroVan: React.FC = () => { @@ -43,77 +43,34 @@ const CadastroVan: React.FC = () => { carPlate: '', carBrand: '', carModel: '', - maxPassengers: 1, - isRent: false, - carRentalName: '', - postalCode: '', - street: '', - number: '', - complement: '', - city: '', - state: '', + seats_number: 1, + isRented: false, + locator_name: '', + locator_address: '', + locator_complement: '', + locator_city: '', + locator_state: '', } ); - // TODO, yup - let schema = yup.object().shape({ - carPlate: yup.string().required(), - carBrand: yup.string().required(), - carModel: yup.string().required(), - maxPassengers: yup.number().integer().min(1).max(100).required(), - isRented: yup.boolean().required(), - carRentalName: yup.string(), // .required(), - postalCode: yup.string(), // .required(), - street: yup.string(), // .required(), - number: yup.number().integer(), // .required(), - complement: yup.string(), // .required(), - city: yup.string(), // .required(), - state: yup.string(), // .required(), - - // name: yup.string().required(), - // age: yup.number().required().positive().integer(), - // email: yup.string().email(), - // website: yup.string().url(), - // createdOn: yup.date().default(function () { - // return new Date(); - // }), - }); - - const vanForm = { - carPlate: inputValues.carPlate, - carBrand: inputValues.carBrand, - carModel: inputValues.carModel, - maxPassengers: inputValues.maxPassengers, - isRented: inputValues.isRented, - carRentalName: inputValues.carRentalName, - carRentalAddress: { - postalCode: inputValues.postalCode, - street: inputValues.street, - number: inputValues.number, - complement: inputValues.complement, - city: inputValues.city, - state: inputValues.state, - } - }; - const clearRentalData = () => { setInputValues({ - carPlate: '', - carBrand: '', - carModel: '', - maxPassengers: 1, - isRent: false, - carRentalName: '', - postalCode: '', - street: '', - number: '', - complement: '', - city: '', - state: '', + carRentalName: '', + complement: '', + city: '', + state: '', }) }; const validateForm = (): boolean => { + const vanForm = { + carPlate: inputValues.carPlate, + carBrand: inputValues.carBrand, + carModel: inputValues.carModel, + seats_number: inputValues.seats_number, + isRented: inputValues.isRented, + }; + if ( !vanForm.carPlate || vanForm.carPlate.length !== 7 || @@ -136,12 +93,18 @@ const CadastroVan: React.FC = () => { return false; } - if (!vanForm.maxPassengers || !parseInt(`${vanForm.maxPassengers}`)) { + if (!vanForm.seats_number || !parseInt(`${vanForm.seats_number}`)) { setToastMessage("Número de passageiros inválido"); setShowToast(true); return false; } + if ((Number)(vanForm.seats_number) < 1) { + setToastMessage("Número de passageiros deve ser positivo!"); + setShowToast(true); + return false; + } + if (vanForm.isRented) { return validateRentalForm(); } else { @@ -152,43 +115,32 @@ const CadastroVan: React.FC = () => { }; const validateRentalForm = (): boolean => { - if (!vanForm.carRentalName) { + const locatorForm = { + locator_name: inputValues.locator_name, + locator_address: inputValues.locator_address, + locator_complement: inputValues.locator_complement, + locator_city: inputValues.locator_city, + locator_state: inputValues.locator_state, + } + + if (!locatorForm.locator_name) { setToastMessage("Nome do Locador é obrigatório"); setShowToast(true); return false; } if ( - !vanForm.carRentalAddress.postalCode || - vanForm.carRentalAddress.postalCode.length !== 8 || - !vanForm.carRentalAddress.postalCode.match(/([0-9]){8}/g) + !locatorForm.locator_city || + !locatorForm.locator_city.match(/([A-zà-úÀ-Ú])/g) ) { - setToastMessage("Cep inválido"); + setToastMessage("Cidade inválida"); setShowToast(true); return false; } if ( - !vanForm.carRentalAddress.number || - !parseInt(`${vanForm.carRentalAddress.number}`) - ) { - setToastMessage("Número inválido"); - setShowToast(true); - return false; - } - - if ( - !vanForm.carRentalAddress.city || - !vanForm.carRentalAddress.city.match(/([A-zà-úÀ-Ú])/g) - ) { - setToastMessage("Cidade inválido"); - setShowToast(true); - return false; - } - - if ( - !vanForm.carRentalAddress.state || - !vanForm.carRentalAddress.state.match(/([A-zà-úÀ-Ú])/g) + !locatorForm.locator_state || + !locatorForm.locator_state.match(/([A-zà-úÀ-Ú])/g) ) { setToastMessage("Estado inválido"); setShowToast(true); @@ -199,9 +151,34 @@ const CadastroVan: React.FC = () => { }; const handleSubmit = async () => { - if (validateForm()) { - await ApiClient.doPost("/cadastro-van", vanForm); + if (!validateForm()) { + return } + + // cria registro da van + await vansRoutes.create({ + plate: inputValues.carPlate, + brand: inputValues.carBrand, + model: inputValues.carModel, + seats_number: inputValues.seats_number, + locator_name: inputValues.locator_name, + locator_address: inputValues.locator_address, + locator_complement: inputValues.locator_complement, + locator_city: inputValues.locator_city, + locator_state: inputValues.locator_state + }).then(response => { + if (response.status === 'error') { + setToastMessage(response.message); + setShowToast(true); + + return + } + + console.log(response) + }).catch((err) => { + setToastMessage(err); + setShowToast(true); + }) }; useEffect(() => { @@ -248,24 +225,15 @@ const CadastroVan: React.FC = () => { setInputValues({ carPlate: e.target.value })} + onIonChange={(e: any) => setInputValues({ carPlate: e.target.value })} /> - {/* - Marca - setInputValues({ carBrand: e.target.value })} - /> - */} - Marca - + setInputValues({ carBrand: e.target.value })}> { carModels ? carModels.map((carModel, index) => { return ({carModel.name}) }) : <> } @@ -278,19 +246,20 @@ const CadastroVan: React.FC = () => { type='text' clearInput placeholder='Digite o Modelo do Veículo' - onIonInput={(e: any) => setInputValues({ carModel: e.target.value })} + onIonChange={(e: any) => setInputValues({ carModel: e.target.value })} /> - Número Máximo de Passageiros + Número de assentos setInputValues({ maxPassengers: e.target.value })} + placeholder='podem ser ocupados por passageiros' + onIonChange={(e: any) => setInputValues({ seats_number: e.target.value })} /> @@ -313,38 +282,32 @@ const CadastroVan: React.FC = () => { type='text' clearInput placeholder='Nome completo do Locador' - onIonInput={(e: any) => setInputValues({ carRentalName: e.target.value })} + onIonChange={(e: any) => setInputValues({ locator_name: e.target.value })} /> setInputValues({ postalCode: e.target.value })} - /> - setInputValues({ number: e.target.value })} + onIonChange={(e: any) => setInputValues({ locator_address: e.target.value })} /> setInputValues({ complement: e.target.value })} + onIonChange={(e: any) => setInputValues({ locator_complement: e.target.value })} /> setInputValues({ city: e.target.value })} + onIonChange={(e: any) => setInputValues({ locator_city: e.target.value })} /> setInputValues({ state: e.target.value })} + onIonChange={(e: any) => setInputValues({ locator_state: e.target.value })} /> diff --git a/src/services/api/users.ts b/src/services/api/users.ts index fd6cd27..be989af 100644 --- a/src/services/api/users.ts +++ b/src/services/api/users.ts @@ -37,9 +37,11 @@ export interface CadastroRequest { } export interface UpdateUserRequest { - name: string; - email: string; - bio: string; + name?: string; + email?: string; + bio?: string; + cpf?: string; + cnpj?: string; } // export async function get(cpf) { diff --git a/src/services/api/vans.ts b/src/services/api/vans.ts new file mode 100644 index 0000000..f77b867 --- /dev/null +++ b/src/services/api/vans.ts @@ -0,0 +1,63 @@ +import instance from "./api"; + +import vansRoutes from "../../constants/routes/vansRoutes"; +import { AxiosRequestHeaders } from "axios"; +import LocalStorage from "../../LocalStorage"; + +let token: string; +let header: AxiosRequestHeaders; + +function updateHeader() { + token = LocalStorage.getToken(); + + header = { + Accept: "application/json", + "Content-Type": "application/json", + Authorization: "Bearer " + token, + }; +} + +export async function getById(vanId: string) { + updateHeader(); + + const response = await instance.get(vansRoutes.getById.url + `/${vanId}`, { + headers: header, + }); + + return response.data; +} + +interface CreateVanBody { + plate: string; + brand: string; + model: string; + seats_number: string; + locator_name: string; + locator_address: string; + locator_complement: string; + locator_city: string; + locator_state: string; +} + +export async function create(CreateVanBody: CreateVanBody) { + updateHeader(); + + const response = await instance.post(vansRoutes.create.url, CreateVanBody); + return response.data; +} + +interface UpdateVanBody { + brand?: string; + model?: string; + seats_number?: string; +} + +export async function update(vanData: UpdateVanBody) { + updateHeader(); + + const response = await instance.patch(vansRoutes.update.url, vanData, { + headers: header, + }); + + return response.data; +} \ No newline at end of file diff --git a/src/services/functions/usersService.ts b/src/services/functions/usersService.ts index 1fef5cb..b0d6ae1 100644 --- a/src/services/functions/usersService.ts +++ b/src/services/functions/usersService.ts @@ -7,6 +7,8 @@ interface getByIdReturn { email: string; birth_date: string; bio: string; + cpf: string; + cnpj: string; }, error?: { errorMessage: string; @@ -23,6 +25,8 @@ interface getByIdRes { email: string; birth_date: string; bio: string; + cpf: string; + cnpj: string; }, } diff --git a/src/services/validateCpf.ts b/src/services/validateCpf.ts new file mode 100644 index 0000000..d713b68 --- /dev/null +++ b/src/services/validateCpf.ts @@ -0,0 +1,25 @@ +export default function validateCpf(cpf: string): Boolean { + let soma = 0, resto; + + if (cpf === "00000000000") return false; + + for (let i = 1; i <= 9; i++) + soma = soma + parseInt(cpf.substring(i - 1, i)) * (11 - i); + + resto = (soma * 10) % 11; + + if (resto === 10 || resto === 11) resto = 0; + if (resto !== parseInt(cpf.substring(9, 10))) return false; + + soma = 0; + for (let i = 1; i <= 10; i++) + soma = soma + parseInt(cpf.substring(i - 1, i)) * (12 - i); + + resto = (soma * 10) % 11; + + if (resto === 10 || resto === 11) resto = 0; + + if (resto !== parseInt(cpf.substring(10, 11))) return false; + + return true; +}; \ No newline at end of file From 3e63a74fc92feae1f81496b0e830fdd30068b244 Mon Sep 17 00:00:00 2001 From: Matheus Albino Brunhara Date: Mon, 20 Jun 2022 04:05:34 -0500 Subject: [PATCH 6/9] Terminando telas de completar cadastro --- src/App.tsx | 6 +- .../CadastroCompletar/CadastroCompletar.tsx | 101 +++------ .../CadastroCompletar/CompletarDocumento.tsx | 193 ++++++++++++++++++ .../CadastroCompletar/CompletarTelefone.tsx | 137 +++++++++++++ src/pages/CadastroVan.tsx | 3 +- src/pages/Home.tsx | 2 +- src/pages/Perfil.tsx | 101 +++------ src/pages/PerfilEditar.tsx | 4 + src/services/api/users.ts | 5 +- src/services/functions/usersService.ts | 10 +- 10 files changed, 411 insertions(+), 151 deletions(-) create mode 100644 src/pages/CadastroCompletar/CompletarDocumento.tsx create mode 100644 src/pages/CadastroCompletar/CompletarTelefone.tsx diff --git a/src/App.tsx b/src/App.tsx index 7b60766..ee3dfae 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -19,7 +19,8 @@ import Perfil from './pages/Perfil'; import PerfilEditar from './pages/PerfilEditar'; import CadastroVan from './pages/CadastroVan'; import CadastroCompletar from './pages/CadastroCompletar/CadastroCompletar'; -import CompletarDocumentos from './pages/CadastroCompletar/CompletarDocumentos'; +import CompletarDocumento from './pages/CadastroCompletar/CompletarDocumento'; +import CompletarTelefone from './pages/CadastroCompletar/CompletarTelefone'; /* Core CSS required for Ionic components to work properly */ import '@ionic/react/css/core.css'; @@ -55,7 +56,8 @@ const routes = ( - + + diff --git a/src/pages/CadastroCompletar/CadastroCompletar.tsx b/src/pages/CadastroCompletar/CadastroCompletar.tsx index 234aa19..09e4c73 100644 --- a/src/pages/CadastroCompletar/CadastroCompletar.tsx +++ b/src/pages/CadastroCompletar/CadastroCompletar.tsx @@ -12,13 +12,11 @@ IonPage, IonTitle, IonToolbar } from "@ionic/react"; -import React, { useEffect, useReducer, useState } from "react"; +import React, { useEffect, useReducer } from "react"; import '../Perfil.css' import { useHistory, useLocation } from "react-router"; -import { bookOutline, callOutline, documentTextOutline, homeOutline } from "ionicons/icons"; - -import * as usersRoutes from '../../services/api/users'; +import { callOutline, documentTextOutline } from "ionicons/icons"; import '../Cadastro/Cadastro.css' @@ -26,93 +24,60 @@ interface userData { name: string; lastname: string; email: string; + phone_number: string; birth_date: string; bio: string; + document_type: string; + document: string; } interface LocationState { userData: userData } -const items = [ - // TODO, CPF e CNH +interface cardItem { + icon: string; + label: string; + description: string; + url: string; + required: boolean; +} + +let items: cardItem[] = [ { icon: documentTextOutline, - label: 'Documentos', - description: 'Cadastre seus documentos para que seu perfil possa ser verificado.' + label: 'Documento', + description: 'Cadastre seu documento para que seu perfil possa ser verificado', + url: '/perfil/completar/documento', + required: false }, - // TODO, telefone e WhatsApp { icon: callOutline, label: 'Informações de contato', - description: 'Cadastre seu número de telefone celular que para possam contatar você.' - }, - { - icon: homeOutline, - label: 'Endereço de residência', - description: 'Diga-nos seu endereço para que possa começar a solicitar vagas.' - }, - { - icon: bookOutline, - label: 'Instituição de ensino', - description: 'Diga-nos sua IES para que possa começar a solicitar vagas.' - }, + description: 'Cadastre seu número de telefone celular que para possam contatar você', + url: '/perfil/completar/telefone', + required: false + } ] const CadastroCompletar: React.FC = () => { const history = useHistory(); const location = useLocation(); - const [showToast, setShowToast] = useState(false); - const [messageToast, setMessageToast] = useState(''); + const handleCardClick = (item: cardItem) => { + if (!item.required) return - const [userData, setUserData] = useState({ - name: '', - lastname: '', - email: '', - birth_date: '', - bio: '', - }); - - const [inputValues, setInputValues] = useReducer( - (state: any, newState: any) => ({ ...state, ...newState }), - { - name: '', - lastname: '', - email: '', - birth_date: '', - bio: '', - } - ); + history.push({ pathname: item.url }); + } useEffect(() => { - let userData = location.state.userData + if (!location.state) { + history.push({ pathname: '/perfil' }) + } - setUserData(location.state.userData) - setInputValues({ - 'name': userData.name, - 'lastname': userData.lastname, - 'email': userData.email, - 'birth_date': userData.birth_date, - '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); - }) - } + if (!location.state.userData.document) items[0].required = true + if (!location.state.userData.phone_number) items[1].required = true + }, []); return ( @@ -128,7 +93,7 @@ const CadastroCompletar: React.FC = () => { { items.map((item, index) => { return ( - + { handleCardClick(item) }}> {item.label} diff --git a/src/pages/CadastroCompletar/CompletarDocumento.tsx b/src/pages/CadastroCompletar/CompletarDocumento.tsx new file mode 100644 index 0000000..d1c7147 --- /dev/null +++ b/src/pages/CadastroCompletar/CompletarDocumento.tsx @@ -0,0 +1,193 @@ +import { + IonBackButton, + IonButtons, + IonContent, + IonFab, + IonFabButton, + IonHeader, + IonIcon, + IonList, + IonPage, + IonSelect, + IonSelectOption, + IonTitle, + IonToast, + IonToolbar +} from "@ionic/react"; +import React, { useEffect, useState } from "react"; +import { IonGrid, IonRow, IonCol } from "@ionic/react"; +import { useHistory, useLocation } from "react-router-dom"; +import { + IonItem, + IonLabel, + IonInput, +} from "@ionic/react"; + +import { saveOutline } from "ionicons/icons"; + +import * as usersRoutes from '../../services/api/users'; + +import validateCpf from '../../services/validateCpf' + +interface documentTypesInterface { + label: string; + name: string; +} + +const CompletarDocumento: React.FC = () => { + const [hasChangedSinceInitialState, setHasChangedSinceInitialState] = useState(false); + + const [documentTypes, setDocumentTypes] = useState([]); + + const [document, setDocument] = useState(''); + const [documentType, setDocumentType] = useState(''); + + const [documentMaxLength, setDocumentMaxLength] = useState(0); + + const [showToast, setShowToast] = useState(false); + const [messageToast, setMessageToast] = useState(''); + + const history = useHistory(); + const location = useLocation(); + + useEffect(() => { + if (!location.state) { + history.push({ pathname: '/perfil/completar' }) + } + }, []) + + const validateform = () => { + console.log(document) + if (isNaN((Number)(document))) { + setMessageToast('Documento pode conter apenas números!') + setShowToast(true) + return false + } + + if (documentType === 'cpf' && !validateCpf(document)) { + setMessageToast('CPF inválido!') + setShowToast(true) + return false + } + + return true + } + + const handleUpdateUserDocuments = async () => { + if (!validateform()) { + return + } + + usersRoutes.update({ document_type: documentType, document: document }).then(response => { + if (response.status === 'error') { + setMessageToast(response.message); + setShowToast(true); + + return + } + + console.log(response) + }).catch((err) => { + setMessageToast(err); + setShowToast(true); + }) + }; + + const handleChangeDocumentType = (document_type: string) => { + switch(document_type) { + case 'cpf': + setDocumentType('cpf') // workaround para o problema de setState para valores vindos de um evento sendo triggerado por um ion-select + setDocumentMaxLength(11) + break; + case 'cnh': + setDocumentType('cnh') // workaround para o problema de setState para valores vindos de um evento sendo triggerado por um ion-select + setDocumentMaxLength(11) + break; + case 'rg': + setDocumentType('rg') // workaround para o problema de setState para valores vindos de um evento sendo triggerado por um ion-select + setDocumentMaxLength(9) + break; + } + } + + useEffect(() => { + setDocumentTypes([ + { + name: 'cpf', + label: 'CPF', + }, + { + name: 'rg', + label: 'RG', + }, + { + name: 'cnh', + label: 'CNH', + }, + ]) + }, []) + + return ( + + + + Completar cadastro + + + + + + + + + + Completar cadastro + + + + + + + + + Tipo de documento + { handleChangeDocumentType(e.detail.value) } }> + { documentTypes ? documentTypes.map((document, index) => { + return ({document.label}) + }) : <> } + + + + Documento + { setDocument(e.target.value); setHasChangedSinceInitialState(true) }} + > + + + + + + + + + + + + + setShowToast(false)} + message={messageToast} + duration={2500} + /> + + + ); +}; + +export default CompletarDocumento; + \ No newline at end of file diff --git a/src/pages/CadastroCompletar/CompletarTelefone.tsx b/src/pages/CadastroCompletar/CompletarTelefone.tsx new file mode 100644 index 0000000..6bccd65 --- /dev/null +++ b/src/pages/CadastroCompletar/CompletarTelefone.tsx @@ -0,0 +1,137 @@ +import { + IonBackButton, + IonButtons, + IonContent, + IonFab, + IonFabButton, + IonHeader, + IonIcon, + IonList, + IonPage, + IonSelect, + IonSelectOption, + IonTitle, + IonToast, + IonToolbar +} from "@ionic/react"; +import React, { useEffect, useState } from "react"; +import { IonGrid, IonRow, IonCol } from "@ionic/react"; +import { useHistory, useLocation } from "react-router-dom"; +import { + IonItem, + IonLabel, + IonInput, +} from "@ionic/react"; + +import { saveOutline } from "ionicons/icons"; + +import * as usersRoutes from '../../services/api/users'; + +interface documentTypesInterface { + label: string; + name: string; +} + +const CompletarTelefone: React.FC = () => { + const [hasChangedSinceInitialState, setHasChangedSinceInitialState] = useState(false); + + const [phone, setPhone] = useState(''); + + const [showToast, setShowToast] = useState(false); + const [messageToast, setMessageToast] = useState(''); + + const history = useHistory(); + const location = useLocation(); + + useEffect(() => { + if (!location.state) { + history.push({ pathname: '/perfil/completar' }) + } + }, []) + + const validateform = () => { + if (isNaN((Number)(phone))) { + setMessageToast('O telefone pode conter apenas números!') + setShowToast(true) + return false + } + + return true + } + + const handleUpdateUserDocuments = async () => { + if (!validateform()) { + return + } + + usersRoutes.update({ phone_number: phone }).then(response => { + if (response.status === 'error') { + setMessageToast(response.message); + setShowToast(true); + + return + } + + console.log(response) + }).catch((err) => { + setMessageToast(err); + setShowToast(true); + }) + }; + + return ( + + + + Completar cadastro + + + + + + + + + + Completar cadastro + + + + + + + + + Telefone + { setPhone(e.target.value); setHasChangedSinceInitialState(true) }} + > + + + + + + + + + + + + + setShowToast(false)} + message={messageToast} + duration={2500} + /> + + + ); +}; + +export default CompletarTelefone; + \ No newline at end of file diff --git a/src/pages/CadastroVan.tsx b/src/pages/CadastroVan.tsx index 5218d7c..7b592d3 100644 --- a/src/pages/CadastroVan.tsx +++ b/src/pages/CadastroVan.tsx @@ -231,9 +231,10 @@ const CadastroVan: React.FC = () => { /> + {/* TODO, problema de setState para valores vindos de um evento sendo triggerado por um ion-select */} Marca - setInputValues({ carBrand: e.target.value })}> + { setInputValues({ carBrand: e.detail.value }) }}> { carModels ? carModels.map((carModel, index) => { return ({carModel.name}) }) : <> } diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index b8b835c..c3d74d6 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -38,7 +38,7 @@ const Home: React.FC = () => { return ( - { history.push({ pathname: '/usuario/56520ae7-faf8-4444-a82b-7f3990ab02d8' }); }}>Ir para o perfil de outra pessoa + {/* { history.push({ pathname: '/usuario/56520ae7-faf8-4444-a82b-7f3990ab02d8' }); }}>Ir para o perfil de outra pessoa */} ); diff --git a/src/pages/Perfil.tsx b/src/pages/Perfil.tsx index ea2dcfd..cb4d126 100644 --- a/src/pages/Perfil.tsx +++ b/src/pages/Perfil.tsx @@ -42,27 +42,23 @@ const Perfil: React.FC = (props) => { const [isVisitor, setIsVisitor] = useState(true) + const [incompleteProfile, setIncompleteProfile] = useState(false) + const [showToast, setShowToast] = useState(false); const [messageToast, setMessageToast] = useState(''); const [inputValues, setInputValues] = useReducer( (state: any, newState: any) => ({ ...state, ...newState }), { + id: '', name: '', lastname: '', email: '', + phone_number: '', birth_date: '', bio: '', - } - ); - - const [inputSocialInformationValues, setInputSocialInformationValues] = useReducer( - (state: any, newState: any) => ({ ...state, ...newState }), - { - phone: '', - whatsapp: '', - facebook: '', - telegram: '', + document_type: '', + document: '', } ); @@ -122,44 +118,24 @@ const Perfil: React.FC = (props) => { if (isMounted) { setInputValues({ + 'id': userId, 'name': userData.name, 'lastname': userData.lastname, 'email': userData.email, + 'phone_number': userData.phone_number, 'birth_date': userData.birth_date, - 'bio': userData.bio + 'bio': userData.bio, + 'document_type': userData.document_type, + 'document': userData.document }); if (!props.match.params.id) { setIsVisitor(false) } - } - } - // get user social info - const getUserSocialInfoRes = await usersService.getUserSocialInfo(userId) - - if (getUserSocialInfoRes.error) { - if (isVisitor && props.match.params.id) { - setMessageToast('Usuário não existe!') - setShowToast(true) - history.push({ pathname: '/home' }) - } else { - setMessageToast(getUserSocialInfoRes.error.errorMessage) - setShowToast(true) - } - - return - } - - if (getUserSocialInfoRes.data) { - const userSocialData = getUserSocialInfoRes.data - - if (isMounted) { - setInputSocialInformationValues({ - 'phone': userSocialData.phone, - 'whatsapp': userSocialData.whatsapp, - 'facebook': userSocialData.facebook, - 'telegram': userSocialData.telegram, - }); + + if (!userData.document || !userData.phone_number) { + setIncompleteProfile(true) + } } } } @@ -226,42 +202,15 @@ const Perfil: React.FC = (props) => { Informações de contato - { !inputSocialInformationValues.phone && !inputSocialInformationValues.whatsapp && !inputSocialInformationValues.facebook && !inputSocialInformationValues.telegram ? + { !inputValues.phone_number ? <>Sem informações de contato. : <> { - inputSocialInformationValues.phone ? + inputValues.phone_number ? <> - {inputSocialInformationValues.phone} - - : <> - } - - { inputSocialInformationValues.whatsapp ? - <> - - - {inputSocialInformationValues.whatsapp} - - : <> - } - - { inputSocialInformationValues.facebook ? - <> - - - {inputSocialInformationValues.facebook} - - : <> - } - - { inputSocialInformationValues.telegram ? - <> - - - {inputSocialInformationValues.telegram} + {inputValues.phone_number} : <> } @@ -277,10 +226,16 @@ const Perfil: React.FC = (props) => { Editar perfil - history.push({ pathname: '/perfil/completar', state: { userData: inputValues } })}> - - Completar cadastro - + + { incompleteProfile ? + <> + history.push({ pathname: '/perfil/completar', state: { userData: inputValues } })}> + + Completar cadastro + + + : <> } + history.push({ pathname: '/cadastro-van'})}> Cadastrar Van diff --git a/src/pages/PerfilEditar.tsx b/src/pages/PerfilEditar.tsx index e7c8d1f..47271f0 100644 --- a/src/pages/PerfilEditar.tsx +++ b/src/pages/PerfilEditar.tsx @@ -68,6 +68,10 @@ const PerfilEditar: React.FC = () => { ); useEffect(() => { + if (!location.state) { + history.push({ pathname: '/perfil' }) + } + let userData = location.state.userData setUserData(location.state.userData) diff --git a/src/services/api/users.ts b/src/services/api/users.ts index be989af..d2d16e4 100644 --- a/src/services/api/users.ts +++ b/src/services/api/users.ts @@ -40,8 +40,9 @@ export interface UpdateUserRequest { name?: string; email?: string; bio?: string; - cpf?: string; - cnpj?: string; + document_type?: string; + document?: string; + phone_number?: string; } // export async function get(cpf) { diff --git a/src/services/functions/usersService.ts b/src/services/functions/usersService.ts index b0d6ae1..34b25be 100644 --- a/src/services/functions/usersService.ts +++ b/src/services/functions/usersService.ts @@ -5,10 +5,11 @@ interface getByIdReturn { name: string; lastname: string; email: string; + phone_number: string; birth_date: string; bio: string; - cpf: string; - cnpj: string; + document_type: string; + document: string; }, error?: { errorMessage: string; @@ -23,10 +24,11 @@ interface getByIdRes { name: string; lastname: string; email: string; + phone_number: string; birth_date: string; bio: string; - cpf: string; - cnpj: string; + document_type: string; + document: string; }, } From b1120248b9aa1b68110c56e1743394b79c2339d7 Mon Sep 17 00:00:00 2001 From: Matheus Albino Brunhara Date: Mon, 20 Jun 2022 05:25:00 -0500 Subject: [PATCH 7/9] =?UTF-8?q?Diversas=20melhorias=20e=20toasts=20aparece?= =?UTF-8?q?m=20em=20redirecionamentos=20de=20p=C3=A1ginas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Cadastro/Cadastro.tsx | 128 +++++++++--------- .../CadastroCompletar/CadastroCompletar.tsx | 55 ++++++-- .../CadastroCompletar/CompletarDocumento.tsx | 56 ++++++-- .../CadastroCompletar/CompletarTelefone.tsx | 66 ++++++--- src/pages/CadastroVan.tsx | 27 +++- src/pages/Home.tsx | 42 +++++- src/pages/Login.tsx | 8 +- src/pages/Perfil.tsx | 54 ++++++-- src/pages/PerfilEditar.tsx | 10 +- 9 files changed, 315 insertions(+), 131 deletions(-) diff --git a/src/pages/Cadastro/Cadastro.tsx b/src/pages/Cadastro/Cadastro.tsx index debc61a..82c6b9a 100644 --- a/src/pages/Cadastro/Cadastro.tsx +++ b/src/pages/Cadastro/Cadastro.tsx @@ -8,6 +8,7 @@ import ModalExample from '../../components/Email'; import * as UsersService from '../../services/api/users' import LocalStorage from '../../LocalStorage'; import { UserContext } from '../../App'; +import { Color } from '@ionic/react/node_modules/@ionic/core'; const Cadastro: React.FC = () => { const history = useHistory(); @@ -15,7 +16,8 @@ const Cadastro: React.FC = () => { const user = useContext(UserContext); const [showToast, setShowToast] = useState(false); - const [messageToast, setMessageToast ] = useState(''); + const [messageToast, setMessageToast] = useState(''); + const [toastColor, setToastColor] = useState("primary"); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); @@ -57,7 +59,7 @@ const Cadastro: React.FC = () => { clearResult(); if(!emailValidate()) { - lResult.error = 'O EMAIL é inválido!'; + lResult.error = 'E-mail inválido!'; lResult.success = false; return lResult; } else if(password.length < 7 || password.length > 12) { //TODO: validar de acordo com a documentação @@ -70,50 +72,56 @@ const Cadastro: React.FC = () => { }; const handleSubmit = async () => { - - if(name != '' && email != '' && birthDate != '' && password != '' && confirmPassword != '') { - if(password === confirmPassword){ - const signUpForm = { - name: firstName, - lastname: lastName, - email: email, - birth_date: birthDate, - password: password - } - - let result = fieldValidate(); - if((await result).success) { - - let retorno = await UsersService.create(signUpForm); - console.log(retorno); - if(retorno.token) { - // let signIn = await Api.signIn(email, passwordField); - // if(signIn.token) { - // await AsyncStorage.setItem('token', signIn.token); - // await AsyncStorage.setItem('cpf', retorno.cpf); - - LocalStorage.setToken(retorno.token.token); - - user.setIsLoggedIn(true); - - history.push('home'); - - } else { - setMessageToast(retorno.message); - setShowToast(true); - } - } else{ - setMessageToast(lResult.error); - setShowToast(true); - } - } else { - setMessageToast('As senhas devem ser iguais!'); - setShowToast(true); - } - } else { - setMessageToast('Nenhum campo pode ser nulo!'); + if(name === '' || email === '' || birthDate === '' || password === '' || confirmPassword === '') { + setToastColor("warning") + setMessageToast('Nenhum campo pode estar vazio!'); setShowToast(true); + return } + + if(password !== confirmPassword) { + setToastColor("warning") + setMessageToast('As senhas devem ser iguais!'); + setShowToast(true); + return + } + + const signUpForm = { + name: firstName, + lastname: lastName, + email: email, + birth_date: birthDate, + password: password + } + + let result = fieldValidate(); + if(!(await result).success) { + setToastColor("warning") + setMessageToast(lResult.error); + setShowToast(true); + return + } + + let retorno = await UsersService.create(signUpForm); + + if(!retorno.token) { + setToastColor('danger') + setMessageToast(retorno.message); + setShowToast(true); + return + } + + LocalStorage.setToken(retorno.token.token); + + user.setIsLoggedIn(true); + + history.push({ pathname: '/home', state: { + redirectData: { + showToastMessage: true, + toastColor: "success", + toastMessage: "Usuário cadastrado com sucesso!", + } + }}) }; const { name } = useParams<{ name: string; }>(); @@ -130,19 +138,11 @@ const Cadastro: React.FC = () => { - - {/* Como você deseja se cadastrar? */} - Cadastro - + + {/* Como você deseja se cadastrar? */} + Cadastro + - {/* - - Continuar com Facebook - - - - Continuar com e-mail - */}
@@ -151,7 +151,7 @@ const Cadastro: React.FC = () => { setFirstName(e.target.value)} + onIonChange={(e: any) => setFirstName(e.target.value)} > @@ -159,7 +159,7 @@ const Cadastro: React.FC = () => { Sobrenome setLastName(e.target.value)} + onIonChange={(e: any) => setLastName(e.target.value)} > @@ -170,7 +170,7 @@ const Cadastro: React.FC = () => { setEmail(e.target.value)} + onIonChange={(e: any) => setEmail(e.target.value)} > @@ -179,7 +179,7 @@ const Cadastro: React.FC = () => { Data de nascimento setBirthDate(e.target.value)} + onIonChange={(e: any) => setBirthDate(e.target.value)} > @@ -189,7 +189,7 @@ const Cadastro: React.FC = () => { setPassword(e.target.value)} + onIonChange={(e: any) => setPassword(e.target.value)} > @@ -197,7 +197,7 @@ const Cadastro: React.FC = () => { setConfirmPassword(e.target.value)} + onIonChange={(e: any) => setConfirmPassword(e.target.value)} > @@ -210,9 +210,9 @@ const Cadastro: React.FC = () => { {/*
*/} + setShowToast(false)} message={messageToast} diff --git a/src/pages/CadastroCompletar/CadastroCompletar.tsx b/src/pages/CadastroCompletar/CadastroCompletar.tsx index 09e4c73..de2c677 100644 --- a/src/pages/CadastroCompletar/CadastroCompletar.tsx +++ b/src/pages/CadastroCompletar/CadastroCompletar.tsx @@ -10,15 +10,25 @@ IonItem, IonLabel, IonPage, IonTitle, +IonToast, IonToolbar } from "@ionic/react"; -import React, { useEffect, useReducer } from "react"; +import React, { useEffect, useReducer, useState } from "react"; import '../Perfil.css' import { useHistory, useLocation } from "react-router"; import { callOutline, documentTextOutline } from "ionicons/icons"; import '../Cadastro/Cadastro.css' +import { Color } from "@ionic/react/node_modules/@ionic/core"; + +interface cardItem { + icon: string; + label: string; + description: string; + url: string; + required: boolean; +} interface userData { name: string; @@ -32,15 +42,13 @@ interface userData { } interface LocationState { - userData: userData -} - -interface cardItem { - icon: string; - label: string; - description: string; - url: string; - required: boolean; + userData: userData; + + redirectData?: { + showToastMessage: boolean; + toastColor: Color; + toastMessage: string; + } } let items: cardItem[] = [ @@ -64,17 +72,31 @@ const CadastroCompletar: React.FC = () => { const history = useHistory(); const location = useLocation(); + const [showToast, setShowToast] = useState(false); + const [toastMessage, setToastMessage] = useState(''); + const [toastColor, setToastColor] = useState("primary"); + const handleCardClick = (item: cardItem) => { if (!item.required) return - history.push({ pathname: item.url }); + history.push({ pathname: item.url, state: { userData: location.state.userData } }); } useEffect(() => { - if (!location.state) { + if (!location.state || !location.state.userData) { history.push({ pathname: '/perfil' }) } + if (location.state && location.state.redirectData) { + const redirectData = location.state.redirectData + + if (redirectData.showToastMessage) { + setToastColor(redirectData.toastColor) + setToastMessage(redirectData.toastMessage) + setShowToast(true) + } + } + if (!location.state.userData.document) items[0].required = true if (!location.state.userData.phone_number) items[1].required = true }, []); @@ -103,6 +125,15 @@ const CadastroCompletar: React.FC = () => { ) })} + + setShowToast(false)} + message={toastMessage} + duration={2500} + /> ); diff --git a/src/pages/CadastroCompletar/CompletarDocumento.tsx b/src/pages/CadastroCompletar/CompletarDocumento.tsx index d1c7147..5fc9a8c 100644 --- a/src/pages/CadastroCompletar/CompletarDocumento.tsx +++ b/src/pages/CadastroCompletar/CompletarDocumento.tsx @@ -14,7 +14,7 @@ import { IonToast, IonToolbar } from "@ionic/react"; -import React, { useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import { IonGrid, IonRow, IonCol } from "@ionic/react"; import { useHistory, useLocation } from "react-router-dom"; import { @@ -33,8 +33,25 @@ interface documentTypesInterface { label: string; name: string; } + +interface userData { + name: string; + lastname: string; + email: string; + phone_number: string; + birth_date: string; + bio: string; + document_type: string; + document: string; +} + +interface LocationState { + userData: userData; +} const CompletarDocumento: React.FC = () => { + const location = useLocation(); + const [hasChangedSinceInitialState, setHasChangedSinceInitialState] = useState(false); const [documentTypes, setDocumentTypes] = useState([]); @@ -48,16 +65,8 @@ const CompletarDocumento: React.FC = () => { const [messageToast, setMessageToast] = useState(''); const history = useHistory(); - const location = useLocation(); - - useEffect(() => { - if (!location.state) { - history.push({ pathname: '/perfil/completar' }) - } - }, []) const validateform = () => { - console.log(document) if (isNaN((Number)(document))) { setMessageToast('Documento pode conter apenas números!') setShowToast(true) @@ -86,7 +95,13 @@ const CompletarDocumento: React.FC = () => { return } - console.log(response) + history.push({ pathname: '/perfil', state: { + redirectData: { + showToastMessage: true, + toastColor: "success", + toastMessage: response.message, + } + }}) }).catch((err) => { setMessageToast(err); setShowToast(true); @@ -111,6 +126,16 @@ const CompletarDocumento: React.FC = () => { } useEffect(() => { + if (!location.state.userData) { + history.push({ pathname: '/perfil', state: { + redirectData: { + showToastMessage: true, + toastColor: "warning", + toastMessage: "Houve um erro. Por favor, tente novamente.", + }, userData: location.state.userData + }}) + } + setDocumentTypes([ { name: 'cpf', @@ -178,11 +203,12 @@ const CompletarDocumento: React.FC = () => { setShowToast(false)} - message={messageToast} - duration={2500} + position="top" + color='danger' + isOpen={showToast} + onDidDismiss={() => setShowToast(false)} + message={messageToast} + duration={2500} /> diff --git a/src/pages/CadastroCompletar/CompletarTelefone.tsx b/src/pages/CadastroCompletar/CompletarTelefone.tsx index 6bccd65..f739146 100644 --- a/src/pages/CadastroCompletar/CompletarTelefone.tsx +++ b/src/pages/CadastroCompletar/CompletarTelefone.tsx @@ -8,13 +8,11 @@ import { IonIcon, IonList, IonPage, - IonSelect, - IonSelectOption, IonTitle, IonToast, IonToolbar } from "@ionic/react"; -import React, { useEffect, useState } from "react"; +import React, { useState, useEffect } from "react"; import { IonGrid, IonRow, IonCol } from "@ionic/react"; import { useHistory, useLocation } from "react-router-dom"; import { @@ -26,28 +24,40 @@ import { import { saveOutline } from "ionicons/icons"; import * as usersRoutes from '../../services/api/users'; +import { Color } from "@ionic/react/node_modules/@ionic/core"; interface documentTypesInterface { label: string; name: string; } - + +interface userData { + name: string; + lastname: string; + email: string; + phone_number: string; + birth_date: string; + bio: string; + document_type: string; + document: string; +} + +interface LocationState { + userData: userData; +} + const CompletarTelefone: React.FC = () => { + const location = useLocation(); + const [hasChangedSinceInitialState, setHasChangedSinceInitialState] = useState(false); const [phone, setPhone] = useState(''); const [showToast, setShowToast] = useState(false); const [messageToast, setMessageToast] = useState(''); + const [toastColor, setToastColor] = useState("primary"); const history = useHistory(); - const location = useLocation(); - - useEffect(() => { - if (!location.state) { - history.push({ pathname: '/perfil/completar' }) - } - }, []) const validateform = () => { if (isNaN((Number)(phone))) { @@ -66,19 +76,40 @@ const CompletarTelefone: React.FC = () => { usersRoutes.update({ phone_number: phone }).then(response => { if (response.status === 'error') { + setToastColor("warning") setMessageToast(response.message); setShowToast(true); return } - console.log(response) + const userDataObj = location.state.userData + + history.push({ pathname: '/perfil', state: { + redirectData: { + showToastMessage: true, + toastColor: "success", + toastMessage: response.message, + }, + }}) }).catch((err) => { setMessageToast(err); setShowToast(true); }) }; + useEffect(() => { + if (!location.state.userData) { + history.push({ pathname: '/perfil', state: { + redirectData: { + showToastMessage: true, + toastColor: "warning", + toastMessage: "Houve um erro. Por favor, tente novamente.", + } + }}) + } + }, []) + return ( @@ -122,11 +153,12 @@ const CompletarTelefone: React.FC = () => { setShowToast(false)} - message={messageToast} - duration={2500} + position="top" + color={toastColor} + isOpen={showToast} + onDidDismiss={() => setShowToast(false)} + message={messageToast} + duration={2500} /> diff --git a/src/pages/CadastroVan.tsx b/src/pages/CadastroVan.tsx index 7b592d3..aa080dd 100644 --- a/src/pages/CadastroVan.tsx +++ b/src/pages/CadastroVan.tsx @@ -19,6 +19,7 @@ import { } from "@ionic/react"; import React, { useEffect, useReducer, useState } from "react"; +import { useHistory } from "react-router-dom"; // import * as yup from 'yup'; @@ -27,10 +28,14 @@ import carsService from '../services/functions/carsService' import * as vansRoutes from '../services/api/vans'; import "./CadastroVan.css"; +import { Color } from "@ionic/react/node_modules/@ionic/core"; const CadastroVan: React.FC = () => { + const history = useHistory(); + const [showToast, setShowToast] = useState(false); const [toastMessage, setToastMessage] = useState(""); + const [toastColor, setToastColor] = useState("primary"); const [carModels, setCarModels] = useState([{ id_model: '', @@ -174,8 +179,15 @@ const CadastroVan: React.FC = () => { return } - console.log(response) + history.push({ pathname: '/perfil', state: { + redirectData: { + showToastMessage: true, + toastColor: "success", + toastMessage: response.message, + }, + }}) }).catch((err) => { + setToastColor("danger") setToastMessage(err); setShowToast(true); }) @@ -188,7 +200,9 @@ const CadastroVan: React.FC = () => { const carModelsRes = await carsService.getAllCarModels() if (carModelsRes.error) { - console.log('Houve um erro') + setToastColor("danger") + setToastMessage(carModelsRes.error.errorMessage); + setShowToast(true); return } @@ -333,6 +347,15 @@ const CadastroVan: React.FC = () => { duration={2500} /> + + setShowToast(false)} + message={toastMessage} + duration={2500} + /> ); }; diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index c3d74d6..1306fd4 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -1,17 +1,40 @@ -import { IonButton, IonContent, IonPage } from '@ionic/react'; -import { useContext, useEffect } from 'react'; -import { useHistory } from 'react-router'; +import { IonContent, IonPage, IonToast } from '@ionic/react'; +import { Color } from '@ionic/react/node_modules/@ionic/core'; +import { useContext, useEffect, useState } from 'react'; +import { useLocation } from 'react-router'; import { UserContext } from '../App'; import * as sessionRoutes from '../services/api/session'; +interface LocationState { + redirectData?: { + showToastMessage: boolean; + toastColor: Color; + toastMessage: string; + } +} + const Home: React.FC = () => { - const history = useHistory() + const location = useLocation(); const user = useContext(UserContext); + const [showToast, setShowToast] = useState(false); + const [toastMessage, setToastMessage] = useState(''); + const [toastColor, setToastColor] = useState("primary"); + useEffect(() => { + if (location.state && location.state.redirectData) { + const redirectData = location.state.redirectData + + if (redirectData.showToastMessage) { + setToastColor(redirectData.toastColor) + setToastMessage(redirectData.toastMessage) + setShowToast(true) + } + } + const refreshUserToken = async () => { await sessionRoutes.refresh().then(response => { if (response.status === 'error') { @@ -33,12 +56,19 @@ const Home: React.FC = () => { } refreshUserToken() - }) + }, []) return ( - {/* { history.push({ pathname: '/usuario/56520ae7-faf8-4444-a82b-7f3990ab02d8' }); }}>Ir para o perfil de outra pessoa */} + setShowToast(false)} + message={toastMessage} + duration={2500} + /> ); diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index afa8665..5e02cec 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -89,7 +89,11 @@ const Page: React.FC = () => { user.setIsLoggedIn(true); - history.push({ pathname: '/home' }); + history.push({ pathname: '/home', state: { redirectData: { + showToastMessage: true, + toastColor: "success", + toastMessage: "Usuário autenticado com sucesso!", + }}}) }).catch(error => { // if (!error.response) return @@ -155,7 +159,7 @@ const Page: React.FC = () => { setShowToast(false)} diff --git a/src/pages/Perfil.tsx b/src/pages/Perfil.tsx index cb4d126..7c88028 100644 --- a/src/pages/Perfil.tsx +++ b/src/pages/Perfil.tsx @@ -1,5 +1,6 @@ import { IonBackButton, + IonBadge, IonButtons, IonCard, IonCardContent, @@ -18,7 +19,7 @@ import { IonToast, IonToolbar, } from "@ionic/react"; -import { useHistory } from "react-router-dom"; +import { useHistory, useLocation } from "react-router-dom"; import React, { useState, useEffect, useReducer, useContext } from "react"; import { callOutline, cardOutline, carOutline, createOutline, exitOutline, logoFacebook, logoWhatsapp, shieldCheckmarkOutline, starOutline } from "ionicons/icons"; @@ -28,6 +29,7 @@ import LocalStorage from "../LocalStorage"; import sessionsService from '../services/functions/sessionsService' import usersService from '../services/functions/usersService' import { UserContext } from "../App"; +import { Color } from "@ionic/react/node_modules/@ionic/core"; interface ScanNewProps { match: { @@ -37,15 +39,28 @@ interface ScanNewProps { } } +interface LocationState { + redirectData?: { + showToastMessage: boolean; + toastColor: Color; + toastMessage: string; + } +} + const Perfil: React.FC = (props) => { const user = useContext(UserContext); + const history = useHistory(); + const location = useLocation(); + const [isVisitor, setIsVisitor] = useState(true) const [incompleteProfile, setIncompleteProfile] = useState(false) + const [incompleteProfileCounter, setIncompleteProfileCounter] = useState(0) const [showToast, setShowToast] = useState(false); - const [messageToast, setMessageToast] = useState(''); + const [toastMessage, setToastMessage] = useState(''); + const [toastColor, setToastColor] = useState("primary"); const [inputValues, setInputValues] = useReducer( (state: any, newState: any) => ({ ...state, ...newState }), @@ -62,12 +77,10 @@ const Perfil: React.FC = (props) => { } ); - const history = useHistory(); - 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!"); + setToastMessage("Por favor, autentique-se!"); setShowToast(true); } @@ -78,6 +91,16 @@ const Perfil: React.FC = (props) => { } useEffect(() => { + if (location.state && location.state.redirectData) { + const redirectData = location.state.redirectData + + if (redirectData.showToastMessage) { + setToastColor(redirectData.toastColor) + setToastMessage(redirectData.toastMessage) + setShowToast(true) + } + } + const loadUserData = async () => { let userId = '' @@ -102,11 +125,11 @@ const Perfil: React.FC = (props) => { if (getByIdRes.error) { if (isVisitor && props.match.params.id) { - setMessageToast('Usuário não existe!') + setToastMessage('Usuário não existe!') setShowToast(true) history.push({ pathname: '/home' }) } else { - setMessageToast(getByIdRes.error.errorMessage) + setToastMessage(getByIdRes.error.errorMessage) setShowToast(true) } @@ -135,6 +158,13 @@ const Perfil: React.FC = (props) => { if (!userData.document || !userData.phone_number) { setIncompleteProfile(true) + + let counter = 0 + + if (!userData.document) counter++ + if (!userData.phone_number) counter++ + + setIncompleteProfileCounter(counter) } } } @@ -173,8 +203,8 @@ const Perfil: React.FC = (props) => { - {/* avatar */} - avatar + avatar + {/* avatar */} {inputValues.name} {inputValues.lastname} @@ -232,6 +262,7 @@ const Perfil: React.FC = (props) => { history.push({ pathname: '/perfil/completar', state: { userData: inputValues } })}> Completar cadastro + {incompleteProfileCounter} : <> } @@ -256,10 +287,11 @@ const Perfil: React.FC = (props) => { } setShowToast(false)} - message={messageToast} + message={toastMessage} duration={2500} /> diff --git a/src/pages/PerfilEditar.tsx b/src/pages/PerfilEditar.tsx index 47271f0..a8a783a 100644 --- a/src/pages/PerfilEditar.tsx +++ b/src/pages/PerfilEditar.tsx @@ -28,6 +28,7 @@ import isEqual from 'lodash.isequal'; import * as usersRoutes from '../services/api/users'; import './Cadastro/Cadastro.css' +import { Color } from "@ionic/react/node_modules/@ionic/core"; interface userData { name: string; @@ -47,6 +48,7 @@ const PerfilEditar: React.FC = () => { const [showToast, setShowToast] = useState(false); const [messageToast, setMessageToast] = useState(''); + const [toastColor, setToastColor] = useState("primary"); const [userData, setUserData] = useState({ name: '', @@ -87,14 +89,18 @@ const PerfilEditar: React.FC = () => { const handleUpdateUserData = () => { usersRoutes.update(inputValues).then(response => { if (response.status === 'error') { + setToastColor("danger") setMessageToast(response.message); setShowToast(true); return } - console.log(response) + setToastColor("success") + setMessageToast(response.message); + setShowToast(true); }).catch((err) => { + setToastColor("danger") setMessageToast(err); setShowToast(true); }) @@ -176,7 +182,7 @@ const PerfilEditar: React.FC = () => { setShowToast(false)} message={messageToast} From c631bb91120214f331b5006b86ee8c1015e196ab Mon Sep 17 00:00:00 2001 From: Matheus Albino Brunhara Date: Mon, 20 Jun 2022 05:51:25 -0500 Subject: [PATCH 8/9] =?UTF-8?q?Corre=C3=A7=C3=A3o=20cadastro=20de=20vans?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/CadastroVan.tsx | 14 +++----------- src/services/api/vans.ts | 4 ++-- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/pages/CadastroVan.tsx b/src/pages/CadastroVan.tsx index aa080dd..7091ce7 100644 --- a/src/pages/CadastroVan.tsx +++ b/src/pages/CadastroVan.tsx @@ -340,22 +340,14 @@ const CadastroVan: React.FC = () => { setShowToast(false)} message={toastMessage} duration={2500} - /> - - - setShowToast(false)} - message={toastMessage} - duration={2500} /> + ); }; diff --git a/src/services/api/vans.ts b/src/services/api/vans.ts index f77b867..ec7c927 100644 --- a/src/services/api/vans.ts +++ b/src/services/api/vans.ts @@ -42,7 +42,7 @@ interface CreateVanBody { export async function create(CreateVanBody: CreateVanBody) { updateHeader(); - const response = await instance.post(vansRoutes.create.url, CreateVanBody); + const response = await instance.post(vansRoutes.create.url, CreateVanBody, { headers: header }); return response.data; } @@ -60,4 +60,4 @@ export async function update(vanData: UpdateVanBody) { }); return response.data; -} \ No newline at end of file +} From c6873625f59f67587b08a956f830ad056c9141a9 Mon Sep 17 00:00:00 2001 From: Matheus Albino Brunhara Date: Mon, 20 Jun 2022 06:10:16 -0500 Subject: [PATCH 9/9] =?UTF-8?q?Altera=C3=A7=C3=B5es=20e=20incluindo=20p?= =?UTF-8?q?=C3=A1gina=20Minhas=20Vans?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 2 + src/constants/routes/vansRoutes.ts | 7 +- src/pages/MinhasVans.tsx | 118 +++++++++++++++++++++++++++++ src/pages/Perfil.tsx | 5 +- src/pages/PerfilEditar.tsx | 10 ++- src/services/api/vans.ts | 14 +++- 6 files changed, 148 insertions(+), 8 deletions(-) create mode 100644 src/pages/MinhasVans.tsx diff --git a/src/App.tsx b/src/App.tsx index ee3dfae..2b012b6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -43,6 +43,7 @@ import './theme/variables.css'; import { search, home, person } from 'ionicons/icons'; import { useState, useContext } from 'react'; import React from 'react'; +import MinhasVans from './pages/MinhasVans'; setupIonicReact(); @@ -62,6 +63,7 @@ const routes = ( + diff --git a/src/constants/routes/vansRoutes.ts b/src/constants/routes/vansRoutes.ts index a4e241c..7bfcd2d 100644 --- a/src/constants/routes/vansRoutes.ts +++ b/src/constants/routes/vansRoutes.ts @@ -3,8 +3,11 @@ const vansRoutes = { list: { url: `${vansRoutesDefault}/list` }, - getById: { - url: `${vansRoutesDefault}/` + getByPlate: { + url: `${vansRoutesDefault}/plate` + }, + getByUserId: { + url: `${vansRoutesDefault}/user` }, create: { url: `${vansRoutesDefault}/` diff --git a/src/pages/MinhasVans.tsx b/src/pages/MinhasVans.tsx new file mode 100644 index 0000000..904478c --- /dev/null +++ b/src/pages/MinhasVans.tsx @@ -0,0 +1,118 @@ +import { IonBackButton, IonButtons, IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonContent, IonHeader, IonIcon, IonItem, IonLabel, IonPage, IonTitle, IonToast, IonToolbar } from '@ionic/react'; +import { Color } from '@ionic/react/node_modules/@ionic/core'; +import { carOutline } from 'ionicons/icons'; +import { useContext, useEffect, useState } from 'react'; +import { useHistory, useLocation } from 'react-router'; + +import { UserContext } from '../App'; + +import * as vansRoutes from '../services/api/vans'; + +import sessionsService from '../services/functions/sessionsService' + +interface VanInfo { + plate: string; + brand: string; + model: string; + seats_number: string; + document_status: boolean, + locator_name: string; + locator_address: string; + locator_complement: string; + locator_city: string; + locator_state: string; +} + +const MinhasVans: React.FC = () => { + const history = useHistory(); + + const [showToast, setShowToast] = useState(false); + const [toastMessage, setToastMessage] = useState(''); + const [toastColor, setToastColor] = useState("primary"); + + const [userVans, setUserVans] = useState(); + + const redirectUserToLogin = () => { + history.push({ pathname: '/login' }); + } + + useEffect(() => { + const getUserVans = async () => { + let userId = '' + + const refreshSessionRes = await sessionsService.refreshSession() + + if (refreshSessionRes.error) { + redirectUserToLogin() + return + } + + if (refreshSessionRes.userId) { + userId = refreshSessionRes.userId + } + + vansRoutes.getByUserId(userId).then(response => { + if (response.status === 'error') { + setToastColor("danger") + setToastMessage(response.message); + setShowToast(true); + + return + } + + setUserVans(response.data) + }).catch((err) => { + setToastColor("danger") + setToastMessage(err); + setShowToast(true); + }) + } + + getUserVans() + }, []) + + return ( + + + + Minhas vans + + + + + + + + { userVans ? userVans.map((van, index) => { + return ( + + + {van.plate} + {van.brand} - {van.model} + + { van.locator_name ? + <> + {van.seats_number} assentos - Locador: {van.locator_name} + : + <> + {van.seats_number} assentos - Não é alugado + + } + + ) + }) : <>} + + setShowToast(false)} + message={toastMessage} + duration={2500} + /> + + + ); +}; + +export default MinhasVans; diff --git a/src/pages/Perfil.tsx b/src/pages/Perfil.tsx index 7c88028..1a4cb0c 100644 --- a/src/pages/Perfil.tsx +++ b/src/pages/Perfil.tsx @@ -78,7 +78,6 @@ const Perfil: React.FC = (props) => { ); const redirectUserToLogin = () => { - // TODO, não impede o usuário de retornar a página de login history.push({ pathname: '/login' }); setToastMessage("Por favor, autentique-se!"); setShowToast(true); @@ -271,6 +270,10 @@ const Perfil: React.FC = (props) => { Cadastrar Van + history.push({ pathname: '/minhas-vans'})}> + + Minhas Vans + Pagamentos diff --git a/src/pages/PerfilEditar.tsx b/src/pages/PerfilEditar.tsx index a8a783a..d3fa677 100644 --- a/src/pages/PerfilEditar.tsx +++ b/src/pages/PerfilEditar.tsx @@ -96,9 +96,13 @@ const PerfilEditar: React.FC = () => { return } - setToastColor("success") - setMessageToast(response.message); - setShowToast(true); + history.push({ pathname: '/perfil', state: { + redirectData: { + showToastMessage: true, + toastColor: "success", + toastMessage: response.message, + }, + }}) }).catch((err) => { setToastColor("danger") setMessageToast(err); diff --git a/src/services/api/vans.ts b/src/services/api/vans.ts index ec7c927..f4b5fd3 100644 --- a/src/services/api/vans.ts +++ b/src/services/api/vans.ts @@ -17,10 +17,20 @@ function updateHeader() { }; } -export async function getById(vanId: string) { +export async function getByPlate(vanId: string) { updateHeader(); - const response = await instance.get(vansRoutes.getById.url + `/${vanId}`, { + const response = await instance.get(vansRoutes.getByPlate.url + `/${vanId}`, { + headers: header, + }); + + return response.data; +} + +export async function getByUserId(userId: string) { + updateHeader(); + + const response = await instance.get(vansRoutes.getByUserId.url + `/${userId}`, { headers: header, });