Merge pull request #7 from CloudAlb/feature/buscar-transporte

Feature/buscar-transporte
This commit is contained in:
CloudAlb
2022-06-20 20:32:42 -03:00
committed by GitHub
20 changed files with 12731 additions and 294 deletions

653
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,7 @@
"lodash.isequal": "^4.5.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-google-places-autocomplete": "^3.3.4",
"react-hook-form": "^7.30.0",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",

View File

@@ -1,8 +1,8 @@
<!DOCTYPE html>
<html lang="en">
<html lang="pt-br">
<head>
<meta charset="utf-8" />
<title>Ionic App</title>
<title>Vanmos App</title>
<base href="/" />

View File

@@ -40,6 +40,10 @@ import '@ionic/react/css/display.css';
/* Theme variables */
import './theme/variables.css';
import BuscarPassageiro from './pages/BuscarPassageiro/BuscarPassageiro';
import Transportes from './pages/Transportes/Transportes';
import BuscarTransporte from './pages/BuscarTransporte/BuscarTransporte';
// import Tabs from './components/Tabs';
import { search, home, person } from 'ionicons/icons';
import { useState, useContext } from 'react';
import React from 'react';

View File

@@ -0,0 +1,60 @@
.overlayContainer {
display: flex;
flex-direction: column;
/* // align-items: center;
// align-content: center; */
padding: 1rem;
width: 12rem;
height: fit-content;
background-color: white;
border-radius: 5px;
box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
}
.overlayContainer ion-card-subtitle {
font-size: 0.7rem;
color: black;
}
.overlayContainer ion-note {
font-size: 0.6rem;
margin-bottom: 0.5rem;
}
.overlayContainer ion-badge {
margin-bottom: 1.5rem;
}
.overlayContainer p {
color: black;
padding: 0;
margin: 0;
margin-bottom: 0.3rem;
font-size: 0.6rem;
display: flex;
flex-direction: row;
align-items: center;
align-content: center;
}
.overlayContainer:after {
content:'';
position: absolute;
top: 100%;
left: 70%;
margin-left: -50px;
width: 0;
height: 0;
border-top: solid 10px white;
border-left: solid 10px transparent;
border-right: solid 10px transparent;
}

View File

@@ -0,0 +1,65 @@
import {
IonBadge,
IonButton,
IonCardSubtitle,
IonCol,
IonIcon,
IonNote,
IonRow,
} from "@ionic/react";
import {
arrowForward,
call,
callOutline,
navigateOutline,
} from "ionicons/icons";
import "./UserSearchInfos.css";
export const UserSearchInfos = (record: any) => {
console.log(record.record);
return (
<div className="overlayContainer">
<IonCardSubtitle>{record.record.user.name}</IonCardSubtitle>
{/* <IonNote color="medium">{ record.record.addressFrom }</IonNote> */}
<IonBadge color="dark">
{record.record.user.star_rating
? `${record.record.user.star_rating} estrelas`
: "Sem avaliações"}
</IonBadge>
<p>
<IonIcon icon={navigateOutline} size='large' />
&nbsp;{record.record.address_to}
</p>
{record.record.user.phone_number && (
<p>
<IonIcon icon={call} />
&nbsp;{record.record.user.phone_number}
</p>
)}
<IonRow className="ion-no-padding ion-no-margin ion-margin-top">
<IonCol size="12" className="ion-no-padding ion-no-margin">
<IonButton
color="primary"
fill="solid"
size="small"
expand="block"
routerLink={`/perfil/${record.record.user.id_user}`}
>
Ver mais informações &rarr;
</IonButton>
</IonCol>
</IonRow>
<IonRow className="ion-no-padding ion-no-margin">
<IonCol size="12" className="ion-no-padding ion-no-margin">
<IonButton color="primary" fill="outline" size="small" expand="block">
<IonIcon icon={callOutline} />
</IonButton>
</IonCol>
</IonRow>
</div>
);
};

View File

@@ -1,7 +0,0 @@
#nome-sobrenome{
display: flex;
}
.toast-notification{
--background: rgb(255, 0, 0);
}

View File

