Merge branch 'develop' of https://github.com/CloudAlb/tcc-vamos-frontend into feature/VAN-16-view-create-itinerary

This commit is contained in:
Hugo Falcao
2022-09-11 22:38:27 -03:00
40 changed files with 1279 additions and 13306 deletions

View File

@@ -9,8 +9,32 @@ import {
setupIonicReact,
} from "@ionic/react";
import { IonReactRouter } from "@ionic/react-router";
import React, { useContext, useState } from "react";
import { Redirect, Route } from "react-router-dom";
import { home, person, search } from "ionicons/icons";
// importação das páginas
import Cadastro from "./pages/Cadastro/Cadastro";
import CadastroCompletar from "./pages/CadastroCompletar/CadastroCompletar";
import CompletarDocumento from "./pages/CadastroCompletar/CompletarDocumento";
import CompletarTelefone from "./pages/CadastroCompletar/CompletarTelefone";
import Home from "./pages/Home";
import Login from "./pages/Login";
import Perfil from "./pages/Perfil";
import PerfilEditar from "./pages/PerfilEditar";
import CadastrarItinerario from "./pages/CadastrarItinerario/CadastrarItinerario";
import MeusItinerarios from "./pages/MeusItinerarios/MeusItinerarios";
import MeusVeiculos from "./pages/MeusVeiculos";
import VeiculoCadastro from "./pages/VeiculoCadastro";
import BuscarItinerario from "./pages/BuscarItinerario";
import BuscarPassageiro from "./pages/BuscarPassageiro/BuscarPassageiro";
import Buscas from "./pages/Buscas";
import Transportes from "./pages/Transportes/Transportes";
/* Core CSS required for Ionic components to work properly */
import "@ionic/react/css/core.css";
@@ -33,37 +57,11 @@ import "./theme/variables.css";
/* Tailwind styles */
import "./theme/tailwind.css";
import { home, person, search } from "ionicons/icons";
import React, { useContext, useState } from "react";
/* Importação das páginas */
import BuscarPassageiro from "./pages/BuscarPassageiro/BuscarPassageiro";
import BuscarTransporte from "./pages/BuscarTransporte/BuscarTransporte";
import CadastrarItinerario from "./pages/CadastrarItinerario/CadastrarItinerario";
import Cadastro from "./pages/Cadastro/Cadastro";
import CadastroCompletar from "./pages/CadastroCompletar/CadastroCompletar";
import CompletarDocumento from "./pages/CadastroCompletar/CompletarDocumento";
import CompletarTelefone from "./pages/CadastroCompletar/CompletarTelefone";
import CadastroVan from "./pages/CadastroVan";
import Home from "./pages/Home";
import Login from "./pages/Login";
import MeusItinerarios from "./pages/MeusItinerarios/MeusItinerarios";
import MinhasVans from "./pages/MinhasVans";
import Perfil from "./pages/Perfil";
import PerfilEditar from "./pages/PerfilEditar";
import Transportes from "./pages/Transportes/Transportes";
setupIonicReact();
const routes = (
<>
<Route exact path="/cadastro" component={Cadastro}></Route>
<Route exact path="/login" component={Login}></Route>
<Route exact path="/home" component={Home}></Route>
<Route exact path="/perfil" component={Perfil}></Route>
<Route exact path="/perfil/editar" component={PerfilEditar}></Route>
<Route exact path="/perfil/completar" component={CadastroCompletar}></Route>
<Route
exact
@@ -76,22 +74,29 @@ const routes = (
component={CompletarTelefone}
></Route>
<Route exact path="/transportes" component={Transportes}></Route>
<Route exact path="/buscar-passageiro" component={BuscarPassageiro}></Route>
<Route exact path="/buscar-transporte" component={BuscarTransporte}></Route>
<Route exact path="/home" component={Home}></Route>
<Route exact path="/login" component={Login}></Route>
<Route exact path="/perfil" component={Perfil}></Route>
<Route exact path="/usuario/:id" component={Perfil}></Route>
<Route exact path="/cadastro-van" component={CadastroVan}></Route>
<Route exact path="/minhas-vans" component={MinhasVans}></Route>
<Route exact path="/perfil/editar" component={PerfilEditar}></Route>
<Route exact path="/veiculos/cadastrar" component={VeiculoCadastro}></Route>
<Route exact path="/veiculos/meus" component={MeusVeiculos}></Route>
<Route
exact
path="/cadastrar-itinerario"
component={CadastrarItinerario}
></Route>
<Route exact path="/meus-itinerarios" component={MeusItinerarios}></Route>
<Route exact path="/buscas" component={Buscas}></Route>
<Route exact path="/buscar/itinerario" component={BuscarItinerario}></Route>
<Route exact path="/buscar/passageiro" component={BuscarPassageiro}></Route>
<Route exact path="/transportes" component={Transportes}></Route>
<Route exact path="/">
<Redirect to="/login" />
<Redirect to="/home" />
</Route>
</>
);
@@ -120,7 +125,7 @@ const IonicApp: React.FC = () => {
<IonRouterOutlet>{routes}</IonRouterOutlet>
<IonTabBar slot="bottom">
<IonTabButton tab="buscar" href="/buscar-transporte">
<IonTabButton tab="buscar" href="/buscas">
<IonIcon icon={search} />
<IonLabel>Buscar</IonLabel>
</IonTabButton>

View File

@@ -1,17 +1,19 @@
import { IonCol, IonRouterLink, IonRow } from "@ionic/react";
interface ComponentProps {
message: string,
link: string,
text: string
message: string;
link: string;
text: string;
}
export const Action = (props: ComponentProps) => (
<IonRow className="ion-text-center ion-justify-content-center">
<IonCol size="12">
{ props.message }
<IonRouterLink className="custom-link" routerLink={ props.link }> { props.text } &rarr;</IonRouterLink>
{props.message}
<IonRouterLink className="custom-link" routerLink={props.link}>
{" "}
{props.text} &rarr;
</IonRouterLink>
</IonCol>
</IonRow>
);

View File

@@ -0,0 +1,17 @@
import { IonBackButton, IonButtons, IonHeader, IonTitle, IonToolbar } from "@ionic/react";
interface ComponentProps {
pageName: string;
backButtonPageUrl?: string;
}
export const PageHeader = (props: ComponentProps) => (
<IonHeader translucent>
<IonToolbar>
<IonTitle>{props.pageName}</IonTitle>
<IonButtons slot="start">
<IonBackButton text="" defaultHref={ props.backButtonPageUrl ? props.backButtonPageUrl : undefined } />
</IonButtons>
</IonToolbar>
</IonHeader>
);

View File

@@ -1,7 +1,10 @@
const carsRoutesDefault = '/cars';
const carsRoutes = {
list: {
url: `${carsRoutesDefault}/list`
listAllBrands: {
url: `${carsRoutesDefault}/brands/list`
},
listCarModels: {
url: `${carsRoutesDefault}/models/list`
}
}

View File

@@ -1,4 +1,4 @@
const transportsRoutesDefault = '/transports';
const transportsRoutesDefault = '/itineraries';
const transportsRoutes = {
create: {
url: `${transportsRoutesDefault}`
@@ -6,6 +6,9 @@ const transportsRoutes = {
get: {
url: `${transportsRoutesDefault}`
},
search: {
url: `${transportsRoutesDefault}/search/inradius`
},
update: {
url: `${transportsRoutesDefault}`
},

View File

@@ -1,17 +1,17 @@
const vansRoutesDefault = '/vans/locator';
const vansRoutes = {
const vehiclesRoutesDefault = '/vehicles/locator';
const vehiclesRoutes = {
list: {
url: `${vansRoutesDefault}/list`
url: `${vehiclesRoutesDefault}/list`
},
getById: {
url: `${vansRoutesDefault}/`
url: `${vehiclesRoutesDefault}/`
},
create: {
url: `${vansRoutesDefault}/`
url: `${vehiclesRoutesDefault}/`
},
update: {
url: `${vansRoutesDefault}/edit`
url: `${vehiclesRoutesDefault}/edit`
}
}
export default vansRoutes;
export default vehiclesRoutes;

View File

@@ -1,20 +0,0 @@
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;

View File

@@ -0,0 +1,20 @@
const vehiclesRoutesDefault = '/vehicles';
const vehiclesRoutes = {
list: {
url: `${vehiclesRoutesDefault}/list`
},
getByPlate: {
url: `${vehiclesRoutesDefault}/plate`
},
getByUserId: {
url: `${vehiclesRoutesDefault}/user`
},
create: {
url: `${vehiclesRoutesDefault}/`
},
update: {
url: `${vehiclesRoutesDefault}/`
}
}
export default vehiclesRoutes;

View File

@@ -0,0 +1,13 @@
export interface Itinerary {
id_itinerary: number;
vehicle_plate: string;
price: number;
days_of_week: number;
specific_day: Date;
estimated_departure_time: Date;
estimated_arrival_time: Date;
available_seats: number;
itinerary_nickname: string;
created_at: Date;
updated_at: Date;
}

View File

@@ -1,4 +1,4 @@
export type Van = {
export type Vehicle = {
id: number;
carPlate: string;
carBrand: string;

View File

@@ -0,0 +1,364 @@
import {
IonButton,
IonCard,
IonCardContent,
IonCardHeader,
IonCardSubtitle,
IonCardTitle,
IonContent,
IonIcon,
IonItemDivider,
IonPage,
IonRow,
IonToast,
} from "@ionic/react";
import {
arrowForwardOutline,
cashOutline,
chevronForwardOutline,
locateOutline,
locationOutline,
personOutline,
starOutline,
timeOutline,
} from "ionicons/icons";
import "./BuscarItinerario.css";
import itinerariesService from "../services/functions/itinerariesService";
import { useEffect, useState } from "react";
import { useHistory } from "react-router";
import { geocodeByAddress, getLatLng } from "react-google-places-autocomplete";
import { PageHeader } from "../components/PageHeader";
import { Itinerary } from "../models/itinerary.model";
import { closeToast } from "../services/utils";
import { Color } from "@ionic/core";
const BuscarItinerario: React.FC = () => {
const history = useHistory();
const [showToast, setShowToast] = useState(false);
const [messageToast, setMessageToast] = useState("");
const [toastColor, setToastColor] = useState<Color>("primary");
const [addressFrom, setAddressFrom] = useState<any>("");
const [coordinatesFrom, setCoordinatesFrom] = useState<any>("");
const [addressTo, setAddressTo] = useState<any>("");
const [coordinatesTo, setCoordinatesTo] = useState<any>("");
const [showModalEnd, setShowModalEnd] = useState(false);
const [addressResults, setAddressResults] = useState<any[]>([]);
const [inputActive, setInputActive] = useState("");
const [recentSearches, setRecentSearches] = useState<any[]>([]);
const [itinerariesList, setItinerariesList] = useState<Itinerary[]>();
// const optionsAddress = async (inputValue: any) => {
// let results = await autoCompleteAddress(inputValue)
// .then((res) => {
// return res.map((item: any) => {
// return {
// value:
// item.geometry.coordinates[0] + "," + item.geometry.coordinates[1],
// label: item.properties.formatted,
// };
// });
// })
// .catch((err) => {
// console.log("Erro ao buscar endereço:", err);
// });
// setAddressResults(results);
// };
// function setInputActiveOpenModal(input: string) {
// setInputActive(input);
// setShowModalEnd(true);
// }
// function setAddress(div: any) {
// if (inputActive === "from") {
// setAddressFrom(div.target.attributes[2].value);
// setCoordinatesFrom(div.target.attributes[1].value);
// } else {
// setAddressTo(div.target.attributes[2].value);
// setCoordinatesTo(div.target.attributes[1].value);
// }
// setShowModalEnd(false);
// }
useEffect(() => {
if (addressFrom.label && addressFrom.label.length > 0) {
geocodeByAddress(addressFrom.label)
.then((results) => getLatLng(results[0]))
.then(({ lat, lng }) => setCoordinatesFrom({ lat, lng }));
}
}, [addressFrom]);
useEffect(() => {
if (addressTo.label && addressTo.label.length > 0) {
geocodeByAddress(addressTo.label)
.then((results) => getLatLng(results[0]))
.then(({ lat, lng }) => setCoordinatesTo({ lat, lng }));
}
}, [addressTo]);
async function buscarItinerarios() {
if (!coordinatesFrom || !coordinatesTo || !addressFrom || !addressTo) {
return;
}
const maxRecentSearchesLength = 0;
if (recentSearches.length >= maxRecentSearchesLength) {
setRecentSearches(
recentSearches.slice(recentSearches.length - maxRecentSearchesLength)
);
}
setRecentSearches((arr) => [
...arr,
{
addressFrom: addressFrom.label,
addressTo: addressTo.label,
time: Date.now(),
},
]);
await itinerariesService
.searchItineraries({
coordinatesFrom,
coordinatesTo,
})
.then((response) => {
// if (response.status === "error") {
// setToastColor("danger");
// setMessageToast(response.message);
// setShowToast(true);
// return;
// }
setItinerariesList(response);
})
.catch((err) => {
setToastColor("danger");
setMessageToast(err);
setShowToast(true);
});
}
function fillSearchBars(addressFrom: string, addressTo: string) {
// setAddressFrom(addressFrom);
// setAddressTo(addressTo);
}
return (
<IonPage>
<PageHeader
pageName="Buscar itinerários"
backButtonPageUrl="/buscas"
></PageHeader>
<IonContent fullscreen>
<IonCard>
<IonCardContent>
<div className="inputs-from-to">
<IonIcon icon={locateOutline}></IonIcon>
{/* <IonSearchbar
showClearButton="never"
onClick={() => setInputActiveOpenModal("from")}
value={addressFrom}
placeholder="R. José Paulino, 1234 - Centro, Campinas - SP, 13013-001"
/> */}
{/* <GooglePlacesAutocomplete
apiKey={process.env.REACT_APP_KEY_API}
apiOptions={{ language: "pt-br", region: "br" }}
selectProps={{
value: addressFrom,
onChange: setAddressFrom,
className: "input-autocomplete",
placeholder: "R. José Paulino, 1234",
}}
/> */}
</div>
<div className="inputs-from-to">
<IonIcon icon={locationOutline}></IonIcon>
{/* <IonSearchbar
showClearButton="never"
onClick={() => setInputActiveOpenModal("to")}
value={addressTo}
placeholder="PUC Campinas"
/> */}
{/* <GooglePlacesAutocomplete
apiKey={process.env.REACT_APP_KEY_API}
apiOptions={{ language: "pt-br", region: "br" }}
selectProps={{
value: addressTo,
onChange: setAddressTo,
className: "input-autocomplete",
placeholder: "PUC Campinas",
}}
/> */}
</div>
<div className="button-search">
<IonButton color="primary" onClick={() => buscarItinerarios()}>
Buscar
</IonButton>
</div>
</IonCardContent>
</IonCard>
{recentSearches && recentSearches.length !== 0 ? (
<>
<IonItemDivider color="dark">Pesquisas recentes</IonItemDivider>
<IonRow class="latest-searches">
{recentSearches.map((search, index) => {
return (
<>
<div>
<IonRow
key={index}
class="latest-searches"
onClick={() => {
fillSearchBars(search.addressFrom, search.addressTo);
}}
>
<IonIcon
className="icon-align-vcenter"
size="large"
icon={timeOutline}
></IonIcon>
<div className="div_from_to">
<span>{search.addressFrom}</span>
<IonIcon icon={arrowForwardOutline}></IonIcon>
<span>{search.addressTo}</span>
<br />
<small>{search.time}</small>
</div>
<IonIcon
className="icon-forward icon-align-vcenter"
size="large"
icon={chevronForwardOutline}
></IonIcon>
</IonRow>
</div>
</>
);
})}
</IonRow>
</>
) : (
<></>
)}
{/* <IonRow class="latest-searches">
<IonIcon
className="icon-align-vcenter"
size="large"
icon={timeOutline}
/>
<div className="div_from_to">
<span>Taquaral</span>
<IonIcon icon={arrowForwardOutline}></IonIcon>
<span>PUC-Campinas</span>
<br />
<small>Há 2 hora</small>
</div>
<IonIcon
className="icon-forward icon-align-vcenter"
size="large"
icon={chevronForwardOutline}
/>
</IonRow> */}
{/* <IonModal isOpen={showModalEnd}>
<IonContent>
<div className="header-search-modal">
<IonIcon
className="icon-return-modal"
icon={arrowBack}
onClick={() => setShowModalEnd(false)}
/>
<IonInput
onIonChange={(e) => optionsAddress(e.detail.value)}
placeholder="R. José Paulino, 1234 - Centro, Campinas - SP, 13013-001"
className="search-modal"
/>
</div>
{addressResults.length > 0 ? (
addressResults.map((item: any) => {
return (
<div
key={item.value}
className="modal-search-results"
data-value={item.value}
data-label={item.label}
onClick={(e) => setAddress(e)}
>
{item.label}
<IonIcon
className="icon-results-modal"
icon={chevronForwardOutline}
/>
</div>
);
})
) : (
<>
<IonProgressBar type="indeterminate" />
<br />
</>
)}
</IonContent>
</IonModal> */}
{itinerariesList && itinerariesList.length !== 0 ? (
<>
<IonItemDivider color="secondary">Resultados</IonItemDivider>
{itinerariesList.map((itinerary, index) => {
return (
<IonCard
button
key={index}
onClick={() => {
history.push(`/itinerary/${itinerary.id_itinerary}`);
}}
>
<IonCardHeader>
<IonCardTitle>{itinerary.itinerary_nickname}</IonCardTitle>
<IonCardSubtitle>
<p>
<IonIcon icon={personOutline} /> Vagas disponíveis:{" "}
{itinerary.available_seats}
</p>
<p>
<IonIcon icon={starOutline} /> Motorista:{" "}
{itinerary.price}
</p>
<p>
<IonIcon icon={cashOutline} /> Valor:{" "}
{itinerary.vehicle_plate}
</p>
</IonCardSubtitle>
</IonCardHeader>
</IonCard>
);
})}
</>
) : (
<></>
)}
<IonToast
color={toastColor}
isOpen={showToast}
onDidDismiss={() => closeToast(setShowToast)}
message={messageToast}
duration={2500}
/>
</IonContent>
</IonPage>
);
};
export default BuscarItinerario;

View File

@@ -12,6 +12,7 @@ import { Map, Marker, Overlay } from "pigeon-maps";
import { maptiler } from "pigeon-maps/providers";
import { useEffect, useState } from "react";
import { PageHeader } from "../../components/PageHeader";
import { UserSearchInfos } from "../../components/UserSearchInfos/UserSearchInfos";
import { getUsersSearching } from "../../services/api/users";
import RecordsStore from "../../store/RecordsStore";
@@ -97,6 +98,10 @@ const BuscarPassageiro: React.FC = () => {
return (
<IonPage>
<PageHeader
pageName="Buscar passageiros"
backButtonPageUrl="/buscas"
></PageHeader>
<IonContent fullscreen>
{/* { results &&
<> */}

View File

@@ -1,233 +0,0 @@
import {
IonButton,
IonCard,
IonCardContent,
IonContent,
IonIcon,
IonPage,
IonRow,
} from "@ionic/react";
import {
arrowForwardOutline,
chevronForwardOutline,
locateOutline,
locationOutline,
timeOutline,
} from "ionicons/icons";
import "./BuscarTransporte.css";
import { useState } from "react";
import { useHistory } from "react-router";
// import GooglePlacesAutocomplete, {
// geocodeByAddress,
// getLatLng,
// } from "react-google-places-autocomplete";
const BuscarTransporte: React.FC = () => {
const history = useHistory();
const [addressFrom, setAddressFrom] = useState<any>("");
const [coordinatesFrom, setCoordinatesFrom] = useState<any>("");
const [addressTo, setAddressTo] = useState<any>("");
const [coordinatesTo, setCoordinatesTo] = useState<any>("");
const [showModalEnd, setShowModalEnd] = useState(false);
const [addressResults, setAddressResults] = useState<any>([]);
const [inputActive, setInputActive] = useState("");
// const optionsAddress = async (inputValue: any) => {
// let results = await autoCompleteAddress(inputValue)
// .then((res) => {
// return res.map((item: any) => {
// return {
// value:
// item.geometry.coordinates[0] + "," + item.geometry.coordinates[1],
// label: item.properties.formatted,
// };
// });
// })
// .catch((err) => {
// console.log("Erro ao buscar endereço:", err);
// });
// setAddressResults(results);
// };
// function setInputActiveOpenModal(input: string) {
// setInputActive(input);
// setShowModalEnd(true);
// }
// function setAddress(div: any) {
// if (inputActive === "from") {
// setAddressFrom(div.target.attributes[2].value);
// setCoordinatesFrom(div.target.attributes[1].value);
// } else {
// setAddressTo(div.target.attributes[2].value);
// setCoordinatesTo(div.target.attributes[1].value);
// }
// setShowModalEnd(false);
// }
// useEffect(() => {
// if (addressFrom.label && addressFrom.label.length > 0) {
// geocodeByAddress(addressFrom.label)
// .then((results) => getLatLng(results[0]))
// .then(({ lat, lng }) => setCoordinatesFrom({ lat, lng }));
// }
// }, [addressFrom]);
// useEffect(() => {
// if (addressTo.label && addressTo.label.length > 0) {
// geocodeByAddress(addressTo.label)
// .then((results) => getLatLng(results[0]))
// .then(({ lat, lng }) => setCoordinatesTo({ lat, lng }));
// }
// }, [addressTo]);
function buscaTransporte() {
if (coordinatesFrom && coordinatesTo && addressFrom && addressTo) {
history.push({
pathname: "/transportes",
state: {
coordinatesFrom,
coordinatesTo,
addressFrom,
addressTo,
},
});
}
}
return (
<IonPage>
<IonContent fullscreen>
<IonCard>
<IonCardContent>
<div className="inputs-from-to">
<IonIcon icon={locateOutline}></IonIcon>
{/* <IonSearchbar
showClearButton="never"
onClick={() => setInputActiveOpenModal("from")}
value={addressFrom}
placeholder="R. José Paulino, 1234 - Centro, Campinas - SP, 13013-001"
/> */}
{/* <GooglePlacesAutocomplete
apiKey={process.env.REACT_APP_KEY_API}
apiOptions={{ language: "pt-br", region: "br" }}
selectProps={{
value: addressFrom,
onChange: setAddressFrom,
className: "input-autocomplete",
placeholder: "R. José Paulino, 1234",
}}
/> */}
</div>
<div className="inputs-from-to">
<IonIcon icon={locationOutline}></IonIcon>
{/* <IonSearchbar
showClearButton="never"
onClick={() => setInputActiveOpenModal("to")}
value={addressTo}
placeholder="PUC Campinas"
/> */}
{/* <GooglePlacesAutocomplete
apiKey={process.env.REACT_APP_KEY_API}
apiOptions={{ language: "pt-br", region: "br" }}
selectProps={{
value: addressTo,
onChange: setAddressTo,
className: "input-autocomplete",
placeholder: "PUC Campinas",
}}
/> */}
</div>
<div className="button-search">
<IonButton color="primary" onClick={() => buscaTransporte()}>
Buscar
</IonButton>
</div>
</IonCardContent>
</IonCard>
<IonRow class="latest-searches">
<IonIcon
className="icon-align-vcenter"
size="large"
icon={timeOutline}
></IonIcon>
<div className="div_from_to">
<span>Rua Tal Tal, 154, São Paulo - SP</span>
<IonIcon icon={arrowForwardOutline}></IonIcon>
<span>USP</span>
<br />
<small> 1 hora</small>
</div>
<IonIcon
className="icon-forward icon-align-vcenter"
size="large"
icon={chevronForwardOutline}
></IonIcon>
</IonRow>
<IonRow class="latest-searches">
<IonIcon
className="icon-align-vcenter"
size="large"
icon={timeOutline}
/>
<div className="div_from_to">
<span>Taquaral</span>
<IonIcon icon={arrowForwardOutline}></IonIcon>
<span>PUC-Campinas</span>
<br />
<small> 2 hora</small>
</div>
<IonIcon
className="icon-forward icon-align-vcenter"
size="large"
icon={chevronForwardOutline}
/>
</IonRow>
{/* <IonModal isOpen={showModalEnd}>
<IonContent>
<div className="header-search-modal">
<IonIcon
className="icon-return-modal"
icon={arrowBack}
onClick={() => setShowModalEnd(false)}
/>
<IonInput
onIonChange={(e) => optionsAddress(e.detail.value)}
placeholder="R. José Paulino, 1234 - Centro, Campinas - SP, 13013-001"
className="search-modal"
/>
</div>
{addressResults.length > 0 ? (
addressResults.map((item: any) => {
return (
<div
key={item.value}
className="modal-search-results"
data-value={item.value}
data-label={item.label}
onClick={(e) => setAddress(e)}
>
{item.label}
<IonIcon
className="icon-results-modal"
icon={chevronForwardOutline}
/>
</div>
);
})
) : (
<>
<IonProgressBar type="indeterminate" />
<br />
</>
)}
</IonContent>
</IonModal> */}
</IonContent>
</IonPage>
);
};
export default BuscarTransporte;

64
src/pages/Buscas.tsx Normal file
View File

@@ -0,0 +1,64 @@
import { IonCard, IonCardContent, IonCardHeader, IonCardSubtitle, IonCardTitle, IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from "@ionic/react";
import { useEffect, useState } from "react";
import { useHistory } from "react-router";
import { PageHeader } from "../components/PageHeader";
const Buscas: React.FC = () => {
useEffect(() => {}, []);
const history = useHistory();
return (
<IonPage>
<PageHeader
pageName="Buscas"
></PageHeader>
<IonContent fullscreen>
<IonCard button class="cardItem" onClick={ () => history.push({ pathname: "/buscar/itinerario"}) }>
<img src="https://images.unsplash.com/photo-1561361513-2d000a50f0dc?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8dmFufGVufDB8fDB8fA%3D%3D&w=1000&q=80" />
<IonCardHeader>
<IonCardTitle>Buscar itinerários</IonCardTitle>
</IonCardHeader>
<IonCardContent>
Clique aqui para buscar por itinerários
</IonCardContent>
</IonCard>
<IonCard button class="cardItem" onClick={ () => history.push({ pathname: "/buscar/passageiro"}) }>
<img src="https://media.istockphoto.com/photos/male-passenger-using-laptop-during-flight-picture-id926203958?k=20&m=926203958&s=612x612&w=0&h=o52_eychVRRum6U5Q8C3bVxpnyXzcueqo1I52bhI-KA=" />
<IonCardHeader>
<IonCardTitle>Buscar passageiros</IonCardTitle>
</IonCardHeader>
<IonCardContent>
Clique aqui para buscar por passageiros
</IonCardContent>
</IonCard>
{/* <IonCard button onClick={ () => history.push({ pathname: "/buscar-transporte"}) }>
<IonCardHeader>
<IonCardTitle>/buscar-transporte</IonCardTitle>
</IonCardHeader>
<IonCardContent>
Clique aqui para buscar por transportes
</IonCardContent>
</IonCard>
<IonCard button onClick={ () => history.push({ pathname: "/buscar-passageiro"}) }>
<IonCardHeader>
<IonCardTitle>/buscar-passageiro</IonCardTitle>
</IonCardHeader>
<IonCardContent>
Clique aqui para buscar por passageiros
</IonCardContent>
</IonCard> */}
</IonContent>
</IonPage>
);
};
export default Buscas;

View File

@@ -1,12 +1,9 @@
import { Color } from "@ionic/core";
import {
IonBackButton,
IonButton,
IonButtons,
IonCheckbox,
IonContent,
IonDatetime,
IonHeader,
IonIcon,
IonInput,
IonItem,
@@ -18,9 +15,7 @@ import {
IonSelectOption,
IonSlide,
IonSlides,
IonTitle,
IonToast,
IonToolbar,
} from "@ionic/react";
import {
add,
@@ -28,7 +23,6 @@ import {
arrowBack,
arrowForward,
checkmark,
close,
informationCircle,
locateOutline,
locationOutline,
@@ -184,14 +178,11 @@ export default function CadastrarItinerario() {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Cadastrar Itinerário</IonTitle>
<IonButtons slot="start">
<IonBackButton icon={close} text="" defaultHref="/perfil" />
</IonButtons>
</IonToolbar>
</IonHeader>
<PageHeader
pageName="Cadastrar itinerário"
backButtonPageUrl="/perfil"
></PageHeader>
<IonContent fullscreen>
<IonSlides ref={mySlides} options={slideOpts}>
<IonSlide>

View File

@@ -1,28 +1,25 @@
import { Color } from "@ionic/core";
import {
IonBackButton,
IonButton,
IonButtons,
IonCardTitle,
IonCol,
IonContent,
IonGrid,
IonHeader,
IonInput,
IonItem,
IonLabel,
IonPage,
IonRow,
IonToast,
IonToolbar,
} from "@ionic/react";
import { arrowBack } from "ionicons/icons";
import { useContext, useState } from "react";
import { useHistory, useParams } from "react-router";
import { UserContext } from "../../App";
import { Action } from "../../components/Action";
import { PageHeader } from "../../components/PageHeader";
import LocalStorage from "../../LocalStorage";
import * as UsersService from "../../services/api/users";
import { closeToast } from "../../services/utils";
import "./Cadastro.css";
const Cadastro: React.FC = () => {
@@ -154,13 +151,8 @@ const Cadastro: React.FC = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonBackButton text={""} icon={arrowBack} defaultHref="login" />
</IonButtons>
</IonToolbar>
</IonHeader>
<PageHeader pageName="Cadastro" backButtonPageUrl="/login"></PageHeader>
<IonContent fullscreen>
<IonGrid className="ion-padding">
<IonRow>
@@ -246,7 +238,7 @@ const Cadastro: React.FC = () => {
<IonToast
color={toastColor}
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
onDidDismiss={() => closeToast(setShowToast)}
message={messageToast}
duration={2500}
/>

View File

@@ -1,17 +1,12 @@
import {
IonBackButton,
IonButtons,
IonCard,
IonCardContent,
IonContent,
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonPage,
IonTitle,
IonToast,
IonToolbar,
} from "@ionic/react";
import React, { useEffect, useState } from "react";
@@ -20,7 +15,8 @@ import { useHistory, useLocation } from "react-router";
import "../Perfil.css";
import { Color } from "@ionic/core";
import "../Cadastro/Cadastro.css";
import { PageHeader } from "../../components/PageHeader";
import { closeToast } from "../../services/utils";
interface cardItem {
icon: string;
@@ -108,14 +104,10 @@ const CadastroCompletar: React.FC = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Completar cadastro</IonTitle>
<IonButtons slot="start">
<IonBackButton defaultHref="/perfil" />
</IonButtons>
</IonToolbar>
</IonHeader>
<PageHeader
pageName="Completar cadastro"
backButtonPageUrl="/perfil"
></PageHeader>
<IonContent>
{items.map((item, index) => {
@@ -141,7 +133,7 @@ const CadastroCompletar: React.FC = () => {
position="top"
color={toastColor}
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
onDidDismiss={() => closeToast(setShowToast)}
message={toastMessage}
duration={2500}
/>

View File

@@ -28,6 +28,8 @@ import { saveOutline } from "ionicons/icons";
import * as usersRoutes from '../../services/api/users';
import validateCpf from '../../services/validateCpf'
import { closeToast } from "../../services/utils";
import { PageHeader } from "../../components/PageHeader";
interface documentTypesInterface {
label: string;
@@ -154,22 +156,12 @@ const CompletarDocumento: React.FC = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Completar cadastro</IonTitle>
<IonButtons slot="start">
<IonBackButton defaultHref="/perfil/completar" />
</IonButtons>
</IonToolbar>
</IonHeader>
<PageHeader
pageName="Completar cadastro"
backButtonPageUrl="/perfil/completar"
></PageHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Completar cadastro</IonTitle>
</IonToolbar>
</IonHeader>
<IonGrid>
<IonRow>
<IonCol>
@@ -206,7 +198,7 @@ const CompletarDocumento: React.FC = () => {
position="top"
color='danger'
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
onDidDismiss={() => closeToast(setShowToast)}
message={messageToast}
duration={2500}
/>

View File

@@ -25,6 +25,8 @@ import { saveOutline } from "ionicons/icons";
import * as usersRoutes from '../../services/api/users';
import { Color } from "@ionic/core";
import { closeToast } from "../../services/utils";
import { PageHeader } from "../../components/PageHeader";
interface documentTypesInterface {
label: string;
@@ -112,22 +114,12 @@ const CompletarTelefone: React.FC = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Completar cadastro</IonTitle>
<IonButtons slot="start">
<IonBackButton defaultHref="/perfil/completar" />
</IonButtons>
</IonToolbar>
</IonHeader>
<PageHeader
pageName="Completar cadastro"
backButtonPageUrl="/perfil/completar"
></PageHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Completar cadastro</IonTitle>
</IonToolbar>
</IonHeader>
<IonGrid>
<IonRow>
<IonCol>
@@ -156,7 +148,7 @@ const CompletarTelefone: React.FC = () => {
position="top"
color={toastColor}
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
onDidDismiss={() => closeToast(setShowToast)}
message={messageToast}
duration={2500}
/>

58
src/pages/Debug.tsx Normal file
View File

@@ -0,0 +1,58 @@
import {
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar,
} from "@ionic/react";
import React, { useContext, useState } from "react";
import { IonGrid, IonRow, IonCol, IonToast } from "@ionic/react";
import { useHistory } from "react-router-dom";
import { IonItem, IonLabel, IonInput, IonButton } from "@ionic/react";
import { UserContext } from "../App";
import { PageHeader } from "../components/PageHeader";
const Debug: React.FC = () => {
const [input, setInput] = useState("");
return (
<IonPage>
<PageHeader pageName="Debug" backButtonPageUrl="/home"></PageHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Debug</IonTitle>
</IonToolbar>
</IonHeader>
<IonGrid>
<IonRow>
<IonCol>
<IonItem>
<IonLabel position="floating"> Input</IonLabel>
<IonInput
type="date"
value={input}
// onIonChange={(e) => { setInput(e.detail.value!) }}
></IonInput>
</IonItem>
<IonButton
onClick={(e) => {
setInput("1994-12-15");
console.log(input);
}}
>
Enviar
</IonButton>
</IonCol>
</IonRow>
</IonGrid>
</IonContent>
</IonPage>
);
};
export default Debug;

View File

@@ -1,11 +1,12 @@
import { IonContent, IonPage, IonToast } from '@ionic/react';
import { Color } from '@ionic/core';
import { useContext, useEffect, useState } from 'react';
import { useLocation } from 'react-router';
import { useHistory, useLocation } from 'react-router';
import { UserContext } from '../App';
import * as sessionRoutes from '../services/api/session';
import { closeToast } from '../services/utils';
interface LocationState {
redirectData?: {
@@ -17,6 +18,7 @@ interface LocationState {
const Home: React.FC = () => {
const location = useLocation<LocationState>();
const history = useHistory();
const user = useContext(UserContext);
@@ -41,6 +43,7 @@ const Home: React.FC = () => {
// setMessageToast(response.message);
// setShowToast(true);
history.push(`/login`)
return
}
@@ -52,11 +55,12 @@ const Home: React.FC = () => {
// if (error.response.data.message) {
console.dir('Houve um erro: ', { error })
alert('Houve um erro')
history.push(`/login`)
})
}
refreshUserToken()
}, [])
}, [location.state, user, history])
return (
<IonPage>
@@ -65,7 +69,7 @@ const Home: React.FC = () => {
position="top"
color={toastColor}
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
onDidDismiss={() => closeToast(setShowToast)}
message={toastMessage}
duration={2500}
/>

View File

@@ -1,4 +1,3 @@
import { Color } from "@ionic/core";
import {
IonBackButton,
IonButtons,
@@ -9,19 +8,28 @@ import {
IonCardTitle,
IonContent,
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonPage,
IonTitle,
IonToast,
IonToolbar,
} from "@ionic/react";
import { useEffect, useState } from "react";
import { useHistory } from "react-router";
import { Color } from "@ionic/core";
import { carOutline } from "ionicons/icons";
import { useContext, useEffect, useState } from "react";
import { useHistory, useLocation } from "react-router";
import * as vansRoutes from "../services/api/vans";
import { UserContext } from "../App";
import * as vehiclesRoutes from "../services/api/vehicles";
import sessionsService from "../services/functions/sessionsService";
import { closeToast } from "../services/utils";
import { PageHeader } from "../components/PageHeader";
interface VanInfo {
interface VehicleInfo {
plate: string;
brand: string;
model: string;
@@ -34,21 +42,21 @@ interface VanInfo {
locator_state: string;
}
const MinhasVans: React.FC = () => {
const Itinerario: 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 [userVehicles, setUserVehicles] = useState<VehicleInfo[]>();
const redirectUserToLogin = () => {
history.push({ pathname: "/login" });
};
useEffect(() => {
const getUserVans = async () => {
const getUserVehicles = async () => {
let userId = "";
const refreshSessionRes = await sessionsService.refreshSession();
@@ -62,7 +70,7 @@ const MinhasVans: React.FC = () => {
userId = refreshSessionRes.userId;
}
vansRoutes
vehiclesRoutes
.getByUserId(userId)
.then((response) => {
if (response.status === "error") {
@@ -73,7 +81,7 @@ const MinhasVans: React.FC = () => {
return;
}
setUserVans(response.data);
setUserVehicles(response.data);
})
.catch((err) => {
setToastColor("danger");
@@ -82,41 +90,37 @@ const MinhasVans: React.FC = () => {
});
};
getUserVans();
getUserVehicles();
}, []);
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Minhas vans</IonTitle>
<IonButtons slot="start">
<IonBackButton defaultHref="/perfil" />
</IonButtons>
</IonToolbar>
</IonHeader>
<PageHeader
pageName="Minhas vehicles"
backButtonPageUrl="/perfil"
></PageHeader>
<IonContent>
{userVans ? (
userVans.map((van, index) => {
{userVehicles ? (
userVehicles.map((vehicle, index) => {
return (
<IonCard key={index}>
<IonCardHeader>
<IonCardTitle>{van.plate}</IonCardTitle>
<IonCardTitle>{vehicle.plate}</IonCardTitle>
<IonCardSubtitle>
{van.brand} - {van.model}
{vehicle.brand} - {vehicle.model}
</IonCardSubtitle>
</IonCardHeader>
{van.locator_name ? (
{vehicle.locator_name ? (
<>
<IonCardContent>
{van.seats_number} assentos - Locador: {van.locator_name}
{vehicle.seats_number} assentos - Locador: {vehicle.locator_name}
</IonCardContent>
</>
) : (
<>
<IonCardContent>
{van.seats_number} assentos - Não é alugado
{vehicle.seats_number} assentos - Não é alugado
</IonCardContent>
</>
)}
@@ -131,7 +135,7 @@ const MinhasVans: React.FC = () => {
position="top"
color={toastColor}
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
onDidDismiss={() => closeToast(setShowToast)}
message={toastMessage}
duration={2500}
/>
@@ -140,4 +144,4 @@ const MinhasVans: React.FC = () => {
);
};
export default MinhasVans;
export default Itinerario;

View File

@@ -3,30 +3,27 @@ import {
IonHeader,
IonPage,
IonTitle,
IonToolbar
IonToolbar,
} from "@ionic/react";
import React, { useContext, useState } from "react";
import { IonGrid, IonRow, IonCol, IonToast } from "@ionic/react";
import { useHistory } from "react-router-dom";
import {
IonItem,
IonLabel,
IonInput,
IonButton,
} from "@ionic/react";
import { IonItem, IonLabel, IonInput, IonButton } from "@ionic/react";
import * as sessionRoutes from '../services/api/session';
import LocalStorage from '../LocalStorage';
import * as sessionRoutes from "../services/api/session";
import LocalStorage from "../LocalStorage";
import { Action } from "../components/Action";
import { UserContext } from "../App";
import { closeToast } from "../services/utils";
import { PageHeader } from "../components/PageHeader";
const Page: React.FC = () => {
const [showToast, setShowToast] = useState(false);
const [messageToast, setMessageToast ] = useState('');
const [messageToast, setMessageToast] = useState("");
const history = useHistory();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const user = useContext(UserContext);
@@ -56,18 +53,18 @@ const Page: React.FC = () => {
return false;
}
if(password.length < 7 || password.length > 12) {
if (password.length < 7 || password.length > 12) {
setMessageToast("A senha deve conter entre 7 e 12 dígitos");
setShowToast(true);
return false;
}
return true;
}
};
const handleLogin = async () => {
if (!validateForm()) {
return
return;
}
const singinForm = {
@@ -75,50 +72,48 @@ const Page: React.FC = () => {
password: password,
};
await sessionRoutes.create(singinForm).then(response => {
if (response.status === 'error') {
await sessionRoutes
.create(singinForm)
.then((response) => {
if (response.status === "error") {
setMessageToast(response.message);
setShowToast(true);
return
return;
}
const { token } = response.token
const { token } = response.token;
LocalStorage.setToken(token);
user.setIsLoggedIn(true);
history.push({ pathname: '/home', state: { redirectData: {
history.push({
pathname: "/home",
state: {
redirectData: {
showToastMessage: true,
toastColor: "success",
toastMessage: "Usuário autenticado com sucesso!",
}}})
}).catch(error => {
},
},
});
})
.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')
})
console.dir("Houve um erro: ", { error });
alert("Houve um erro");
});
};
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Login</IonTitle>
</IonToolbar>
</IonHeader>
<PageHeader pageName="Login"></PageHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Login</IonTitle>
</IonToolbar>
</IonHeader>
<IonGrid>
<IonRow>
<IonCol>
@@ -152,7 +147,11 @@ const Page: React.FC = () => {
Login
</IonButton>
<p style={{ fontSize: "medium" }}>
<Action message="Ainda não possui uma conta?" text="Cadastre-se aqui!" link="/cadastro" />
<Action
message="Ainda não possui uma conta?"
text="Cadastre-se aqui!"
link="/cadastro"
/>
</p>
</IonCol>
</IonRow>
@@ -160,9 +159,9 @@ const Page: React.FC = () => {
<IonToast
position="top"
color='danger'
color="danger"
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
onDidDismiss={() => closeToast(setShowToast)}
message={messageToast}
duration={2500}
/>

View File

@@ -16,11 +16,12 @@ import {
} from "@ionic/react";
import { add, locateOutline, locationOutline } from "ionicons/icons";
import { useState } from "react";
import { PageHeader } from "../../components/PageHeader";
import "./MeusItinerarios.css";
interface ItineraryInfo {
id_itinerary: number;
van_plate: string;
vehicle_plate: string;
days_of_week: number;
specific_day: string;
estimated_departure_time: string;
@@ -35,7 +36,7 @@ export default function MeusItinerarios() {
[
{
id_itinerary: 1,
van_plate: 'FSS1918',
vehicle_plate: 'FSS1918',
days_of_week: 3,
specific_day: '24/08/2022',
estimated_departure_time: '10:00',
@@ -46,7 +47,7 @@ export default function MeusItinerarios() {
},
{
id_itinerary: 1,
van_plate: 'FSS1918',
vehicle_plate: 'FSS1918',
days_of_week: 3,
specific_day: '24/08/2022',
estimated_departure_time: '10:00',
@@ -57,7 +58,7 @@ export default function MeusItinerarios() {
},
{
id_itinerary: 1,
van_plate: 'FSS1918',
vehicle_plate: 'FSS1918',
days_of_week: 3,
specific_day: '24/08/2022',
estimated_departure_time: '10:00',
@@ -68,7 +69,7 @@ export default function MeusItinerarios() {
},
{
id_itinerary: 1,
van_plate: 'FSS1918',
vehicle_plate: 'FSS1918',
days_of_week: 3,
specific_day: '24/08/2022',
estimated_departure_time: '10:00',
@@ -79,7 +80,7 @@ export default function MeusItinerarios() {
},
{
id_itinerary: 1,
van_plate: 'FSS1918',
vehicle_plate: 'FSS1918',
days_of_week: 3,
specific_day: '24/08/2022',
estimated_departure_time: '10:00',
@@ -93,20 +94,12 @@ export default function MeusItinerarios() {
return (
<IonPage>
<IonHeader translucent>
<IonToolbar>
<IonTitle>Meus Itinerários</IonTitle>
<IonButtons slot="start">
<IonBackButton text={""} defaultHref="/perfil" />
</IonButtons>
</IonToolbar>
</IonHeader>
<PageHeader
pageName="Meus Itinerários"
backButtonPageUrl="/perfil"
></PageHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Meus Itinerários</IonTitle>
</IonToolbar>
</IonHeader>
{routes ? (
routes.map((itinerary, index) => {
return (

153
src/pages/MeusVeiculos.tsx Normal file
View File

@@ -0,0 +1,153 @@
import {
IonBackButton,
IonButtons,
IonCard,
IonCardContent,
IonCardHeader,
IonCardSubtitle,
IonCardTitle,
IonContent,
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonPage,
IonTitle,
IonToast,
IonToolbar,
} from "@ionic/react";
import { Color } from "@ionic/core";
import { carOutline, informationCircleOutline, peopleOutline } from "ionicons/icons";
import { useContext, useEffect, useState } from "react";
import { useHistory, useLocation } from "react-router";
import { UserContext } from "../App";
import * as vehiclesRoutes from "../services/api/vehicles";
import sessionsService from "../services/functions/sessionsService";
import { closeToast } from "../services/utils";
import { PageHeader } from "../components/PageHeader";
interface VehicleInfo {
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 MeusVeiculos: React.FC = () => {
const history = useHistory();
const [showToast, setShowToast] = useState(false);
const [toastMessage, setToastMessage] = useState("");
const [toastColor, setToastColor] = useState<Color>("primary");
const [vehiclesList, setVehiclesList] = useState<VehicleInfo[]>();
const redirectUserToLogin = () => {
history.push({ pathname: "/login" });
};
useEffect(() => {
const getUserVehiclesList = async () => {
let userId = "";
const refreshSessionRes = await sessionsService.refreshSession();
if (refreshSessionRes.error) {
redirectUserToLogin();
return;
}
if (refreshSessionRes.userId) {
userId = refreshSessionRes.userId;
}
vehiclesRoutes
.getByUserId(userId)
.then((response) => {
if (response.status === "error") {
setToastColor("danger");
setToastMessage(response.message);
setShowToast(true);
return;
}
setVehiclesList(response.data);
})
.catch((err) => {
setToastColor("danger");
setToastMessage(err);
setShowToast(true);
});
};
getUserVehiclesList();
}, []);
return (
<IonPage>
<PageHeader
pageName="Meus veículos"
backButtonPageUrl="/perfil"
></PageHeader>
<IonContent>
{vehiclesList ? (
<>
<IonCard color={"primary"}>
<IonCardContent>
<IonIcon icon={informationCircleOutline} /> Toque em um veículo cadastrado para ver suas viagens e itinerários!
</IonCardContent>
</IonCard>
{vehiclesList.map((vehicle, index) => {
return (
<IonCard button key={index}>
<img src="https://s2.glbimg.com/-xUhYluyWnnnib57vy3QI1kD9oQ=/1200x/smart/filters:cover():strip_icc()/i.s3.glbimg.com/v1/AUTH_cf9d035bf26b4646b105bd958f32089d/internal_photos/bs/2020/y/E/vdU7J0TeAIC2kZONmgBQ/2018-09-04-sprintervanfoto.jpg" />
<IonCardHeader>
<IonCardTitle>
{vehicle.brand} {vehicle.model}
</IonCardTitle>
<IonCardSubtitle>Placa: {vehicle.plate}</IonCardSubtitle>
</IonCardHeader>
<>
<IonCardContent>
<IonIcon icon={peopleOutline} size={"small"} />{" "}
{vehicle.seats_number} assentos -{" "}
{vehicle.locator_name ? (
<>Locador: {vehicle.locator_name}</>
) : (
<>Não é alugado</>
)}
</IonCardContent>
</>
</IonCard>
);
})}
</>
) : (
<></>
)}
<IonToast
position="top"
color={toastColor}
isOpen={showToast}
onDidDismiss={() => closeToast(setShowToast)}
message={toastMessage}
duration={2500}
/>
</IonContent>
</IonPage>
);
};
export default MeusVeiculos;

View File

@@ -1,23 +1,18 @@
import {
IonBackButton,
IonBadge,
IonButtons,
IonCard,
IonCardContent,
IonCardHeader,
IonCardTitle,
IonChip,
IonContent,
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonList,
IonListHeader,
IonPage,
IonTitle,
IonToast,
IonToolbar,
} from "@ionic/react";
import {
callOutline,
@@ -38,11 +33,13 @@ import "./Perfil.css";
import { Color } from "@ionic/core";
import { UserContext } from "../App";
import { PageHeader } from "../components/PageHeader";
import sessionsService from "../services/functions/sessionsService";
import {
checkIfUserIsDriver,
getById,
} from "../services/functions/usersService";
import { closeToast } from "../services/utils";
interface ScanNewProps {
match: {
@@ -214,22 +211,9 @@ const Perfil: React.FC<ScanNewProps> = (props) => {
return (
<IonPage>
<IonHeader translucent>
<IonToolbar>
<IonTitle>Seu perfil</IonTitle>
<IonButtons slot="start">
<IonBackButton text="" defaultHref="/home" />
</IonButtons>
</IonToolbar>
</IonHeader>
<PageHeader pageName="Meu perfil"></PageHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Seu perfil</IonTitle>
</IonToolbar>
</IonHeader>
<IonCard>
<IonCardContent>
<img
@@ -337,20 +321,20 @@ const Perfil: React.FC<ScanNewProps> = (props) => {
<IonItem
button
onClick={() => history.push({ pathname: "/cadastro-van" })}
onClick={() => history.push({ pathname: "/veiculos/cadastrar" })}
>
<IonIcon icon={carOutline} slot="start" />
<IonLabel>Cadastrar van</IonLabel>
<IonLabel>Cadastrar veículo</IonLabel>
</IonItem>
{isDriver ? (
<>
<IonItem
button
onClick={() => history.push({ pathname: "/minhas-vans" })}
onClick={() => history.push({ pathname: "/veiculos/meus" })}
>
<IonIcon icon={carOutline} slot="start" />
<IonLabel>Minhas vans</IonLabel>
<IonLabel>Meus veículos</IonLabel>
</IonItem>
<IonItem
button
@@ -405,7 +389,7 @@ const Perfil: React.FC<ScanNewProps> = (props) => {
position="top"
color={toastColor}
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
onDidDismiss={() => closeToast(setShowToast)}
message={toastMessage}
duration={2500}
/>

View File

@@ -14,21 +14,23 @@ import {
IonTextarea,
IonTitle,
IonToast,
IonToolbar
IonToolbar,
} from "@ionic/react";
import React, { useEffect, useReducer, useState } from "react";
import { IonRow, IonCol } from "@ionic/react";
import './Perfil.css'
import "./Perfil.css";
import { useHistory, useLocation } from "react-router";
import { saveOutline } from "ionicons/icons";
import isEqual from 'lodash.isequal';
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/core";
import { closeToast } from "../services/utils";
import { PageHeader } from "../components/PageHeader";
interface userData {
name: string;
@@ -39,7 +41,7 @@ interface userData {
}
interface LocationState {
userData: userData
userData: userData;
}
const PerfilEditar: React.FC = () => {
@@ -47,95 +49,99 @@ const PerfilEditar: React.FC = () => {
const location = useLocation<LocationState>();
const [showToast, setShowToast] = useState(false);
const [messageToast, setMessageToast] = useState('');
const [messageToast, setMessageToast] = useState("");
const [toastColor, setToastColor] = useState<Color>("primary");
const [userData, setUserData] = useState({
name: '',
lastname: '',
email: '',
birth_date: '',
bio: '',
name: "",
lastname: "",
email: "",
birth_date: "",
bio: "",
});
const [inputValues, setInputValues] = useReducer(
(state: any, newState: any) => ({ ...state, ...newState }),
{
name: '',
lastname: '',
email: '',
birth_date: '',
bio: '',
name: "",
lastname: "",
email: "",
birth_date: "",
bio: "",
}
);
useEffect(() => {
if (!location.state) {
history.push({ pathname: '/perfil' })
history.push({ pathname: "/perfil" });
}
let userData = location.state.userData
let userData = location.state.userData;
setUserData(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
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') {
setToastColor("danger")
usersRoutes
.update(inputValues)
.then((response) => {
if (response.status === "error") {
setToastColor("danger");
setMessageToast(response.message);
setShowToast(true);
return
return;
}
history.push({ pathname: '/perfil', state: {
history.push({
pathname: "/perfil",
state: {
redirectData: {
showToastMessage: true,
toastColor: "success",
toastMessage: response.message,
},
}})
}).catch((err) => {
setToastColor("danger")
},
});
})
.catch((err) => {
setToastColor("danger");
setMessageToast(err);
setShowToast(true);
})
}
});
};
const hasChangedSinceInitialState = () => {
return isEqual(userData, inputValues)
}
return isEqual(userData, inputValues);
};
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Editar perfil</IonTitle>
<IonButtons slot="start">
<IonBackButton defaultHref="/perfil" />
</IonButtons>
</IonToolbar>
</IonHeader>
<PageHeader
pageName="Editar perfil"
backButtonPageUrl="/perfil"
></PageHeader>
<IonContent>
<IonGrid>
<IonRow>
<IonCol size="12">
<div id='nome-sobrenome'>
<div id="nome-sobrenome">
<IonItem>
<IonLabel position="stacked"> Nome</IonLabel>
<IonInput
type="text"
value={inputValues.name}
onIonChange={(e) => setInputValues({'name': e.detail.value!})}
onIonChange={(e) =>
setInputValues({ name: e.detail.value! })
}
></IonInput>
</IonItem>
@@ -144,7 +150,9 @@ const PerfilEditar: React.FC = () => {
<IonInput
type="text"
value={inputValues.lastname}
onIonChange={(e) => setInputValues({'lastname': e.detail.value!})}
onIonChange={(e) =>
setInputValues({ lastname: e.detail.value! })
}
></IonInput>
</IonItem>
</div>
@@ -154,25 +162,28 @@ const PerfilEditar: React.FC = () => {
<IonInput
type="email"
value={inputValues.email}
onIonChange={(e) => setInputValues({'email': e.detail.value!})}
onIonChange={(e) =>
setInputValues({ email: e.detail.value! })
}
></IonInput>
</IonItem>
<IonItem>
<IonLabel position='stacked'>Data de nascimento</IonLabel>
<IonLabel position="stacked">Data de nascimento</IonLabel>
<IonInput
type='date'
type="date"
value={inputValues.birth_date}
onIonInput={(e: any) => setInputValues({'birth_date': e.detail.value!})}
>
</IonInput>
onIonChange={(e) =>
setInputValues({ birth_date: e.detail.value! })
}
></IonInput>
</IonItem>
<IonItem>
<IonLabel position="stacked"> Biografia</IonLabel>
<IonTextarea
value={inputValues.bio}
onIonChange={(e) => setInputValues({'bio': e.detail.value!})}
onIonChange={(e) => setInputValues({ bio: e.detail.value! })}
></IonTextarea>
</IonItem>
</IonCol>
@@ -180,7 +191,10 @@ const PerfilEditar: React.FC = () => {
</IonGrid>
<IonFab vertical="bottom" horizontal="end" slot="fixed">
<IonFabButton disabled={hasChangedSinceInitialState()} onClick={handleUpdateUserData}>
<IonFabButton
disabled={hasChangedSinceInitialState()}
onClick={handleUpdateUserData}
>
<IonIcon icon={saveOutline} />
</IonFabButton>
</IonFab>
@@ -188,7 +202,7 @@ const PerfilEditar: React.FC = () => {
<IonToast
color={toastColor}
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
onDidDismiss={() => closeToast(setShowToast)}
message={messageToast}
duration={2500}
/>

View File

@@ -28,7 +28,8 @@ import {
import { useEffect, useState } from "react";
import { useHistory, useLocation } from "react-router";
import { createUserSearch } from "../../services/api/users";
import { getTransportes } from "../../services/functions/transportsService";
import itinerariesService from "../../services/functions/itinerariesService";
import { closeToast } from "../../services/utils";
import "./Transportes.css";
interface InfoBusca {
@@ -42,7 +43,7 @@ const Transportes: React.FC = () => {
const history = useHistory();
const location = useLocation();
const props = location.state as InfoBusca;
const [transportes, setTransportes] = useState([]);
const [itinerarios, setItinerarios] = useState([]);
const [showModalFilters, setShowModalFilters] = useState(false);
const [showToast, setShowToast] = useState(false);
const [messageToast, setMessageToast] = useState("");
@@ -50,13 +51,13 @@ const Transportes: React.FC = () => {
useEffect(() => {
if (props) {
buscaTransportes();
buscaItinerarios();
}
}, [props]);
async function buscaTransportes() {
let data = (await getTransportes(props)) as any;
setTransportes(data);
async function buscaItinerarios() {
let data = (await itinerariesService.searchItineraries(props)) as any;
setItinerarios(data);
}
function criaAlerta() {
@@ -78,6 +79,7 @@ const Transportes: React.FC = () => {
return (
<IonPage>
{/* TODO, componentizar Header */}
<IonHeader>
<div className="header-page">
{/* <IonButtons slot="start">
@@ -95,7 +97,7 @@ const Transportes: React.FC = () => {
</div>
</IonHeader>
<IonContent fullscreen>
{transportes && transportes.length > 0 ? (
{itinerarios && itinerarios.length > 0 ? (
<div className="header-tabs">
<IonSlides>
<IonSlide>
@@ -117,8 +119,8 @@ const Transportes: React.FC = () => {
Não foi encontrado nenhum transporte que atenda essa rota.
</h1>
)}
{transportes &&
transportes.map((record: any, index: any) => {
{itinerarios &&
itinerarios.map((record: any, index: any) => {
return (
<IonCard className="card-transporte" key={index}>
<IonCardContent>
@@ -200,7 +202,7 @@ const Transportes: React.FC = () => {
// cssClass={"toast-notification"}
color={toastColor}
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
onDidDismiss={() => closeToast(setShowToast)}
message={messageToast}
duration={2500}
/>

View File

@@ -1,21 +1,22 @@
import {
IonToast,
IonItem,
IonLabel,
IonInput,
IonBackButton,
IonButton,
IonButtons,
IonCheckbox,
IonContent,
IonHeader,
IonInput,
IonItem,
IonLabel,
IonList,
IonListHeader,
IonPage,
IonToolbar,
IonTitle,
IonList,
IonCheckbox,
IonListHeader,
IonSelect,
IonSelectOption,
IonTitle,
IonToast,
IonToolbar,
IonItemDivider,
} from "@ionic/react";
import React, { useEffect, useReducer, useState } from "react";
@@ -25,22 +26,31 @@ import { useHistory } from "react-router-dom";
import carsService from "../services/functions/carsService";
import * as vansRoutes from "../services/api/vans";
import * as vehiclesRoutes from "../services/api/vehicles";
import "./VeiculoCadastro.css";
import { Color } from "@ionic/core";
import "./CadastroVan.css";
import { closeToast } from "../services/utils";
import { PageHeader } from "../components/PageHeader";
const CadastroVan: React.FC = () => {
const VeiculoCadastro: React.FC = () => {
const history = useHistory();
const [showToast, setShowToast] = useState<boolean>(false);
const [toastMessage, setToastMessage] = useState<string>("");
const [toastColor, setToastColor] = useState<Color>("primary");
const [carBrands, setCarBrands] = useState([
{
codigo: "",
nome: "",
},
]);
const [carModels, setCarModels] = useState([
{
id_model: "",
name: "",
codigo: "",
nome: "",
},
]);
@@ -70,7 +80,7 @@ const CadastroVan: React.FC = () => {
};
const validateForm = (): boolean => {
const vanForm = {
const vehicleForm = {
carPlate: inputValues.carPlate,
carBrand: inputValues.carBrand,
carModel: inputValues.carModel,
@@ -79,40 +89,40 @@ const CadastroVan: React.FC = () => {
};
if (
!vanForm.carPlate ||
vanForm.carPlate.length !== 7 ||
!vanForm.carPlate.match(/([A-z0-9]){7}/g)
!vehicleForm.carPlate ||
vehicleForm.carPlate.length !== 7 ||
!vehicleForm.carPlate.match(/([A-z0-9]){7}/g)
) {
setToastMessage("Placa do veículo inválida!");
setShowToast(true);
return false;
}
if (!vanForm.carBrand) {
if (!vehicleForm.carBrand) {
setToastMessage("Marca do veículo é obrigatório");
setShowToast(true);
return false;
}
if (!vanForm.carModel) {
if (!vehicleForm.carModel) {
setToastMessage("Modelo do veículo é obrigatório");
setShowToast(true);
return false;
}
if (!vanForm.seats_number || !parseInt(`${vanForm.seats_number}`)) {
if (!vehicleForm.seats_number || !parseInt(`${vehicleForm.seats_number}`)) {
setToastMessage("Número de passageiros inválido");
setShowToast(true);
return false;
}
if (Number(vanForm.seats_number) < 1) {
if (Number(vehicleForm.seats_number) < 1) {
setToastMessage("Número de passageiros deve ser positivo!");
setShowToast(true);
return false;
}
if (vanForm.isRented) {
if (vehicleForm.isRented) {
return validateRentalForm();
} else {
clearRentalData();
@@ -157,13 +167,28 @@ const CadastroVan: React.FC = () => {
return true;
};
const loadCarModels = async (carBrandId: string) => {
const carModelsRes = await carsService.getCarModels(carBrandId);
if (carModelsRes.error) {
setToastColor("danger");
setToastMessage(carModelsRes.error.errorMessage);
setInputValues({ carBrand: "" });
return;
}
if (carModelsRes.data) {
setCarModels(carModelsRes.data);
}
};
const handleSubmit = async () => {
if (!validateForm()) {
return;
}
// cria registro da van
await vansRoutes
// cria registro da vehicle
await vehiclesRoutes
.create({
plate: inputValues.carPlate,
brand: inputValues.carBrand,
@@ -184,7 +209,7 @@ const CadastroVan: React.FC = () => {
}
history.push({
pathname: "/minhas-vans",
pathname: "/minhas-vehicles",
state: {
redirectData: {
showToastMessage: true,
@@ -204,24 +229,24 @@ const CadastroVan: React.FC = () => {
useEffect(() => {
let isMounted = true;
const getCarsModels = async () => {
const carModelsRes = await carsService.getAllCarModels();
const getCarsBrands = async () => {
const carBrandsRes = await carsService.getAllCarBrands();
if (carModelsRes.error) {
if (carBrandsRes.error) {
setToastColor("danger");
setToastMessage(carModelsRes.error.errorMessage);
setToastMessage(carBrandsRes.error.errorMessage);
setShowToast(true);
return;
}
if (carModelsRes.data) {
if (carBrandsRes.data) {
if (isMounted) {
setCarModels(carModelsRes.data);
setCarBrands(carBrandsRes.data);
}
}
};
getCarsModels();
getCarsBrands();
return () => {
isMounted = false;
@@ -230,27 +255,20 @@ const CadastroVan: React.FC = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Cadastro de veículo</IonTitle>
<IonButtons slot="start">
<IonBackButton defaultHref="/perfil" />
</IonButtons>
</IonToolbar>
</IonHeader>
<PageHeader
pageName="Cadastro de veículo"
backButtonPageUrl="/perfil"
></PageHeader>
<IonContent>
<IonList lines="full" class="ion-no-margin">
<IonListHeader lines="full">
<IonLabel>Informações do veículo</IonLabel>
</IonListHeader>
<IonItemDivider color={"primary"}>Informações do veículo</IonItemDivider>
<IonItem>
<IonLabel position="floating">Placa </IonLabel>
<IonLabel position="fixed">Placa </IonLabel>
<IonInput
type="text"
clearInput
maxlength={7}
placeholder="Digite a Placa do Veículo"
onIonChange={(e: any) =>
setInputValues({ carPlate: e.target.value })
}
@@ -263,13 +281,14 @@ const CadastroVan: React.FC = () => {
<IonSelect
onIonChange={(e: any) => {
setInputValues({ carBrand: e.detail.value });
loadCarModels(e.detail.value);
}}
>
{carModels ? (
carModels.map((carModel, index) => {
{carBrands ? (
carBrands.map((carBrand, index) => {
return (
<IonSelectOption key={index} value={carModel.name}>
{carModel.name}
<IonSelectOption key={index} value={index}>
{carBrand.nome}
</IonSelectOption>
);
})
@@ -279,25 +298,37 @@ const CadastroVan: React.FC = () => {
</IonSelect>
</IonItem>
{inputValues.carBrand ? (
<IonItem>
<IonLabel position="floating">Modelo </IonLabel>
<IonInput
type="text"
clearInput
placeholder="Digite o Modelo do Veículo"
onIonChange={(e: any) =>
setInputValues({ carModel: e.target.value })
}
/>
<IonLabel>Modelo</IonLabel>
<IonSelect
onIonChange={(e: any) => {
setInputValues({ carModel: e.detail.value });
}}
>
{carModels ? (
carModels.map((carModel, index) => {
return (
<IonSelectOption key={index} value={carModel.nome}>
{carModel.nome}
</IonSelectOption>
);
})
) : (
<></>
)}
</IonSelect>
</IonItem>
) : (
<></>
)}
<IonItem>
<IonLabel position="floating">Número de assentos</IonLabel>
<IonLabel position="fixed">Nº assentos</IonLabel>
<IonInput
type="number"
min={1}
clearInput
placeholder="podem ser ocupados por passageiros"
onIonChange={(e: any) =>
setInputValues({ seats_number: e.target.value })
}
@@ -305,11 +336,9 @@ const CadastroVan: React.FC = () => {
</IonItem>
</IonList>
<IonList lines="full" class="ion-no-margin">
<IonListHeader lines="full">
<IonLabel>Informações do locador</IonLabel>
</IonListHeader>
<IonItemDivider color={"medium"}>Informações de locação</IonItemDivider>
<IonList lines="full" class="ion-no-margin">
<IonItem>
<IonLabel>O veículo é alugado?</IonLabel>
<IonCheckbox
@@ -321,7 +350,6 @@ const CadastroVan: React.FC = () => {
</IonItem>
{inputValues.isRented && (
<div>
<IonItem>
<IonLabel position="stacked" />
<IonInput
@@ -366,7 +394,6 @@ const CadastroVan: React.FC = () => {
}
/>
</IonItem>
</div>
)}
<div>
@@ -384,7 +411,7 @@ const CadastroVan: React.FC = () => {
position="top"
color={toastColor}
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
onDidDismiss={() => closeToast(setShowToast)}
message={toastMessage}
duration={2500}
/>
@@ -393,4 +420,4 @@ const CadastroVan: React.FC = () => {
);
};
export default CadastroVan;
export default VeiculoCadastro;

View File

@@ -16,10 +16,19 @@ function updateHeader() {
"Authorization": 'Bearer ' + token
}
}
export async function list() {
export async function listAllBrands() {
updateHeader();
const response = await instance.get(carsRoutes.list.url, { headers: header });
const response = await instance.get(carsRoutes.listAllBrands.url, { headers: header });
return response.data;
}
export async function listCarModels(carBrandId: string) {
updateHeader();
const response = await instance.get(carsRoutes.listCarModels.url + `/${carBrandId}`, { headers: header });
return response.data;
}

View File

@@ -0,0 +1,39 @@
import instance from './api';
// import LocalStorage from '../LocalStorage';
import transportsRoutes from '../../constants/routes/itinerariesRoutes';
import { AxiosRequestHeaders } from 'axios';
import LocalStorage from '../../LocalStorage';
import { setStore } from '../../store/RecordsStore';
let token: string;
let header: AxiosRequestHeaders;
function updateHeader() {
token = LocalStorage.getToken();
header = {
"Accept": 'application/json',
"Content-Type": 'application/json',
"Authorization": 'Bearer ' + token
}
}
export interface Coordinates {
lat: number,
lng: number
}
export async function get() {
updateHeader();
const response = await instance.get(transportsRoutes.get.url, { headers: header });
return response.data;
}
export async function search(coordinatesOrigin: Coordinates, coordinatesDestination: Coordinates) {
updateHeader();
const response = await instance.post(transportsRoutes.search.url, { coordinatesOrigin, coordinatesDestination }, { headers: header });
return response.data;
}

View File

@@ -1,40 +0,0 @@
import instance from "./api";
// import LocalStorage from '../LocalStorage';
import { AxiosRequestHeaders } from "axios";
import transportsRoutes from "../../constants/routes/transportsRoutes";
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 interface getTransportsRequest {
coordinatesFrom: {
lat: number;
lng: number;
};
coordinatesTo: {
lat: number;
lng: number;
};
}
export async function get(coordinates: getTransportsRequest) {
updateHeader();
const response = await instance.get(
transportsRoutes.get.url + `/${coordinates}`,
{ headers: header }
);
return response.data;
}

View File

@@ -1,6 +1,6 @@
import instance from "./api";
import vansRoutes from "../../constants/routes/vansRoutes";
import vehiclesRoutes from "../../constants/routes/vehiclesRoutes";
import { AxiosRequestHeaders } from "axios";
import LocalStorage from "../../LocalStorage";
@@ -17,10 +17,10 @@ function updateHeader() {
};
}
export async function getByPlate(vanId: string) {
export async function getByPlate(vehicleId: string) {
updateHeader();
const response = await instance.get(vansRoutes.getByPlate.url + `/${vanId}`, {
const response = await instance.get(vehiclesRoutes.getByPlate.url + `/${vehicleId}`, {
headers: header,
});
@@ -30,14 +30,14 @@ export async function getByPlate(vanId: string) {
export async function getByUserId(userId: string) {
updateHeader();
const response = await instance.get(vansRoutes.getByUserId.url + `/${userId}`, {
const response = await instance.get(vehiclesRoutes.getByUserId.url + `/${userId}`, {
headers: header,
});
return response.data;
}
interface CreateVanBody {
interface CreateVehicleBody {
plate: string;
brand: string;
model: string;
@@ -49,23 +49,23 @@ interface CreateVanBody {
locator_state: string;
}
export async function create(CreateVanBody: CreateVanBody) {
export async function create(CreateVehicleBody: CreateVehicleBody) {
updateHeader();
const response = await instance.post(vansRoutes.create.url, CreateVanBody, { headers: header });
const response = await instance.post(vehiclesRoutes.create.url, CreateVehicleBody, { headers: header });
return response.data;
}
interface UpdateVanBody {
interface UpdateVehicleBody {
brand?: string;
model?: string;
seats_number?: string;
}
export async function update(vanData: UpdateVanBody) {
export async function update(vehicleData: UpdateVehicleBody) {
updateHeader();
const response = await instance.patch(vansRoutes.update.url, vanData, {
const response = await instance.patch(vehiclesRoutes.update.url, vehicleData, {
headers: header,
});

View File

@@ -1,30 +1,29 @@
import * as carsRoutes from "../api/cars";
interface getAllCarModelsReturn {
data?: {
id_model: string;
name: string;
}[];
interface CarObject {
codigo: string;
nome: string;
}
interface getAllCarBrandsReturn {
data?: CarObject[];
error?: {
errorMessage: string;
};
}
interface getAllCarModelsRes {
interface getAllCarBrandsRes {
status?: string;
message: string;
data?: {
id_model: string;
name: string;
}[];
data?: CarObject[];
}
const getAllCarModels = async (): Promise<getAllCarModelsReturn> => {
const getAllCarBrands = async (): Promise<getAllCarBrandsReturn> => {
try {
let res: getAllCarModelsRes = await carsRoutes.list();
let res: getAllCarBrandsRes = await carsRoutes.listAllBrands();
if (res.status === "error") {
return {
@@ -40,14 +39,36 @@ const getAllCarModels = async (): Promise<getAllCarModelsReturn> => {
} catch (err) {
return {
error: {
errorMessage: "Por favor, autentique-se.",
errorMessage: "Por favor, tente novamente.",
},
};
}
};
const method = {
getAllCarModels,
const getCarModels = async (
carBrandId: string
): Promise<getAllCarBrandsReturn> => {
try {
let res: getAllCarBrandsRes = await carsRoutes.listCarModels(carBrandId);
if (res.status === "error") {
return {
error: {
errorMessage: res.message,
},
};
}
return {
data: res.data,
};
} catch (err) {
return {
error: {
errorMessage: "Por favor, tente novamente.",
},
};
}
};
export default method;
export default { getAllCarBrands, getCarModels };

View File

@@ -0,0 +1,38 @@
import * as itinerariesRoutes from '../api/itineraries';
interface CoordinatesRequest {
coordinatesFrom: {
lat: number,
lng: number
},
coordinatesTo: {
lat: number,
lng: number
}
}
export async function getAllItineraries(): Promise<any> {
let res: any;
try {
res = await itinerariesRoutes.get();
} catch (error) {
// TODO
}
return res.data
}
export async function searchItineraries({ coordinatesFrom, coordinatesTo }: CoordinatesRequest): Promise<any> {
let res: any
try {
res = await itinerariesRoutes.search(coordinatesFrom, coordinatesTo);
} catch (error) {
// TODO
}
return res.data
}
export default { getAllItineraries, searchItineraries }

View File

@@ -1,18 +0,0 @@
interface CoordinatesRequest {
coordinatesFrom: {
lat: number;
lng: number;
};
coordinatesTo: {
lat: number;
lng: number;
};
}
export async function getTransportes(
request: CoordinatesRequest
): Promise<any> {
try {
// let res : any = await transportsRoutes.get(request);
} catch (error) {}
}

View File

@@ -5,3 +5,8 @@ export async function autoCompleteAddress(address:string) {
const response = await instance.get(`https://api.geoapify.com/v1/geocode/autocomplete?text=${address}&apiKey=ee574aacff6f440a84378bbbf7e2f20d`);
return response.data.features;
}
export async function closeToast(setShowToast: React.Dispatch<React.SetStateAction<boolean>>) {
setShowToast(false)
window.history.replaceState({}, document.title)
}

12521
yarn.lock

File diff suppressed because it is too large Load Diff