Merge pull request #6 from CloudAlb/feature/completar-cadastro
Feature/completar cadastro e muitas outras correções, alterações e melhorias
This commit is contained in:
12
src/App.tsx
12
src/App.tsx
@@ -17,8 +17,10 @@ import Login from './pages/Login';
|
|||||||
import Home from './pages/Home';
|
import Home from './pages/Home';
|
||||||
import Perfil from './pages/Perfil';
|
import Perfil from './pages/Perfil';
|
||||||
import PerfilEditar from './pages/PerfilEditar';
|
import PerfilEditar from './pages/PerfilEditar';
|
||||||
import CadastroCompletar from './pages/CadastroCompletar';
|
|
||||||
import CadastroVan from './pages/CadastroVan';
|
import CadastroVan from './pages/CadastroVan';
|
||||||
|
import CadastroCompletar from './pages/CadastroCompletar/CadastroCompletar';
|
||||||
|
import CompletarDocumento from './pages/CadastroCompletar/CompletarDocumento';
|
||||||
|
import CompletarTelefone from './pages/CadastroCompletar/CompletarTelefone';
|
||||||
|
|
||||||
/* Core CSS required for Ionic components to work properly */
|
/* Core CSS required for Ionic components to work properly */
|
||||||
import '@ionic/react/css/core.css';
|
import '@ionic/react/css/core.css';
|
||||||
@@ -41,6 +43,7 @@ import './theme/variables.css';
|
|||||||
import { search, home, person } from 'ionicons/icons';
|
import { search, home, person } from 'ionicons/icons';
|
||||||
import { useState, useContext } from 'react';
|
import { useState, useContext } from 'react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import MinhasVans from './pages/MinhasVans';
|
||||||
|
|
||||||
setupIonicReact();
|
setupIonicReact();
|
||||||
|
|
||||||
@@ -48,12 +51,19 @@ const routes = (
|
|||||||
<>
|
<>
|
||||||
<Route exact path="/cadastro" component={Cadastro}></Route>
|
<Route exact path="/cadastro" component={Cadastro}></Route>
|
||||||
<Route exact path="/login" component={Login}></Route>
|
<Route exact path="/login" component={Login}></Route>
|
||||||
|
|
||||||
<Route exact path="/home" component={Home}></Route>
|
<Route exact path="/home" component={Home}></Route>
|
||||||
|
|
||||||
<Route exact path="/perfil" component={Perfil}></Route>
|
<Route exact path="/perfil" component={Perfil}></Route>
|
||||||
<Route exact path="/perfil/editar" component={PerfilEditar}></Route>
|
<Route exact path="/perfil/editar" component={PerfilEditar}></Route>
|
||||||
<Route exact path="/perfil/completar" component={CadastroCompletar}></Route>
|
<Route exact path="/perfil/completar" component={CadastroCompletar}></Route>
|
||||||
|
<Route exact path="/perfil/completar/documento" component={CompletarDocumento}></Route>
|
||||||
|
<Route exact path="/perfil/completar/telefone" component={CompletarTelefone}></Route>
|
||||||
|
|
||||||
<Route exact path="/usuario/:id" component={Perfil}></Route>
|
<Route exact path="/usuario/:id" component={Perfil}></Route>
|
||||||
|
|
||||||
<Route exact path="/cadastro-van" component={CadastroVan}></Route>
|
<Route exact path="/cadastro-van" component={CadastroVan}></Route>
|
||||||
|
<Route exact path="/minhas-vans" component={MinhasVans}></Route>
|
||||||
<Route exact path="/">
|
<Route exact path="/">
|
||||||
<Redirect to="/login" />
|
<Redirect to="/login" />
|
||||||
</Route>
|
</Route>
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ const usersRoutes = {
|
|||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
url: `${usersRoutesDefault}/edit`
|
url: `${usersRoutesDefault}/edit`
|
||||||
|
},
|
||||||
|
getSocialInfo: {
|
||||||
|
url: `${usersRoutesDefault}/social`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
17
src/constants/routes/vansLocatorsRoutes.ts
Normal file
17
src/constants/routes/vansLocatorsRoutes.ts
Normal file
@@ -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;
|
||||||
20
src/constants/routes/vansRoutes.ts
Normal file
20
src/constants/routes/vansRoutes.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
const vansRoutesDefault = '/vans';
|
||||||
|
const vansRoutes = {
|
||||||
|
list: {
|
||||||
|
url: `${vansRoutesDefault}/list`
|
||||||
|
},
|
||||||
|
getByPlate: {
|
||||||
|
url: `${vansRoutesDefault}/plate`
|
||||||
|
},
|
||||||
|
getByUserId: {
|
||||||
|
url: `${vansRoutesDefault}/user`
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
url: `${vansRoutesDefault}/`
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
url: `${vansRoutesDefault}/`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default vansRoutes;
|
||||||
@@ -1,17 +1,23 @@
|
|||||||
import { IonToast, IonProgressBar, IonItem, IonLabel, IonInput, IonBackButton, IonButton, IonButtons, IonCardTitle, IonCol, IonContent, IonGrid, IonHeader, IonPage, IonRow, IonToolbar } from '@ionic/react';
|
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 { arrowBack, logoFacebook, mail } from 'ionicons/icons';
|
||||||
import { Action } from '../../components/Action';
|
import { Action } from '../../components/Action';
|
||||||
import { useEffect, useState } from 'react';
|
import { useContext, useEffect, useState } from 'react';
|
||||||
import { useHistory, useParams } from 'react-router';
|
import { useHistory, useParams } from 'react-router';
|
||||||
import './Cadastro.css';
|
import './Cadastro.css';
|
||||||
import ModalExample from '../../components/Email';
|
import ModalExample from '../../components/Email';
|
||||||
import * as UsersService from '../../services/api/users'
|
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 Cadastro: React.FC = () => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
|
const user = useContext(UserContext);
|
||||||
|
|
||||||
const [showToast, setShowToast] = useState(false);
|
const [showToast, setShowToast] = useState(false);
|
||||||
const [messageToast, setMessageToast ] = useState('');
|
const [messageToast, setMessageToast] = useState('');
|
||||||
|
const [toastColor, setToastColor] = useState<Color>("primary");
|
||||||
|
|
||||||
const [email, setEmail] = useState<string>('');
|
const [email, setEmail] = useState<string>('');
|
||||||
const [password, setPassword] = useState<string>('');
|
const [password, setPassword] = useState<string>('');
|
||||||
@@ -53,7 +59,7 @@ const Cadastro: React.FC = () => {
|
|||||||
clearResult();
|
clearResult();
|
||||||
|
|
||||||
if(!emailValidate()) {
|
if(!emailValidate()) {
|
||||||
lResult.error = 'O EMAIL é inválido!';
|
lResult.error = 'E-mail inválido!';
|
||||||
lResult.success = false;
|
lResult.success = false;
|
||||||
return lResult;
|
return lResult;
|
||||||
} else if(password.length < 7 || password.length > 12) { //TODO: validar de acordo com a documentação
|
} else if(password.length < 7 || password.length > 12) { //TODO: validar de acordo com a documentação
|
||||||
@@ -66,45 +72,56 @@ const Cadastro: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
|
if(name === '' || email === '' || birthDate === '' || password === '' || confirmPassword === '') {
|
||||||
if(name != '' && email != '' && birthDate != '' && password != '' && confirmPassword != '') {
|
setToastColor("warning")
|
||||||
if(password === confirmPassword){
|
setMessageToast('Nenhum campo pode estar vazio!');
|
||||||
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);
|
|
||||||
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!');
|
|
||||||
setShowToast(true);
|
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; }>();
|
const { name } = useParams<{ name: string; }>();
|
||||||
@@ -121,19 +138,11 @@ const Cadastro: React.FC = () => {
|
|||||||
<IonContent fullscreen>
|
<IonContent fullscreen>
|
||||||
<IonGrid className="ion-padding">
|
<IonGrid className="ion-padding">
|
||||||
<IonRow>
|
<IonRow>
|
||||||
<IonCol size="12">
|
<IonCol size="12">
|
||||||
{/* <IonCardTitle>Como você deseja se cadastrar?</IonCardTitle> */}
|
{/* <IonCardTitle>Como você deseja se cadastrar?</IonCardTitle> */}
|
||||||
<IonCardTitle>Cadastro</IonCardTitle>
|
<IonCardTitle>Cadastro</IonCardTitle>
|
||||||
</IonCol>
|
</IonCol>
|
||||||
</IonRow>
|
</IonRow>
|
||||||
{/* <IonItem>
|
|
||||||
<IonIcon icon={logoFacebook} />
|
|
||||||
Continuar com Facebook
|
|
||||||
</IonItem>
|
|
||||||
<IonItem>
|
|
||||||
<IonIcon icon={mail} />
|
|
||||||
Continuar com e-mail
|
|
||||||
</IonItem> */}
|
|
||||||
<IonRow>
|
<IonRow>
|
||||||
<IonCol size="12">
|
<IonCol size="12">
|
||||||
<div id='nome-sobrenome'>
|
<div id='nome-sobrenome'>
|
||||||
@@ -142,7 +151,7 @@ const Cadastro: React.FC = () => {
|
|||||||
<IonInput
|
<IonInput
|
||||||
type='text'
|
type='text'
|
||||||
clearInput
|
clearInput
|
||||||
onIonInput={(e: any) => setFirstName(e.target.value)}
|
onIonChange={(e: any) => setFirstName(e.target.value)}
|
||||||
>
|
>
|
||||||
</IonInput>
|
</IonInput>
|
||||||
</IonItem>
|
</IonItem>
|
||||||
@@ -150,7 +159,7 @@ const Cadastro: React.FC = () => {
|
|||||||
<IonLabel position='floating'>Sobrenome</IonLabel>
|
<IonLabel position='floating'>Sobrenome</IonLabel>
|
||||||
<IonInput
|
<IonInput
|
||||||
clearInput
|
clearInput
|
||||||
onIonInput={(e: any) => setLastName(e.target.value)}
|
onIonChange={(e: any) => setLastName(e.target.value)}
|
||||||
>
|
>
|
||||||
</IonInput>
|
</IonInput>
|
||||||
</IonItem>
|
</IonItem>
|
||||||
@@ -161,7 +170,7 @@ const Cadastro: React.FC = () => {
|
|||||||
<IonInput
|
<IonInput
|
||||||
clearInput
|
clearInput
|
||||||
type='email'
|
type='email'
|
||||||
onIonInput={(e: any) => setEmail(e.target.value)}
|
onIonChange={(e: any) => setEmail(e.target.value)}
|
||||||
>
|
>
|
||||||
</IonInput>
|
</IonInput>
|
||||||
</IonItem>
|
</IonItem>
|
||||||
@@ -170,7 +179,7 @@ const Cadastro: React.FC = () => {
|
|||||||
<IonLabel position='stacked'>Data de nascimento</IonLabel>
|
<IonLabel position='stacked'>Data de nascimento</IonLabel>
|
||||||
<IonInput
|
<IonInput
|
||||||
type='date'
|
type='date'
|
||||||
onIonInput={(e: any) => setBirthDate(e.target.value)}
|
onIonChange={(e: any) => setBirthDate(e.target.value)}
|
||||||
>
|
>
|
||||||
</IonInput>
|
</IonInput>
|
||||||
</IonItem>
|
</IonItem>
|
||||||
@@ -180,7 +189,7 @@ const Cadastro: React.FC = () => {
|
|||||||
<IonInput
|
<IonInput
|
||||||
clearInput
|
clearInput
|
||||||
type='password'
|
type='password'
|
||||||
onIonInput={(e: any) => setPassword(e.target.value)}
|
onIonChange={(e: any) => setPassword(e.target.value)}
|
||||||
></IonInput>
|
></IonInput>
|
||||||
</IonItem>
|
</IonItem>
|
||||||
<IonItem>
|
<IonItem>
|
||||||
@@ -188,7 +197,7 @@ const Cadastro: React.FC = () => {
|
|||||||
<IonInput
|
<IonInput
|
||||||
clearInput
|
clearInput
|
||||||
type='password'
|
type='password'
|
||||||
onIonInput={(e: any) => setConfirmPassword(e.target.value)}
|
onIonChange={(e: any) => setConfirmPassword(e.target.value)}
|
||||||
></IonInput>
|
></IonInput>
|
||||||
</IonItem>
|
</IonItem>
|
||||||
|
|
||||||
@@ -201,9 +210,9 @@ const Cadastro: React.FC = () => {
|
|||||||
<Action message="Já tem conta?" text="Login" link="/login" />
|
<Action message="Já tem conta?" text="Login" link="/login" />
|
||||||
</IonGrid>
|
</IonGrid>
|
||||||
{/* <IonProgressBar type="indeterminate"></IonProgressBar><br /> */}
|
{/* <IonProgressBar type="indeterminate"></IonProgressBar><br /> */}
|
||||||
|
|
||||||
<IonToast
|
<IonToast
|
||||||
// cssClass={"toast-notification"}
|
color={toastColor}
|
||||||
color='danger'
|
|
||||||
isOpen={showToast}
|
isOpen={showToast}
|
||||||
onDidDismiss={() => setShowToast(false)}
|
onDidDismiss={() => setShowToast(false)}
|
||||||
message={messageToast}
|
message={messageToast}
|
||||||
|
|||||||
@@ -1,149 +0,0 @@
|
|||||||
import {
|
|
||||||
IonBackButton,
|
|
||||||
IonButton,
|
|
||||||
IonButtons,
|
|
||||||
IonCard,
|
|
||||||
IonCardContent,
|
|
||||||
IonContent,
|
|
||||||
IonHeader,
|
|
||||||
IonIcon,
|
|
||||||
IonItem,
|
|
||||||
IonLabel,
|
|
||||||
IonPage,
|
|
||||||
IonTitle,
|
|
||||||
IonToolbar
|
|
||||||
} from "@ionic/react";
|
|
||||||
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 * as usersRoutes from '../services/api/users';
|
|
||||||
|
|
||||||
import './Cadastro/Cadastro.css'
|
|
||||||
|
|
||||||
interface userData {
|
|
||||||
name: string;
|
|
||||||
lastname: string;
|
|
||||||
email: string;
|
|
||||||
birth_date: string;
|
|
||||||
bio: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface LocationState {
|
|
||||||
userData: userData
|
|
||||||
}
|
|
||||||
|
|
||||||
const items = [
|
|
||||||
// TODO, CPF e CNH
|
|
||||||
{
|
|
||||||
icon: documentTextOutline,
|
|
||||||
label: 'Documentos',
|
|
||||||
description: 'Cadastre seus documentos para que seu perfil possa ser verificado.'
|
|
||||||
},
|
|
||||||
// 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.'
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
const CadastroCompletar: React.FC = () => {
|
|
||||||
const history = useHistory();
|
|
||||||
const location = useLocation<LocationState>();
|
|
||||||
|
|
||||||
const [showToast, setShowToast] = useState(false);
|
|
||||||
const [messageToast, setMessageToast] = useState('');
|
|
||||||
|
|
||||||
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: '',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let userData = location.state.userData
|
|
||||||
|
|
||||||
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);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<IonPage>
|
|
||||||
<IonHeader>
|
|
||||||
<IonToolbar>
|
|
||||||
<IonTitle>Completar cadastro</IonTitle>
|
|
||||||
<IonButtons slot="start">
|
|
||||||
<IonBackButton defaultHref="/perfil" />
|
|
||||||
</IonButtons>
|
|
||||||
</IonToolbar>
|
|
||||||
</IonHeader>
|
|
||||||
|
|
||||||
<IonContent>
|
|
||||||
{ items.map((item, index) => {
|
|
||||||
return (
|
|
||||||
<IonCard button key={index}>
|
|
||||||
<IonItem>
|
|
||||||
<IonIcon icon={item.icon} slot="start" />
|
|
||||||
<IonLabel>{item.label}</IonLabel>
|
|
||||||
</IonItem>
|
|
||||||
|
|
||||||
<IonCardContent>{item.description}</IonCardContent>
|
|
||||||
</IonCard>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</IonContent>
|
|
||||||
</IonPage>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default CadastroCompletar;
|
|
||||||
142
src/pages/CadastroCompletar/CadastroCompletar.tsx
Normal file
142
src/pages/CadastroCompletar/CadastroCompletar.tsx
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
import {
|
||||||
|
IonBackButton,
|
||||||
|
IonButtons,
|
||||||
|
IonCard,
|
||||||
|
IonCardContent,
|
||||||
|
IonContent,
|
||||||
|
IonHeader,
|
||||||
|
IonIcon,
|
||||||
|
IonItem,
|
||||||
|
IonLabel,
|
||||||
|
IonPage,
|
||||||
|
IonTitle,
|
||||||
|
IonToast,
|
||||||
|
IonToolbar
|
||||||
|
} from "@ionic/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;
|
||||||
|
lastname: string;
|
||||||
|
email: string;
|
||||||
|
phone_number: string;
|
||||||
|
birth_date: string;
|
||||||
|
bio: string;
|
||||||
|
document_type: string;
|
||||||
|
document: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LocationState {
|
||||||
|
userData: userData;
|
||||||
|
|
||||||
|
redirectData?: {
|
||||||
|
showToastMessage: boolean;
|
||||||
|
toastColor: Color;
|
||||||
|
toastMessage: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let items: cardItem[] = [
|
||||||
|
{
|
||||||
|
icon: documentTextOutline,
|
||||||
|
label: 'Documento',
|
||||||
|
description: 'Cadastre seu documento para que seu perfil possa ser verificado',
|
||||||
|
url: '/perfil/completar/documento',
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: callOutline,
|
||||||
|
label: 'Informações de contato',
|
||||||
|
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<LocationState>();
|
||||||
|
|
||||||
|
const [showToast, setShowToast] = useState(false);
|
||||||
|
const [toastMessage, setToastMessage] = useState('');
|
||||||
|
const [toastColor, setToastColor] = useState<Color>("primary");
|
||||||
|
|
||||||
|
const handleCardClick = (item: cardItem) => {
|
||||||
|
if (!item.required) return
|
||||||
|
|
||||||
|
history.push({ pathname: item.url, state: { userData: location.state.userData } });
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
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
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IonPage>
|
||||||
|
<IonHeader>
|
||||||
|
<IonToolbar>
|
||||||
|
<IonTitle>Completar cadastro</IonTitle>
|
||||||
|
<IonButtons slot="start">
|
||||||
|
<IonBackButton defaultHref="/perfil" />
|
||||||
|
</IonButtons>
|
||||||
|
</IonToolbar>
|
||||||
|
</IonHeader>
|
||||||
|
|
||||||
|
<IonContent>
|
||||||
|
{ items.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<IonCard button={item.required} key={index} onClick={() => { handleCardClick(item) }}>
|
||||||
|
<IonItem>
|
||||||
|
<IonIcon icon={item.icon} slot="start" />
|
||||||
|
<IonLabel>{item.label}</IonLabel>
|
||||||
|
</IonItem>
|
||||||
|
|
||||||
|
<IonCardContent>{item.description}</IonCardContent>
|
||||||
|
</IonCard>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
|
||||||
|
<IonToast
|
||||||
|
position="top"
|
||||||
|
color={toastColor}
|
||||||
|
isOpen={showToast}
|
||||||
|
onDidDismiss={() => setShowToast(false)}
|
||||||
|
message={toastMessage}
|
||||||
|
duration={2500}
|
||||||
|
/>
|
||||||
|
</IonContent>
|
||||||
|
</IonPage>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CadastroCompletar;
|
||||||
219
src/pages/CadastroCompletar/CompletarDocumento.tsx
Normal file
219
src/pages/CadastroCompletar/CompletarDocumento.tsx
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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<LocationState>();
|
||||||
|
|
||||||
|
const [hasChangedSinceInitialState, setHasChangedSinceInitialState] = useState(false);
|
||||||
|
|
||||||
|
const [documentTypes, setDocumentTypes] = useState<documentTypesInterface[]>([]);
|
||||||
|
|
||||||
|
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 validateform = () => {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
history.push({ pathname: '/perfil', state: {
|
||||||
|
redirectData: {
|
||||||
|
showToastMessage: true,
|
||||||
|
toastColor: "success",
|
||||||
|
toastMessage: response.message,
|
||||||
|
}
|
||||||
|
}})
|
||||||
|
}).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(() => {
|
||||||
|
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',
|
||||||
|
label: 'CPF',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'rg',
|
||||||
|
label: 'RG',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cnh',
|
||||||
|
label: 'CNH',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IonPage>
|
||||||
|
<IonHeader>
|
||||||
|
<IonToolbar>
|
||||||
|
<IonTitle>Completar cadastro</IonTitle>
|
||||||
|
<IonButtons slot="start">
|
||||||
|
<IonBackButton defaultHref="/perfil/completar" />
|
||||||
|
</IonButtons>
|
||||||
|
</IonToolbar>
|
||||||
|
</IonHeader>
|
||||||
|
|
||||||
|
<IonContent fullscreen>
|
||||||
|
<IonHeader collapse="condense">
|
||||||
|
<IonToolbar>
|
||||||
|
<IonTitle size="large">Completar cadastro</IonTitle>
|
||||||
|
</IonToolbar>
|
||||||
|
</IonHeader>
|
||||||
|
|
||||||
|
<IonGrid>
|
||||||
|
<IonRow>
|
||||||
|
<IonCol>
|
||||||
|
<IonList lines="full" class="ion-no-margin">
|
||||||
|
<IonItem>
|
||||||
|
<IonLabel position="floating"> Tipo de documento</IonLabel>
|
||||||
|
<IonSelect id="document_type" onIonChange={(e: any) => { handleChangeDocumentType(e.detail.value) } }>
|
||||||
|
{ documentTypes ? documentTypes.map((document, index) => {
|
||||||
|
return (<IonSelectOption key={index} value={document.name}>{document.label}</IonSelectOption>)
|
||||||
|
}) : <></> }
|
||||||
|
</IonSelect>
|
||||||
|
</IonItem>
|
||||||
|
<IonItem>
|
||||||
|
<IonLabel position="floating"> Documento</IonLabel>
|
||||||
|
<IonInput
|
||||||
|
type="text"
|
||||||
|
value={document}
|
||||||
|
maxlength={documentMaxLength}
|
||||||
|
onIonChange={(e: any) => { setDocument(e.target.value); setHasChangedSinceInitialState(true) }}
|
||||||
|
></IonInput>
|
||||||
|
</IonItem>
|
||||||
|
</IonList>
|
||||||
|
</IonCol>
|
||||||
|
</IonRow>
|
||||||
|
</IonGrid>
|
||||||
|
|
||||||
|
<IonFab vertical="bottom" horizontal="end" slot="fixed">
|
||||||
|
<IonFabButton disabled={!hasChangedSinceInitialState} onClick={handleUpdateUserDocuments}>
|
||||||
|
<IonIcon icon={saveOutline} />
|
||||||
|
</IonFabButton>
|
||||||
|
</IonFab>
|
||||||
|
|
||||||
|
<IonToast
|
||||||
|
position="top"
|
||||||
|
color='danger'
|
||||||
|
isOpen={showToast}
|
||||||
|
onDidDismiss={() => setShowToast(false)}
|
||||||
|
message={messageToast}
|
||||||
|
duration={2500}
|
||||||
|
/>
|
||||||
|
</IonContent>
|
||||||
|
</IonPage>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CompletarDocumento;
|
||||||
|
|
||||||
169
src/pages/CadastroCompletar/CompletarTelefone.tsx
Normal file
169
src/pages/CadastroCompletar/CompletarTelefone.tsx
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
import {
|
||||||
|
IonBackButton,
|
||||||
|
IonButtons,
|
||||||
|
IonContent,
|
||||||
|
IonFab,
|
||||||
|
IonFabButton,
|
||||||
|
IonHeader,
|
||||||
|
IonIcon,
|
||||||
|
IonList,
|
||||||
|
IonPage,
|
||||||
|
IonTitle,
|
||||||
|
IonToast,
|
||||||
|
IonToolbar
|
||||||
|
} from "@ionic/react";
|
||||||
|
import React, { useState, useEffect } 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 { 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<LocationState>();
|
||||||
|
|
||||||
|
const [hasChangedSinceInitialState, setHasChangedSinceInitialState] = useState(false);
|
||||||
|
|
||||||
|
const [phone, setPhone] = useState('');
|
||||||
|
|
||||||
|
const [showToast, setShowToast] = useState(false);
|
||||||
|
const [messageToast, setMessageToast] = useState('');
|
||||||
|
const [toastColor, setToastColor] = useState<Color>("primary");
|
||||||
|
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
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') {
|
||||||
|
setToastColor("warning")
|
||||||
|
setMessageToast(response.message);
|
||||||
|
setShowToast(true);
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<IonPage>
|
||||||
|
<IonHeader>
|
||||||
|
<IonToolbar>
|
||||||
|
<IonTitle>Completar cadastro</IonTitle>
|
||||||
|
<IonButtons slot="start">
|
||||||
|
<IonBackButton defaultHref="/perfil/completar" />
|
||||||
|
</IonButtons>
|
||||||
|
</IonToolbar>
|
||||||
|
</IonHeader>
|
||||||
|
|
||||||
|
<IonContent fullscreen>
|
||||||
|
<IonHeader collapse="condense">
|
||||||
|
<IonToolbar>
|
||||||
|
<IonTitle size="large">Completar cadastro</IonTitle>
|
||||||
|
</IonToolbar>
|
||||||
|
</IonHeader>
|
||||||
|
|
||||||
|
<IonGrid>
|
||||||
|
<IonRow>
|
||||||
|
<IonCol>
|
||||||
|
<IonList lines="full" class="ion-no-margin">
|
||||||
|
<IonItem>
|
||||||
|
<IonLabel position="floating"> Telefone</IonLabel>
|
||||||
|
<IonInput
|
||||||
|
type="text"
|
||||||
|
value={phone}
|
||||||
|
maxlength={11}
|
||||||
|
onIonChange={(e: any) => { setPhone(e.target.value); setHasChangedSinceInitialState(true) }}
|
||||||
|
></IonInput>
|
||||||
|
</IonItem>
|
||||||
|
</IonList>
|
||||||
|
</IonCol>
|
||||||
|
</IonRow>
|
||||||
|
</IonGrid>
|
||||||
|
|
||||||
|
<IonFab vertical="bottom" horizontal="end" slot="fixed">
|
||||||
|
<IonFabButton disabled={!hasChangedSinceInitialState} onClick={handleUpdateUserDocuments}>
|
||||||
|
<IonIcon icon={saveOutline} />
|
||||||
|
</IonFabButton>
|
||||||
|
</IonFab>
|
||||||
|
|
||||||
|
<IonToast
|
||||||
|
position="top"
|
||||||
|
color={toastColor}
|
||||||
|
isOpen={showToast}
|
||||||
|
onDidDismiss={() => setShowToast(false)}
|
||||||
|
message={messageToast}
|
||||||
|
duration={2500}
|
||||||
|
/>
|
||||||
|
</IonContent>
|
||||||
|
</IonPage>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CompletarTelefone;
|
||||||
|
|
||||||
@@ -19,18 +19,23 @@ import {
|
|||||||
} from "@ionic/react";
|
} from "@ionic/react";
|
||||||
|
|
||||||
import React, { useEffect, useReducer, useState } from "react";
|
import React, { useEffect, useReducer, useState } from "react";
|
||||||
|
import { useHistory } from "react-router-dom";
|
||||||
|
|
||||||
import * as yup from 'yup';
|
// import * as yup from 'yup';
|
||||||
|
|
||||||
import { ApiClient } from "../services/api-client.service";
|
|
||||||
|
|
||||||
import carsService from '../services/functions/carsService'
|
import carsService from '../services/functions/carsService'
|
||||||
|
|
||||||
|
import * as vansRoutes from '../services/api/vans';
|
||||||
|
|
||||||
import "./CadastroVan.css";
|
import "./CadastroVan.css";
|
||||||
|
import { Color } from "@ionic/react/node_modules/@ionic/core";
|
||||||
|
|
||||||
const CadastroVan: React.FC = () => {
|
const CadastroVan: React.FC = () => {
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
const [showToast, setShowToast] = useState<boolean>(false);
|
const [showToast, setShowToast] = useState<boolean>(false);
|
||||||
const [toastMessage, setToastMessage] = useState<string>("");
|
const [toastMessage, setToastMessage] = useState<string>("");
|
||||||
|
const [toastColor, setToastColor] = useState<Color>("primary");
|
||||||
|
|
||||||
const [carModels, setCarModels] = useState([{
|
const [carModels, setCarModels] = useState([{
|
||||||
id_model: '',
|
id_model: '',
|
||||||
@@ -43,77 +48,34 @@ const CadastroVan: React.FC = () => {
|
|||||||
carPlate: '',
|
carPlate: '',
|
||||||
carBrand: '',
|
carBrand: '',
|
||||||
carModel: '',
|
carModel: '',
|
||||||
maxPassengers: 1,
|
seats_number: 1,
|
||||||
isRent: false,
|
isRented: false,
|
||||||
carRentalName: '',
|
locator_name: '',
|
||||||
postalCode: '',
|
locator_address: '',
|
||||||
street: '',
|
locator_complement: '',
|
||||||
number: '',
|
locator_city: '',
|
||||||
complement: '',
|
locator_state: '',
|
||||||
city: '',
|
|
||||||
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 = () => {
|
const clearRentalData = () => {
|
||||||
setInputValues({
|
setInputValues({
|
||||||
carPlate: '',
|
carRentalName: '',
|
||||||
carBrand: '',
|
complement: '',
|
||||||
carModel: '',
|
city: '',
|
||||||
maxPassengers: 1,
|
state: '',
|
||||||
isRent: false,
|
|
||||||
carRentalName: '',
|
|
||||||
postalCode: '',
|
|
||||||
street: '',
|
|
||||||
number: '',
|
|
||||||
complement: '',
|
|
||||||
city: '',
|
|
||||||
state: '',
|
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateForm = (): boolean => {
|
const validateForm = (): boolean => {
|
||||||
|
const vanForm = {
|
||||||
|
carPlate: inputValues.carPlate,
|
||||||
|
carBrand: inputValues.carBrand,
|
||||||
|
carModel: inputValues.carModel,
|
||||||
|
seats_number: inputValues.seats_number,
|
||||||
|
isRented: inputValues.isRented,
|
||||||
|
};
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!vanForm.carPlate ||
|
!vanForm.carPlate ||
|
||||||
vanForm.carPlate.length !== 7 ||
|
vanForm.carPlate.length !== 7 ||
|
||||||
@@ -136,12 +98,18 @@ const CadastroVan: React.FC = () => {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vanForm.maxPassengers || !parseInt(`${vanForm.maxPassengers}`)) {
|
if (!vanForm.seats_number || !parseInt(`${vanForm.seats_number}`)) {
|
||||||
setToastMessage("Número de passageiros inválido");
|
setToastMessage("Número de passageiros inválido");
|
||||||
setShowToast(true);
|
setShowToast(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((Number)(vanForm.seats_number) < 1) {
|
||||||
|
setToastMessage("Número de passageiros deve ser positivo!");
|
||||||
|
setShowToast(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (vanForm.isRented) {
|
if (vanForm.isRented) {
|
||||||
return validateRentalForm();
|
return validateRentalForm();
|
||||||
} else {
|
} else {
|
||||||
@@ -152,43 +120,32 @@ const CadastroVan: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const validateRentalForm = (): boolean => {
|
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");
|
setToastMessage("Nome do Locador é obrigatório");
|
||||||
setShowToast(true);
|
setShowToast(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!vanForm.carRentalAddress.postalCode ||
|
!locatorForm.locator_city ||
|
||||||
vanForm.carRentalAddress.postalCode.length !== 8 ||
|
!locatorForm.locator_city.match(/([A-zà-úÀ-Ú])/g)
|
||||||
!vanForm.carRentalAddress.postalCode.match(/([0-9]){8}/g)
|
|
||||||
) {
|
) {
|
||||||
setToastMessage("Cep inválido");
|
setToastMessage("Cidade inválida");
|
||||||
setShowToast(true);
|
setShowToast(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!vanForm.carRentalAddress.number ||
|
!locatorForm.locator_state ||
|
||||||
!parseInt(`${vanForm.carRentalAddress.number}`)
|
!locatorForm.locator_state.match(/([A-zà-úÀ-Ú])/g)
|
||||||
) {
|
|
||||||
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)
|
|
||||||
) {
|
) {
|
||||||
setToastMessage("Estado inválido");
|
setToastMessage("Estado inválido");
|
||||||
setShowToast(true);
|
setShowToast(true);
|
||||||
@@ -199,9 +156,41 @@ const CadastroVan: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (validateForm()) {
|
if (!validateForm()) {
|
||||||
await ApiClient.doPost("/cadastro-van", vanForm);
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
history.push({ pathname: '/perfil', state: {
|
||||||
|
redirectData: {
|
||||||
|
showToastMessage: true,
|
||||||
|
toastColor: "success",
|
||||||
|
toastMessage: response.message,
|
||||||
|
},
|
||||||
|
}})
|
||||||
|
}).catch((err) => {
|
||||||
|
setToastColor("danger")
|
||||||
|
setToastMessage(err);
|
||||||
|
setShowToast(true);
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -211,7 +200,9 @@ const CadastroVan: React.FC = () => {
|
|||||||
const carModelsRes = await carsService.getAllCarModels()
|
const carModelsRes = await carsService.getAllCarModels()
|
||||||
|
|
||||||
if (carModelsRes.error) {
|
if (carModelsRes.error) {
|
||||||
console.log('Houve um erro')
|
setToastColor("danger")
|
||||||
|
setToastMessage(carModelsRes.error.errorMessage);
|
||||||
|
setShowToast(true);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,24 +239,16 @@ const CadastroVan: React.FC = () => {
|
|||||||
<IonInput
|
<IonInput
|
||||||
type='text'
|
type='text'
|
||||||
clearInput
|
clearInput
|
||||||
|
maxlength={7}
|
||||||
placeholder='Digite a Placa do Veículo'
|
placeholder='Digite a Placa do Veículo'
|
||||||
onIonInput={(e: any) => setInputValues({ carPlate: e.target.value })}
|
onIonChange={(e: any) => setInputValues({ carPlate: e.target.value })}
|
||||||
/>
|
/>
|
||||||
</IonItem>
|
</IonItem>
|
||||||
|
|
||||||
{/* <IonItem>
|
{/* TODO, problema de setState para valores vindos de um evento sendo triggerado por um ion-select */}
|
||||||
<IonLabel position='floating'>Marca </IonLabel>
|
|
||||||
<IonInput
|
|
||||||
type='text'
|
|
||||||
clearInput
|
|
||||||
placeholder='Digite a Marca do Veículo'
|
|
||||||
onIonInput={(e: any) => setInputValues({ carBrand: e.target.value })}
|
|
||||||
/>
|
|
||||||
</IonItem> */}
|
|
||||||
|
|
||||||
<IonItem>
|
<IonItem>
|
||||||
<IonLabel>Marca</IonLabel>
|
<IonLabel>Marca</IonLabel>
|
||||||
<IonSelect value={inputValues.marca}>
|
<IonSelect onIonChange={(e: any) => { setInputValues({ carBrand: e.detail.value }) }}>
|
||||||
{ carModels ? carModels.map((carModel, index) => {
|
{ carModels ? carModels.map((carModel, index) => {
|
||||||
return (<IonSelectOption key={index} value={carModel.name}>{carModel.name}</IonSelectOption>)
|
return (<IonSelectOption key={index} value={carModel.name}>{carModel.name}</IonSelectOption>)
|
||||||
}) : <></> }
|
}) : <></> }
|
||||||
@@ -278,19 +261,20 @@ const CadastroVan: React.FC = () => {
|
|||||||
type='text'
|
type='text'
|
||||||
clearInput
|
clearInput
|
||||||
placeholder='Digite o Modelo do Veículo'
|
placeholder='Digite o Modelo do Veículo'
|
||||||
onIonInput={(e: any) => setInputValues({ carModel: e.target.value })}
|
onIonChange={(e: any) => setInputValues({ carModel: e.target.value })}
|
||||||
/>
|
/>
|
||||||
</IonItem>
|
</IonItem>
|
||||||
|
|
||||||
<IonItem>
|
<IonItem>
|
||||||
<IonLabel position='floating'>
|
<IonLabel position='floating'>
|
||||||
Número Máximo de Passageiros
|
Número de assentos
|
||||||
</IonLabel>
|
</IonLabel>
|
||||||
<IonInput
|
<IonInput
|
||||||
type='text'
|
type='number'
|
||||||
|
min={1}
|
||||||
clearInput
|
clearInput
|
||||||
placeholder='Digite o número máximo de passageiros'
|
placeholder='podem ser ocupados por passageiros'
|
||||||
onIonInput={(e: any) => setInputValues({ maxPassengers: e.target.value })}
|
onIonChange={(e: any) => setInputValues({ seats_number: e.target.value })}
|
||||||
/>
|
/>
|
||||||
</IonItem>
|
</IonItem>
|
||||||
</IonList>
|
</IonList>
|
||||||
@@ -313,38 +297,32 @@ const CadastroVan: React.FC = () => {
|
|||||||
type='text'
|
type='text'
|
||||||
clearInput
|
clearInput
|
||||||
placeholder='Nome completo do Locador'
|
placeholder='Nome completo do Locador'
|
||||||
onIonInput={(e: any) => setInputValues({ carRentalName: e.target.value })}
|
onIonChange={(e: any) => setInputValues({ locator_name: e.target.value })}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<IonInput
|
<IonInput
|
||||||
type='text'
|
type='text'
|
||||||
clearInput
|
clearInput
|
||||||
placeholder='Endereço do locador'
|
placeholder='Endereço do locador'
|
||||||
onIonInput={(e: any) => setInputValues({ postalCode: e.target.value })}
|
onIonChange={(e: any) => setInputValues({ locator_address: e.target.value })}
|
||||||
/>
|
|
||||||
<IonInput
|
|
||||||
type='text'
|
|
||||||
clearInput
|
|
||||||
placeholder='Número'
|
|
||||||
onIonInput={(e: any) => setInputValues({ number: e.target.value })}
|
|
||||||
/>
|
/>
|
||||||
<IonInput
|
<IonInput
|
||||||
type='text'
|
type='text'
|
||||||
clearInput
|
clearInput
|
||||||
placeholder='Complemento'
|
placeholder='Complemento'
|
||||||
onIonInput={(e: any) => setInputValues({ complement: e.target.value })}
|
onIonChange={(e: any) => setInputValues({ locator_complement: e.target.value })}
|
||||||
/>
|
/>
|
||||||
<IonInput
|
<IonInput
|
||||||
type='text'
|
type='text'
|
||||||
clearInput
|
clearInput
|
||||||
placeholder='Cidade'
|
placeholder='Cidade'
|
||||||
onIonInput={(e: any) => setInputValues({ city: e.target.value })}
|
onIonChange={(e: any) => setInputValues({ locator_city: e.target.value })}
|
||||||
/>
|
/>
|
||||||
<IonInput
|
<IonInput
|
||||||
type='text'
|
type='text'
|
||||||
clearInput
|
clearInput
|
||||||
placeholder='Estado'
|
placeholder='Estado'
|
||||||
onIonInput={(e: any) => setInputValues({ state: e.target.value })}
|
onIonChange={(e: any) => setInputValues({ locator_state: e.target.value })}
|
||||||
/>
|
/>
|
||||||
</IonItem>
|
</IonItem>
|
||||||
</div>
|
</div>
|
||||||
@@ -362,12 +340,13 @@ const CadastroVan: React.FC = () => {
|
|||||||
</IonList>
|
</IonList>
|
||||||
|
|
||||||
<IonToast
|
<IonToast
|
||||||
color='danger'
|
position="top"
|
||||||
|
color={toastColor}
|
||||||
isOpen={showToast}
|
isOpen={showToast}
|
||||||
onDidDismiss={() => setShowToast(false)}
|
onDidDismiss={() => setShowToast(false)}
|
||||||
message={toastMessage}
|
message={toastMessage}
|
||||||
duration={2500}
|
duration={2500}
|
||||||
/>
|
/>
|
||||||
</IonContent>
|
</IonContent>
|
||||||
</IonPage>
|
</IonPage>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,14 +1,74 @@
|
|||||||
import { IonItem, IonLabel, IonInput, IonButton, IonCardTitle, IonCol, IonContent, IonGrid, IonPage, IonRow } from '@ionic/react';
|
import { IonContent, IonPage, IonToast } from '@ionic/react';
|
||||||
import { useHistory } from 'react-router';
|
import { Color } from '@ionic/react/node_modules/@ionic/core';
|
||||||
import { Action } from '../components/Action';
|
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 Home: React.FC = () => {
|
||||||
const history = useHistory()
|
const location = useLocation<LocationState>();
|
||||||
|
|
||||||
|
const user = useContext(UserContext);
|
||||||
|
|
||||||
|
const [showToast, setShowToast] = useState(false);
|
||||||
|
const [toastMessage, setToastMessage] = useState('');
|
||||||
|
const [toastColor, setToastColor] = useState<Color>("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') {
|
||||||
|
// 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 (
|
return (
|
||||||
<IonPage>
|
<IonPage>
|
||||||
<IonContent>
|
<IonContent>
|
||||||
<IonButton onClick={() => { history.push({ pathname: '/usuario/56520ae7-faf8-4444-a82b-7f3990ab02d8' }); }}>Ir para o perfil de outra pessoa</IonButton>
|
<IonToast
|
||||||
|
position="top"
|
||||||
|
color={toastColor}
|
||||||
|
isOpen={showToast}
|
||||||
|
onDidDismiss={() => setShowToast(false)}
|
||||||
|
message={toastMessage}
|
||||||
|
duration={2500}
|
||||||
|
/>
|
||||||
</IonContent>
|
</IonContent>
|
||||||
</IonPage>
|
</IonPage>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -89,7 +89,11 @@ const Page: React.FC = () => {
|
|||||||
|
|
||||||
user.setIsLoggedIn(true);
|
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 => {
|
}).catch(error => {
|
||||||
// if (!error.response) return
|
// if (!error.response) return
|
||||||
|
|
||||||
@@ -155,7 +159,7 @@ const Page: React.FC = () => {
|
|||||||
</IonGrid>
|
</IonGrid>
|
||||||
|
|
||||||
<IonToast
|
<IonToast
|
||||||
// cssClass={"toast-notification"}
|
position="top"
|
||||||
color='danger'
|
color='danger'
|
||||||
isOpen={showToast}
|
isOpen={showToast}
|
||||||
onDidDismiss={() => setShowToast(false)}
|
onDidDismiss={() => setShowToast(false)}
|
||||||
|
|||||||
118
src/pages/MinhasVans.tsx
Normal file
118
src/pages/MinhasVans.tsx
Normal file
@@ -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<Color>("primary");
|
||||||
|
|
||||||
|
const [userVans, setUserVans] = useState<VanInfo[]>();
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<IonPage>
|
||||||
|
<IonHeader>
|
||||||
|
<IonToolbar>
|
||||||
|
<IonTitle>Minhas vans</IonTitle>
|
||||||
|
<IonButtons slot="start">
|
||||||
|
<IonBackButton defaultHref="/perfil" />
|
||||||
|
</IonButtons>
|
||||||
|
</IonToolbar>
|
||||||
|
</IonHeader>
|
||||||
|
|
||||||
|
<IonContent>
|
||||||
|
{ userVans ? userVans.map((van, index) => {
|
||||||
|
return (
|
||||||
|
<IonCard key={index}>
|
||||||
|
<IonCardHeader>
|
||||||
|
<IonCardTitle>{van.plate}</IonCardTitle>
|
||||||
|
<IonCardSubtitle>{van.brand} - {van.model}</IonCardSubtitle>
|
||||||
|
</IonCardHeader>
|
||||||
|
{ van.locator_name ?
|
||||||
|
<>
|
||||||
|
<IonCardContent>{van.seats_number} assentos - Locador: {van.locator_name}</IonCardContent>
|
||||||
|
</> :
|
||||||
|
<>
|
||||||
|
<IonCardContent>{van.seats_number} assentos - Não é alugado</IonCardContent>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</IonCard>
|
||||||
|
)
|
||||||
|
}) : <></>}
|
||||||
|
|
||||||
|
<IonToast
|
||||||
|
position="top"
|
||||||
|
color={toastColor}
|
||||||
|
isOpen={showToast}
|
||||||
|
onDidDismiss={() => setShowToast(false)}
|
||||||
|
message={toastMessage}
|
||||||
|
duration={2500}
|
||||||
|
/>
|
||||||
|
</IonContent>
|
||||||
|
</IonPage>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MinhasVans;
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
|
IonBackButton,
|
||||||
|
IonBadge,
|
||||||
|
IonButtons,
|
||||||
IonCard,
|
IonCard,
|
||||||
IonCardContent,
|
IonCardContent,
|
||||||
IonCardHeader,
|
IonCardHeader,
|
||||||
@@ -16,9 +19,9 @@ import {
|
|||||||
IonToast,
|
IonToast,
|
||||||
IonToolbar,
|
IonToolbar,
|
||||||
} from "@ionic/react";
|
} 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 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 './Perfil.css'
|
||||||
import LocalStorage from "../LocalStorage";
|
import LocalStorage from "../LocalStorage";
|
||||||
@@ -26,6 +29,7 @@ import LocalStorage from "../LocalStorage";
|
|||||||
import sessionsService from '../services/functions/sessionsService'
|
import sessionsService from '../services/functions/sessionsService'
|
||||||
import usersService from '../services/functions/usersService'
|
import usersService from '../services/functions/usersService'
|
||||||
import { UserContext } from "../App";
|
import { UserContext } from "../App";
|
||||||
|
import { Color } from "@ionic/react/node_modules/@ionic/core";
|
||||||
|
|
||||||
interface ScanNewProps {
|
interface ScanNewProps {
|
||||||
match: {
|
match: {
|
||||||
@@ -35,31 +39,47 @@ interface ScanNewProps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface LocationState {
|
||||||
|
redirectData?: {
|
||||||
|
showToastMessage: boolean;
|
||||||
|
toastColor: Color;
|
||||||
|
toastMessage: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const Perfil: React.FC<ScanNewProps> = (props) => {
|
const Perfil: React.FC<ScanNewProps> = (props) => {
|
||||||
const user = useContext(UserContext);
|
const user = useContext(UserContext);
|
||||||
|
|
||||||
|
const history = useHistory();
|
||||||
|
const location = useLocation<LocationState>();
|
||||||
|
|
||||||
const [isVisitor, setIsVisitor] = useState(true)
|
const [isVisitor, setIsVisitor] = useState(true)
|
||||||
|
|
||||||
|
const [incompleteProfile, setIncompleteProfile] = useState(false)
|
||||||
|
const [incompleteProfileCounter, setIncompleteProfileCounter] = useState(0)
|
||||||
|
|
||||||
const [showToast, setShowToast] = useState(false);
|
const [showToast, setShowToast] = useState(false);
|
||||||
const [messageToast, setMessageToast] = useState('');
|
const [toastMessage, setToastMessage] = useState('');
|
||||||
|
const [toastColor, setToastColor] = useState<Color>("primary");
|
||||||
|
|
||||||
const [inputValues, setInputValues] = useReducer(
|
const [inputValues, setInputValues] = useReducer(
|
||||||
(state: any, newState: any) => ({ ...state, ...newState }),
|
(state: any, newState: any) => ({ ...state, ...newState }),
|
||||||
{
|
{
|
||||||
|
id: '',
|
||||||
name: '',
|
name: '',
|
||||||
lastname: '',
|
lastname: '',
|
||||||
email: '',
|
email: '',
|
||||||
|
phone_number: '',
|
||||||
birth_date: '',
|
birth_date: '',
|
||||||
bio: '',
|
bio: '',
|
||||||
|
document_type: '',
|
||||||
|
document: '',
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const history = useHistory();
|
|
||||||
|
|
||||||
const redirectUserToLogin = () => {
|
const redirectUserToLogin = () => {
|
||||||
// TODO, não impede o usuário de retornar a página de login
|
|
||||||
history.push({ pathname: '/login' });
|
history.push({ pathname: '/login' });
|
||||||
setMessageToast("Por favor, autentique-se!");
|
setToastMessage("Por favor, autentique-se!");
|
||||||
setShowToast(true);
|
setShowToast(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,6 +90,16 @@ const Perfil: React.FC<ScanNewProps> = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
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 () => {
|
const loadUserData = async () => {
|
||||||
let userId = ''
|
let userId = ''
|
||||||
|
|
||||||
@@ -94,11 +124,11 @@ const Perfil: React.FC<ScanNewProps> = (props) => {
|
|||||||
|
|
||||||
if (getByIdRes.error) {
|
if (getByIdRes.error) {
|
||||||
if (isVisitor && props.match.params.id) {
|
if (isVisitor && props.match.params.id) {
|
||||||
setMessageToast('Usuário não existe!')
|
setToastMessage('Usuário não existe!')
|
||||||
setShowToast(true)
|
setShowToast(true)
|
||||||
history.push({ pathname: '/home' })
|
history.push({ pathname: '/home' })
|
||||||
} else {
|
} else {
|
||||||
setMessageToast(getByIdRes.error.errorMessage)
|
setToastMessage(getByIdRes.error.errorMessage)
|
||||||
setShowToast(true)
|
setShowToast(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,16 +140,31 @@ const Perfil: React.FC<ScanNewProps> = (props) => {
|
|||||||
|
|
||||||
if (isMounted) {
|
if (isMounted) {
|
||||||
setInputValues({
|
setInputValues({
|
||||||
|
'id': userId,
|
||||||
'name': userData.name,
|
'name': userData.name,
|
||||||
'lastname': userData.lastname,
|
'lastname': userData.lastname,
|
||||||
'email': userData.email,
|
'email': userData.email,
|
||||||
|
'phone_number': userData.phone_number,
|
||||||
'birth_date': userData.birth_date,
|
'birth_date': userData.birth_date,
|
||||||
'bio': userData.bio
|
'bio': userData.bio,
|
||||||
|
'document_type': userData.document_type,
|
||||||
|
'document': userData.document
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!props.match.params.id) {
|
if (!props.match.params.id) {
|
||||||
setIsVisitor(false)
|
setIsVisitor(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!userData.document || !userData.phone_number) {
|
||||||
|
setIncompleteProfile(true)
|
||||||
|
|
||||||
|
let counter = 0
|
||||||
|
|
||||||
|
if (!userData.document) counter++
|
||||||
|
if (!userData.phone_number) counter++
|
||||||
|
|
||||||
|
setIncompleteProfileCounter(counter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,6 +187,9 @@ const Perfil: React.FC<ScanNewProps> = (props) => {
|
|||||||
<IonHeader>
|
<IonHeader>
|
||||||
<IonToolbar>
|
<IonToolbar>
|
||||||
<IonTitle>Seu perfil</IonTitle>
|
<IonTitle>Seu perfil</IonTitle>
|
||||||
|
<IonButtons slot="start">
|
||||||
|
<IonBackButton defaultHref="/home" />
|
||||||
|
</IonButtons>
|
||||||
</IonToolbar>
|
</IonToolbar>
|
||||||
</IonHeader>
|
</IonHeader>
|
||||||
|
|
||||||
@@ -154,8 +202,8 @@ const Perfil: React.FC<ScanNewProps> = (props) => {
|
|||||||
|
|
||||||
<IonCard>
|
<IonCard>
|
||||||
<IonCardContent>
|
<IonCardContent>
|
||||||
{/* <img src="https://static.generated.photos/vue-static/home/feed/adult.png" alt="avatar" className='avatar' id='avatar'/> */}
|
<img src="https://static.generated.photos/vue-static/home/feed/adult.png" alt="avatar" className='avatar' id='avatar'/>
|
||||||
<img src="https://lastfm.freetls.fastly.net/i/u/avatar170s/faa68f71f3b2a48ca89228c2c2aa72d3" alt="avatar" className='avatar' id='avatar'/>
|
{/* <img src="https://lastfm.freetls.fastly.net/i/u/avatar170s/faa68f71f3b2a48ca89228c2c2aa72d3" alt="avatar" className='avatar' id='avatar'/> */}
|
||||||
<IonCardHeader>
|
<IonCardHeader>
|
||||||
<IonCardTitle class="ion-text-center">{inputValues.name} {inputValues.lastname}</IonCardTitle>
|
<IonCardTitle class="ion-text-center">{inputValues.name} {inputValues.lastname}</IonCardTitle>
|
||||||
</IonCardHeader>
|
</IonCardHeader>
|
||||||
@@ -174,11 +222,31 @@ const Perfil: React.FC<ScanNewProps> = (props) => {
|
|||||||
<IonCardTitle>Biografia</IonCardTitle>
|
<IonCardTitle>Biografia</IonCardTitle>
|
||||||
</IonCardHeader>
|
</IonCardHeader>
|
||||||
<IonCardContent>
|
<IonCardContent>
|
||||||
{inputValues.bio ? inputValues.bio : 'Sem biografia.' }
|
{inputValues.bio ? inputValues.bio : 'Sem biografia.' }
|
||||||
</IonCardContent>
|
</IonCardContent>
|
||||||
</IonCard>
|
</IonCard>
|
||||||
|
|
||||||
{/* // TODO, card de informações de contato */}
|
<IonCard>
|
||||||
|
<IonCardHeader>
|
||||||
|
<IonCardTitle>Informações de contato</IonCardTitle>
|
||||||
|
</IonCardHeader>
|
||||||
|
<IonCardContent>
|
||||||
|
{ !inputValues.phone_number ?
|
||||||
|
<>Sem informações de contato.</>
|
||||||
|
: <>
|
||||||
|
{
|
||||||
|
inputValues.phone_number ?
|
||||||
|
<>
|
||||||
|
<IonChip>
|
||||||
|
<IonIcon icon={callOutline} />
|
||||||
|
<IonLabel>{inputValues.phone_number}</IonLabel>
|
||||||
|
</IonChip>
|
||||||
|
</> : <></>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</IonCardContent>
|
||||||
|
</IonCard>
|
||||||
|
|
||||||
{ !isVisitor ?
|
{ !isVisitor ?
|
||||||
<IonList>
|
<IonList>
|
||||||
@@ -187,14 +255,25 @@ const Perfil: React.FC<ScanNewProps> = (props) => {
|
|||||||
<IonIcon icon={createOutline} slot="start" />
|
<IonIcon icon={createOutline} slot="start" />
|
||||||
<IonLabel>Editar perfil</IonLabel>
|
<IonLabel>Editar perfil</IonLabel>
|
||||||
</IonItem>
|
</IonItem>
|
||||||
<IonItem button onClick={() => history.push({ pathname: '/perfil/completar', state: { userData: inputValues } })}>
|
|
||||||
<IonIcon icon={shieldCheckmarkOutline} slot="start" />
|
{ incompleteProfile ?
|
||||||
<IonLabel>Completar cadastro</IonLabel>
|
<>
|
||||||
</IonItem>
|
<IonItem button onClick={() => history.push({ pathname: '/perfil/completar', state: { userData: inputValues } })}>
|
||||||
|
<IonIcon icon={shieldCheckmarkOutline} slot="start" />
|
||||||
|
<IonLabel>Completar cadastro</IonLabel>
|
||||||
|
<IonBadge color="primary">{incompleteProfileCounter}</IonBadge>
|
||||||
|
</IonItem>
|
||||||
|
</>
|
||||||
|
: <></> }
|
||||||
|
|
||||||
<IonItem button onClick={() => history.push({ pathname: '/cadastro-van'})}>
|
<IonItem button onClick={() => history.push({ pathname: '/cadastro-van'})}>
|
||||||
<IonIcon icon={carOutline} slot="start" />
|
<IonIcon icon={carOutline} slot="start" />
|
||||||
<IonLabel>Cadastrar Van</IonLabel>
|
<IonLabel>Cadastrar Van</IonLabel>
|
||||||
</IonItem>
|
</IonItem>
|
||||||
|
<IonItem button onClick={() => history.push({ pathname: '/minhas-vans'})}>
|
||||||
|
<IonIcon icon={carOutline} slot="start" />
|
||||||
|
<IonLabel>Minhas Vans</IonLabel>
|
||||||
|
</IonItem>
|
||||||
<IonItem>
|
<IonItem>
|
||||||
<IonIcon icon={cardOutline} slot="start" />
|
<IonIcon icon={cardOutline} slot="start" />
|
||||||
<IonLabel>Pagamentos</IonLabel>
|
<IonLabel>Pagamentos</IonLabel>
|
||||||
@@ -211,10 +290,11 @@ const Perfil: React.FC<ScanNewProps> = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
<IonToast
|
<IonToast
|
||||||
color='danger'
|
position="top"
|
||||||
|
color={toastColor}
|
||||||
isOpen={showToast}
|
isOpen={showToast}
|
||||||
onDidDismiss={() => setShowToast(false)}
|
onDidDismiss={() => setShowToast(false)}
|
||||||
message={messageToast}
|
message={toastMessage}
|
||||||
duration={2500}
|
duration={2500}
|
||||||
/>
|
/>
|
||||||
</IonContent>
|
</IonContent>
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import isEqual from 'lodash.isequal';
|
|||||||
import * as usersRoutes from '../services/api/users';
|
import * as usersRoutes from '../services/api/users';
|
||||||
|
|
||||||
import './Cadastro/Cadastro.css'
|
import './Cadastro/Cadastro.css'
|
||||||
|
import { Color } from "@ionic/react/node_modules/@ionic/core";
|
||||||
|
|
||||||
interface userData {
|
interface userData {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -47,6 +48,7 @@ const PerfilEditar: React.FC = () => {
|
|||||||
|
|
||||||
const [showToast, setShowToast] = useState(false);
|
const [showToast, setShowToast] = useState(false);
|
||||||
const [messageToast, setMessageToast] = useState('');
|
const [messageToast, setMessageToast] = useState('');
|
||||||
|
const [toastColor, setToastColor] = useState<Color>("primary");
|
||||||
|
|
||||||
const [userData, setUserData] = useState({
|
const [userData, setUserData] = useState({
|
||||||
name: '',
|
name: '',
|
||||||
@@ -68,6 +70,10 @@ const PerfilEditar: React.FC = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!location.state) {
|
||||||
|
history.push({ pathname: '/perfil' })
|
||||||
|
}
|
||||||
|
|
||||||
let userData = location.state.userData
|
let userData = location.state.userData
|
||||||
|
|
||||||
setUserData(location.state.userData)
|
setUserData(location.state.userData)
|
||||||
@@ -83,14 +89,22 @@ const PerfilEditar: React.FC = () => {
|
|||||||
const handleUpdateUserData = () => {
|
const handleUpdateUserData = () => {
|
||||||
usersRoutes.update(inputValues).then(response => {
|
usersRoutes.update(inputValues).then(response => {
|
||||||
if (response.status === 'error') {
|
if (response.status === 'error') {
|
||||||
|
setToastColor("danger")
|
||||||
setMessageToast(response.message);
|
setMessageToast(response.message);
|
||||||
setShowToast(true);
|
setShowToast(true);
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(response)
|
history.push({ pathname: '/perfil', state: {
|
||||||
|
redirectData: {
|
||||||
|
showToastMessage: true,
|
||||||
|
toastColor: "success",
|
||||||
|
toastMessage: response.message,
|
||||||
|
},
|
||||||
|
}})
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
|
setToastColor("danger")
|
||||||
setMessageToast(err);
|
setMessageToast(err);
|
||||||
setShowToast(true);
|
setShowToast(true);
|
||||||
})
|
})
|
||||||
@@ -172,7 +186,7 @@ const PerfilEditar: React.FC = () => {
|
|||||||
</IonFab>
|
</IonFab>
|
||||||
|
|
||||||
<IonToast
|
<IonToast
|
||||||
color='danger'
|
color={toastColor}
|
||||||
isOpen={showToast}
|
isOpen={showToast}
|
||||||
onDidDismiss={() => setShowToast(false)}
|
onDidDismiss={() => setShowToast(false)}
|
||||||
message={messageToast}
|
message={messageToast}
|
||||||
|
|||||||
@@ -37,9 +37,12 @@ export interface CadastroRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateUserRequest {
|
export interface UpdateUserRequest {
|
||||||
name: string;
|
name?: string;
|
||||||
email: string;
|
email?: string;
|
||||||
bio: string;
|
bio?: string;
|
||||||
|
document_type?: string;
|
||||||
|
document?: string;
|
||||||
|
phone_number?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// export async function get(cpf) {
|
// export async function get(cpf) {
|
||||||
@@ -68,4 +71,12 @@ export async function update(userData: UpdateUserRequest) {
|
|||||||
|
|
||||||
const response = await instance.patch(userRoutes.update.url, userData, { headers: header });
|
const response = await instance.patch(userRoutes.update.url, userData, { headers: header });
|
||||||
return response.data;
|
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;
|
||||||
}
|
}
|
||||||
73
src/services/api/vans.ts
Normal file
73
src/services/api/vans.ts
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
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 getByPlate(vanId: string) {
|
||||||
|
updateHeader();
|
||||||
|
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
|
||||||
|
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, { headers: header });
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -5,8 +5,11 @@ interface getByIdReturn {
|
|||||||
name: string;
|
name: string;
|
||||||
lastname: string;
|
lastname: string;
|
||||||
email: string;
|
email: string;
|
||||||
|
phone_number: string;
|
||||||
birth_date: string;
|
birth_date: string;
|
||||||
bio: string;
|
bio: string;
|
||||||
|
document_type: string;
|
||||||
|
document: string;
|
||||||
},
|
},
|
||||||
error?: {
|
error?: {
|
||||||
errorMessage: string;
|
errorMessage: string;
|
||||||
@@ -21,8 +24,11 @@ interface getByIdRes {
|
|||||||
name: string;
|
name: string;
|
||||||
lastname: string;
|
lastname: string;
|
||||||
email: string;
|
email: string;
|
||||||
|
phone_number: string;
|
||||||
birth_date: string;
|
birth_date: string;
|
||||||
bio: string;
|
bio: string;
|
||||||
|
document_type: string;
|
||||||
|
document: string;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,4 +56,40 @@ const getById = async (userId: string): Promise<getByIdReturn> => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default { getById }
|
interface getByIdReturn {
|
||||||
|
data?: {
|
||||||
|
phone: '',
|
||||||
|
whatsapp: '',
|
||||||
|
facebook: '',
|
||||||
|
telegram: '',
|
||||||
|
},
|
||||||
|
error?: {
|
||||||
|
errorMessage: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUserSocialInfo = async (userId: string): Promise<getByIdReturn> => {
|
||||||
|
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 }
|
||||||
25
src/services/validateCpf.ts
Normal file
25
src/services/validateCpf.ts
Normal file
@@ -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;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user