@@ -9,6 +9,7 @@ import { useEffect, useState } from 'react';
import RecordsStore from '../../store/RecordsStore';
import { fetchRecords } from '../../store/Selectors';
import { getUsersSearching } from '../../services/users';
import { UserSearchInfos } from '../../components/UserSearchInfos/UserSearchInfos';
const maptilerProvider = maptiler('d5JQJPLLuap8TkJJlTdJ', 'streets');
@@ -75,6 +76,18 @@ const BuscarPassageiro: React.FC = () => {
await getUsersSearching(currentPoint);
}
const showMarkerInfo = (e:any, index:any) => {
const tempRecords = JSON.parse(JSON.stringify(results));
// Hide all current marker infos
!tempRecords[index].showInfo && tempRecords.forEach((tempRecord:any) => tempRecord.showInfo = false);
tempRecords[index].showInfo = !tempRecords[index].showInfo;
console.log(tempRecords)
setResults(tempRecords);
}
return (
<IonPage>
<IonContent fullscreen>
@@ -82,21 +95,21 @@ const BuscarPassageiro: React.FC = () => {
<> */}
<Map onBoundsChanged={e => handleMap(e)} defaultCenter={ [center.latitude, center.longitude] } defaultZoom={ zoom } provider={ maptilerProvider } touchEvents={ true }>
{ results.map((record:{latitude:any, longitude:any}, index) => {
return <Marker key={ index } color="#3578e5" width={ 50 } anchor={ [ parseFloat(record.latitude), parseFloat(record.longitude) ] } />
{results && results.map((record:{latitude_from:any, longitude_from:any}, index) => {
return <Marker onClick={ e => showMarkerInfo(e, index) } key={ index } color="#3578e5" width={ 50 } anchor={ [ parseFloat(record.latitude_from), parseFloat(record.longitude_from) ] } />
})}
{/* { results.map((record:{showInfo:boolean, latitude:any, longitude:any}, index) => {
{ results.map((record:any, index) => {
if (record.showInfo) {
return (
<Overlay key={ index } anchor={ [ record.latitude, record.longitude ] } offset={[95, 304]}> */}
{/* <MapOverlay record={ record } /> */}
{/* </Overlay>
);
<Overlay key={ index } anchor={ [ parseFloat(record.latitude_from), parseFloat(record.longitude_from) ] } offset={[95, 304]}>
<UserSearchInfos record={ record } />
</Overlay>
)
}
})} */}
})}
</Map>
<IonFab vertical="bottom" horizontal="end" slot="fixed">

View File

@@ -0,0 +1,182 @@
import {
IonContent,
IonPage,
IonIcon,
IonCard,
IonInput,
IonRow,
IonCardContent,
IonButton,
IonSearchbar,
IonModal,
IonProgressBar,
} from "@ionic/react";
import {
arrowBack,
arrowForwardOutline,
chevronForwardOutline,
locateOutline,
locationOutline,
timeOutline,
} from "ionicons/icons";
import "./BuscarTransporte.css";
import { useEffect, useState } from "react";
import { autoCompleteAddress } from "../../services/utils";
import { useHistory } from "react-router";
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)
}
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"
/>
</div>
<div className="inputs-from-to">
<IonIcon icon={locationOutline}></IonIcon>
<IonSearchbar
showClearButton="never"
onClick={() => setInputActiveOpenModal("to")}
value={addressTo}
placeholder="PUC Campinas"
/>
</div>
<div className="button-search">
<IonButton color="primary" onClick={() => history.push("/transportes")}>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;

View File

@@ -0,0 +1,57 @@
.inputs-from-to{
display: flex;
align-items: center;
}
.button-search{
display: flex;
justify-content: center;
}
.latest-searches{
margin: 1rem;
}
.div_from_to{
max-width: 70%;
margin-inline: 1rem;
}
.icon-align-vcenter{
align-self: center;
}
.icon-forward{
margin-left: auto;
margin-right: 0;
}
.header-search-modal{
background-color: var(--ion-toolbar-background);
display: flex;
justify-content: center;
align-items: center;
border-radius: 1rem;
margin: 0.5rem;
}
.icon-return-modal{
font-size: 1.5rem;
}
.modal-search-results{
display: flex;
align-items: center;
margin: 1rem;
padding-bottom: 1rem;
border-bottom: 1px solid var(--ion-toolbar-border-color);
}
.icon-results-modal{
font-size: 2rem;
}
.input-autocomplete{
margin: 0.5rem 0 0.5rem 0.5rem;
width: 100%;
}

View File

