feat(buscar-transporte): ✨ find a transport
Find a transport informing place of departure and arrival
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="pt-br">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>Ionic App</title>
|
<title>Vanmos App</title>
|
||||||
|
|
||||||
<base href="/" />
|
<base href="/" />
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ import '@ionic/react/css/display.css';
|
|||||||
|
|
||||||
/* Theme variables */
|
/* Theme variables */
|
||||||
import './theme/variables.css';
|
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 Tabs from './components/Tabs';
|
||||||
|
|
||||||
setupIonicReact();
|
setupIonicReact();
|
||||||
@@ -41,6 +44,9 @@ const App: React.FC = () => (
|
|||||||
<Route exact path="/mainpages" component={MainPages}></Route>
|
<Route exact path="/mainpages" component={MainPages}></Route>
|
||||||
<Route exact path="/cadastro" component={Cadastro}></Route>
|
<Route exact path="/cadastro" component={Cadastro}></Route>
|
||||||
<Route exact path="/login" component={Login}></Route>
|
<Route exact path="/login" component={Login}></Route>
|
||||||
|
<Route exact path="/buscar-passageiro" component={BuscarPassageiro}></Route>
|
||||||
|
<Route exact path="/buscar-transporte" component={BuscarTransporte}></Route>
|
||||||
|
<Route exact path="/transportes" component={Transportes}></Route>
|
||||||
<Route exact path="/">
|
<Route exact path="/">
|
||||||
<Redirect to="/mainpages" />
|
<Redirect to="/mainpages" />
|
||||||
</Route>
|
</Route>
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
#nome-sobrenome{
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toast-notification{
|
|
||||||
--background: rgb(255, 0, 0);
|
|
||||||
}
|
|
||||||
52
src/pages/BuscarTransporte/BuscarTransporte.css
Normal file
52
src/pages/BuscarTransporte/BuscarTransporte.css
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
.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;
|
||||||
|
}
|
||||||
182
src/pages/BuscarTransporte/BuscarTransporte.tsx
Normal file
182
src/pages/BuscarTransporte/BuscarTransporte.tsx
Normal 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>Há 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>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>
|
||||||
|
</IonContent>
|
||||||
|
</IonPage>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BuscarTransporte;
|
||||||
@@ -14,6 +14,7 @@ import { search, home, person } from 'ionicons/icons';
|
|||||||
|
|
||||||
import Home from './Home';
|
import Home from './Home';
|
||||||
import BuscarPassageiro from './BuscarPassageiro/BuscarPassageiro';
|
import BuscarPassageiro from './BuscarPassageiro/BuscarPassageiro';
|
||||||
|
import BuscarTransporte from './BuscarTransporte/BuscarTransporte';
|
||||||
|
|
||||||
export const MainPages: React.FC = () => {
|
export const MainPages: React.FC = () => {
|
||||||
|
|
||||||
@@ -23,18 +24,17 @@ export const MainPages: React.FC = () => {
|
|||||||
<Route path="/home" exact={true}>
|
<Route path="/home" exact={true}>
|
||||||
<Home />
|
<Home />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/buscar" exact={true}>
|
<Route path="/buscar-passageiro" exact={true}>
|
||||||
<BuscarPassageiro />
|
<BuscarPassageiro />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/buscar" exact={true}>
|
<Route path="/buscar-transporte" exact={true}>
|
||||||
<BuscarPassageiro />
|
<BuscarTransporte />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/mainpages" render={() => <Redirect to="/buscar
|
<Route path="/mainpages" render={() => <Redirect to="/buscar-transporte" />} exact={true} />
|
||||||
" />} />
|
|
||||||
</IonRouterOutlet>
|
</IonRouterOutlet>
|
||||||
|
|
||||||
<IonTabBar slot="bottom">
|
<IonTabBar slot="bottom">
|
||||||
<IonTabButton tab="buscar" href="/buscar">
|
<IonTabButton tab="buscar" href="/buscar-transporte">
|
||||||
<IonIcon icon={search} />
|
<IonIcon icon={search} />
|
||||||
<IonLabel>Buscar</IonLabel>
|
<IonLabel>Buscar</IonLabel>
|
||||||
</IonTabButton>
|
</IonTabButton>
|
||||||
|
|||||||
19
src/pages/Transportes/Transportes.css
Normal file
19
src/pages/Transportes/Transportes.css
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
.header-page{
|
||||||
|
background-color: var(--ion-toolbar-background);
|
||||||
|
border-bottom: 1px solid var(--ion-toolbar-border-color);
|
||||||
|
height: 3.5rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-return{
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.span-info-back{
|
||||||
|
background-color: #4e4e4e;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
38
src/pages/Transportes/Transportes.tsx
Normal file
38
src/pages/Transportes/Transportes.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { IonContent, IonPage, IonFab, IonFabButton, IonIcon, IonCard, IonInput, IonRow, IonCol, IonCardContent, IonButton, IonHeader, IonToolbar, IonButtons, IonBackButton } from '@ionic/react';
|
||||||
|
import { arrowBack, arrowBackOutline, arrowForwardOutline, chevronBackOutline, chevronForwardOutline, locateOutline, locationOutline, timeOutline } from 'ionicons/icons';
|
||||||
|
import { useHistory } from 'react-router';
|
||||||
|
import './Transportes.css';
|
||||||
|
|
||||||
|
const Transportes: React.FC = () => {
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
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>
|
||||||
|
Vila Réggio
|
||||||
|
<IonIcon icon={arrowForwardOutline}/>
|
||||||
|
PUC-Campinas
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</IonHeader>
|
||||||
|
<IonContent fullscreen>
|
||||||
|
|
||||||
|
<IonFab vertical="bottom" horizontal="center" slot="fixed">
|
||||||
|
<IonFabButton>
|
||||||
|
Filtros
|
||||||
|
</IonFabButton>
|
||||||
|
</IonFab>
|
||||||
|
</IonContent>
|
||||||
|
</IonPage>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Transportes;
|
||||||
7
src/services/utils.ts
Normal file
7
src/services/utils.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import instance from '../services/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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user