@@ -0,0 +1,242 @@
import {
IonContent,
IonPage,
IonIcon,
IonCard,
IonInput,
IonRow,
IonCardContent,
IonButton,
IonSearchbar,
IonModal,
IonProgressBar,
} from "@ionic/react";
import {
arrowBack,
arrowForwardOutline,
chevronForwardOutline,
locateOutline,
locationOutline,
timeOutline,
} from "ionicons/icons";
import "./BuscarTransporte.css";
import { useEffect, useState } from "react";
import { autoCompleteAddress } from "../../services/utils";
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="AIzaSyAGfCsaNwxwyj4Ajtfy7MTNADE6JwmnZvA"
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="AIzaSyAGfCsaNwxwyj4Ajtfy7MTNADE6JwmnZvA"
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;

View File

@@ -151,7 +151,9 @@ const Cadastro: React.FC = () => {
<IonInput
type='text'
clearInput
onIonChange={(e: any) => setFirstName(e.target.value)}
onIonInput={(e: any) => setFirstName(e.target.value)}
// error={isError}
// onIonChange={(e: any) => setFirstName(e.detail.value)}
>
</IonInput>
</IonItem>

View File

@@ -1,51 +0,0 @@
import React, { useState, useRef } from 'react';
import {
IonTabs,
IonTabBar,
IonTabButton,
IonLabel,
IonPage,
IonIcon,
IonRouterOutlet
} from '@ionic/react';
import { Redirect, Route } from 'react-router-dom';
import { IonReactRouter } from '@ionic/react-router';
import { search, home, person } from 'ionicons/icons';
import Home from './Home';
import BuscarPassageiro from './BuscarPassageiro/BuscarPassageiro';
export const MainPages: React.FC = () => {
return (
<IonTabs>
<IonRouterOutlet>
<Route path="/home" exact={true}>
<Home />
</Route>
<Route path="/buscar" exact={true}>
<BuscarPassageiro />
</Route>
<Route path="/mainpages" render={() => <Redirect to="/buscar
" />} />
</IonRouterOutlet>
<IonTabBar slot="bottom">
<IonTabButton tab="buscar" href="/buscar">
<IonIcon icon={search} />
<IonLabel>Buscar</IonLabel>
</IonTabButton>
<IonTabButton tab="home" href="/home">
<IonIcon icon={home} />
<IonLabel>Home</IonLabel>
</IonTabButton>
<IonTabButton tab="perfil" href="/perfil">
<IonIcon icon={person} />
<IonLabel>Perfil</IonLabel>
</IonTabButton>
</IonTabBar>
</IonTabs>
)
}
export default MainPages;

View File

@@ -0,0 +1,78 @@
.header-page{
background-color: var(--ion-item-background);
border-bottom: 1px solid var(--ion-color-step-150, #dadada);
height: 3.5rem;
display: flex;
padding: 0.5rem;
}
.icon-return{
font-size: 1.5rem;
}
.span-info-back{
background-color: var(--ion-color-step-150, #dadada);
border-radius: 0.5rem;
padding: 0.5rem;
display: flex;
width: 100%;
}
.address-from-to{
/* display: block; */
margin-top: -0.2rem;
font-size: 0.8rem;
white-space: nowrap;
overflow: hidden;
max-width: 100%;
}
/* .address-from-to span{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 1rem!important;
} */
.address-from-to ion-icon{
margin-inline: 0.2rem;
}
.address-from-to small{
display: block;
}
.header-tabs{
background-color: var(--ion-color-step-150,#dadada);
height: 5.5rem;
padding: 0.5rem;
}
.header-tabs h5{
margin: 0;
}
.header-tabs .card-transporte{
margin: 0;
}
.content-filter-modal{
margin: 0.5rem;
}
.header-filter-modal{
display: flex;
justify-content: space-between;
align-items: center;
}
.button-criar-alerta{
display: flex;
justify-content: center;
align-items: center;
margin: 1rem 0 5.5rem 0;
}
.msg-not-found{
margin: 1.5rem;
}

View File

@@ -0,0 +1,222 @@
import {
IonContent,
IonPage,
IonFab,
IonFabButton,
IonIcon,
IonCard,
IonInput,
IonRow,
IonCol,
IonCardContent,
IonButton,
IonHeader,
IonToolbar,
IonButtons,
IonBackButton,
IonTabs,
IonTabBar,
IonTabButton,
IonLabel,
IonBadge,
IonRouterOutlet,
IonSlides,
IonSlide,
IonModal,
IonList,
IonRadioGroup,
IonListHeader,
IonItem,
IonRadio,
IonCheckbox,
IonFooter,
IonToast,
} from "@ionic/react";
import {
arrowBack,
arrowBackOutline,
arrowForwardOutline,
chevronBackOutline,
chevronForwardOutline,
closeOutline,
locateOutline,
locationOutline,
timeOutline,
} from "ionicons/icons";
import { useEffect, useState } from "react";
import { useHistory, useLocation } from "react-router";
import { getTransportes } from "../../services/transportes";
import { createUserSearch } from "../../services/users";
import "./Transportes.css";
interface InfoBusca {
addressFrom: any;
addressTo: any;
coordinatesFrom: any;
coordinatesTo: any;
}
const Transportes: React.FC = () => {
const history = useHistory();
const location = useLocation();
const props = location.state as InfoBusca;
const [transportes, setTransportes] = useState([]);
const [showModalFilters, setShowModalFilters] = useState(false);
const [showToast, setShowToast] = useState(false);
const [messageToast, setMessageToast ] = useState('');
const [toastColor, setToastColor] = useState('success');
useEffect(() => {
if (props) {
buscaTransportes();
}
}, [props]);
async function buscaTransportes() {
let data = (await getTransportes(props)) as any;
setTransportes(data);
}
function criaAlerta(){
createUserSearch(props.coordinatesFrom.lat, props.coordinatesFrom.lng, props.addressTo.label).then(() => {
setMessageToast('Alerta criado com sucesso!');
setShowToast(true);
}).catch((err:any) => {
setMessageToast('Não foi possível criar o alerta!');
setToastColor('danger');
setShowToast(true);
})
}
return (
<IonPage>
<IonHeader>
<div className="header-page">
{/* <IonButtons slot="start">
<IonBackButton text={'aaaa'} icon={arrowBack} defaultHref='buscar-transporte' />
</IonButtons> */}
<span className="span-info-back" onClick={history.goBack}>
<IonIcon className="icon-return" icon={chevronBackOutline} />
<div className="address-from-to">
<span>{props.addressFrom.label}</span>
<IonIcon icon={arrowForwardOutline} />
<span>{props.addressTo.label}</span>
<small>Hoje</small>
</div>
</span>
</div>
</IonHeader>
<IonContent fullscreen>
{transportes && transportes.length > 0? (
<div className="header-tabs">
<IonSlides>
<IonSlide>
<h5>Mais barata</h5>
<IonCard className="card-transporte">
<IonCardContent>Seu João</IonCardContent>
</IonCard>
</IonSlide>
<IonSlide>
<h5>Melhor avaliação</h5>
<IonCard className="card-transporte">
<IonCardContent>Seu </IonCardContent>
</IonCard>
</IonSlide>
</IonSlides>
</div>
)
:
(<h1 className="msg-not-found">Não foi encontrado nenhum transporte que atenda essa rota.</h1>)}
{transportes &&
transportes.map((record: any, index: any) => {
return (
<IonCard className="card-transporte" key={index}>
<IonCardContent>
<h1>Motorista: {record.motorista}</h1>
<div>Avaliação: {record.avaliacao}</div>
<div>Valor: {record.valor}</div>
<div>Lugares disponíveis: {record.lugares}</div>
</IonCardContent>
</IonCard>
);
})}
<div className="button-criar-alerta">
<IonButton onClick={() => criaAlerta()}>Criar Alerta</IonButton>
</div>
<IonFab
onClick={() => setShowModalFilters(true)}
vertical="bottom"
horizontal="center"
slot="fixed"
>
<IonFabButton>Filtros</IonFabButton>
</IonFab>
<IonModal isOpen={showModalFilters}>
<IonToolbar>
<div className="header-filter-modal">
<IonIcon
size="large"
icon={closeOutline}
onClick={() => setShowModalFilters(false)}
/>
<h4>
<b>Limpar</b>
</h4>
</div>
</IonToolbar>
<IonContent>
<div className="content-filter-modal">
<h1>Filtrar</h1>
<h3>Ordernar por</h3>
<IonRadioGroup>
<IonItem>
<IonLabel>Menor preço</IonLabel>
<IonRadio value="menor_preco" />
</IonItem>
<IonItem>
<IonLabel>Avaliação</IonLabel>
<IonRadio value="avaliacao" />
</IonItem>
<IonItem>
<IonLabel>Lugares disponíveis</IonLabel>
<IonRadio value="lugares_disponiveis" />
</IonItem>
</IonRadioGroup>
<h3>Preferências</h3>
<IonItem>
<IonLabel>Vaga avulsa</IonLabel>
<IonCheckbox value="vaga_avulsa" />
</IonItem>
<IonItem>
<IonLabel>Ar condicionado</IonLabel>
<IonCheckbox value="ar_condicionado" />
</IonItem>
</div>
</IonContent>
<IonFooter>
<IonButton
expand="block"
onClick={() => setShowModalFilters(false)}
>
Aplicar Filtros
</IonButton>
</IonFooter>
</IonModal>
<IonToast
// cssClass={"toast-notification"}
color={toastColor}
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
message={messageToast}
duration={2500}
/>
</IonContent>
</IonPage>
);
};
export default Transportes;

View File

@@ -4,6 +4,7 @@ import instance from './api';
import userRoutes from '../../constants/routes/usersRoutes';
import { AxiosRequestHeaders } from 'axios';
import LocalStorage from '../../LocalStorage';
import { setStore } from '../../store/RecordsStore';
let token: string;
let header: AxiosRequestHeaders;
@@ -87,3 +88,15 @@ export async function getSocialInfo(userId: string) {
const response = await instance.get(userRoutes.getSocialInfo.url + `/${userId}`, { headers: header });
return response.data;
}
export async function getUsersSearching(currentPoint: any) {
// Replace lat/long with values from get current location.
// Allow choosing of radius?
// Offset could = amount loaded in an infinite scroll?
var latitude = currentPoint.latitude, longitude = currentPoint.longitude, radius = 3000, offset = 0;
// const response = await fetch(`http://localhost:4000/get-records?latitude=${ latitude }&longitude=${ longitude }&radius=${ radius }&offset=${ offset }`);
const response = await instance.post(`${userRoutes.getUsersSearching.url}`, currentPoint)
// const data = await response.json();
console.log(response.data)
setStore(response.data);
}

View File

@@ -0,0 +1,34 @@
import instance from "../services/api/api";
import { setStore } from "../store/RecordsStore";
// import LocalStorage from '../LocalStorage';
// let token:string;
let header: string;
function updateHeader() {
// token = LocalStorage.getToken();
header = `{
"Accept": 'application/json',
"Content-Type": 'application/json',
"Authorization": 'Bearer ' + token
}`;
}
interface CoordinatesRequest {
coordinatesFrom:{
lat: number,
lng: number
},
coordinatesTo:{
lat: number,
lng: number
}
}
export async function getTransportes(request: CoordinatesRequest) {
updateHeader();
console.log(request)
const response = await instance.post("http://localhost:3333/transportes/", request);
return response.data as [];
}

View File

@@ -1,60 +0,0 @@
import instance from '../services/api/api';
import { setStore } from "../store/RecordsStore";
// import LocalStorage from '../LocalStorage';
import userRoutes from '../constants/routes/usersRoutes';
// let token:string;
let header:string;
function updateHeader() {
// token = LocalStorage.getToken();
header = `{
"Accept": 'application/json',
"Content-Type": 'application/json',
"Authorization": 'Bearer ' + token
}`
}
export interface CadastroResponse {
message?: string;
token?: {
token: string;
};
error?: string;
}
export interface CadastroRequest {
name: string;
email: string;
birth_date: string;
password: string;
}
// export async function get(cpf) {
// updateHeader();
// const response = await instance.get(userRoutes.get.url + `/${cpf}`, { headers: header });
// return response.data;
// }
export async function create(CadastroRequest: any) {
updateHeader();
const response = await instance.post("http://localhost:3333/users/", CadastroRequest);
return response.data;
}
export async function getUsersSearching(currentPoint: any) {
// Replace lat/long with values from get current location.
// Allow choosing of radius?
// Offset could = amount loaded in an infinite scroll?
var latitude = currentPoint.latitude, longitude = currentPoint.longitude, radius = 3000, offset = 0;
// const response = await fetch(`http://localhost:4000/get-records?latitude=${ latitude }&longitude=${ longitude }&radius=${ radius }&offset=${ offset }`);
const response = await instance.post(`${userRoutes.getUsersSearching.url}`, currentPoint)
// const data = await response.json();
console.log(response.data)
setStore(response.data);
}

7
src/services/utils.ts Normal file
View File

@@ -0,0 +1,7 @@
import instance from '../services/api/api';
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;
}

11252
yarn.lock

File diff suppressed because it is too large Load Diff