This commit is contained in:
Hugo Falcao
2022-09-14 20:52:09 -03:00
parent 3d5aa1e144
commit 327b1ee492
6 changed files with 304 additions and 134 deletions

View File

@@ -32,11 +32,12 @@ interface AddressSelected {
interface AutoCompleteInputProps extends InputHTMLAttributes<HTMLInputElement> { interface AutoCompleteInputProps extends InputHTMLAttributes<HTMLInputElement> {
onAddressSelected: (address: AddressSelected) => void; onAddressSelected: (address: AddressSelected) => void;
clearAfterSelect?: boolean;
} }
function AutoCompleteInput(props: AutoCompleteInputProps) { function AutoCompleteInput(props: AutoCompleteInputProps) {
const searchInput = useRef(null); const searchInput = useRef(null);
const { onAddressSelected, ...othersProps } = props; const { onAddressSelected, clearAfterSelect, ...othersProps } = props;
// do something on address change // do something on address change
const onChangeAddress = (autocomplete: any) => { const onChangeAddress = (autocomplete: any) => {

View File

@@ -24,8 +24,6 @@ import {
} from "ionicons/icons"; } from "ionicons/icons";
import "./BuscarItinerario.css"; import "./BuscarItinerario.css";
import itinerariesService from "../services/functions/itinerariesService";
import { useState } from "react"; import { useState } from "react";
import { useHistory } from "react-router"; import { useHistory } from "react-router";
@@ -35,6 +33,7 @@ import { closeToast } from "../services/utils";
import { Color } from "@ionic/core"; import { Color } from "@ionic/core";
import AutoCompleteInput from "../components/AutoCompleteInput"; import AutoCompleteInput from "../components/AutoCompleteInput";
import { searchItineraries } from "../services/functions/itinerariesService";
interface Address { interface Address {
formatted_address: string; formatted_address: string;
@@ -116,11 +115,10 @@ const BuscarItinerario: React.FC = () => {
}, },
]); ]);
await itinerariesService await searchItineraries({
.searchItineraries({ coordinatesFrom: addressFrom,
coordinatesFrom: addressFrom, coordinatesTo: addressTo,
coordinatesTo: addressTo, })
})
.then((response) => { .then((response) => {
// if (response.status === "error") { // if (response.status === "error") {
// setToastColor("danger"); // setToastColor("danger");

View File

@@ -11,33 +11,29 @@ import {
IonInput, IonInput,
IonItem, IonItem,
IonLabel, IonLabel,
IonList,
IonPage, IonPage,
IonRange,
IonSelect, IonSelect,
IonSelectOption, IonSelectOption,
IonSlide, IonSlide,
IonSlides, IonSlides,
IonTitle, IonTitle,
IonToast, IonToast,
IonToolbar, IonToolbar
} from "@ionic/react"; } from "@ionic/react";
import { import {
add,
addCircleOutline, addCircleOutline,
arrowBack, arrowBack,
arrowForward, arrowForward,
checkmark, checkmark,
close, close,
informationCircle, informationCircle,
locateOutline, removeCircleOutline
locationOutline,
removeCircleOutline,
} from "ionicons/icons"; } from "ionicons/icons";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { useHistory } from "react-router"; import { useHistory } from "react-router";
import AutoCompleteInput from "../../components/AutoCompleteInput"; import { CreateItineraryRequest } from "../../services/api/itineraries";
import * as vehiclesRoutes from "../../services/api/vehicles"; import * as vehiclesRoutes from "../../services/api/vehicles";
import { createItinerary } from "../../services/functions/itinerariesService";
import sessionsService from "../../services/functions/sessionsService"; import sessionsService from "../../services/functions/sessionsService";
const slideOpts = { const slideOpts = {
@@ -58,11 +54,6 @@ interface VanInfo {
locator_state: string; locator_state: string;
} }
interface Coords {
lat: number;
lng: number;
}
interface Address { interface Address {
formatted_address: string; formatted_address: string;
lat: number; lat: number;
@@ -74,28 +65,33 @@ export default function CadastrarItinerario() {
const history = useHistory(); const history = useHistory();
const [showToast, setShowToast] = useState<boolean>(false);
const [toastMessage, setToastMessage] = useState<string>("");
const [toastColor, setToastColor] = useState<Color>("primary");
const mySlides = useRef<any>(null); const mySlides = useRef<any>(null);
const nextButton1 = useRef<HTMLIonButtonElement>(null); const nextButton1 = useRef<HTMLIonButtonElement>(null);
const nextButton2 = useRef<HTMLIonButtonElement>(null); const nextButton2 = useRef<HTMLIonButtonElement>(null);
const nextButton3 = useRef<HTMLIonButtonElement>(null);
const nextButton4 = useRef<HTMLIonButtonElement>(null);
const nextButton5 = useRef<HTMLIonButtonElement>(null);
const nextButton6 = useRef<HTMLIonButtonElement>(null);
const [specificDate, setSpecificDate] = useState<boolean>(false); const [specificDate, setSpecificDate] = useState<boolean>(false);
const [singleVacancy, setSingleVacancy] = useState<boolean>(false); const [singleVacancy, setSingleVacancy] = useState<boolean>(false);
const [vans, setVans] = useState<VanInfo[]>(); const [vans, setVans] = useState<VanInfo[]>();
const [showToast, setShowToast] = useState<boolean>(false);
const [toastMessage, setToastMessage] = useState<string>("");
const [toastColor, setToastColor] = useState<Color>("primary");
//Infos //Infos
const [initialAddress, setInitialAddress] = useState<Address>(); const [initialAddress, setInitialAddress] = useState<Address>();
const [initialCoords, setInitialCoords] = useState<Coords>(); const [neighborhoods, setNeighborhoods] = useState<Array<Address>>([]);
const [neighborhoods, setNeighborhoods] = useState<Array<string>>([]); const [finalAddress, setFinalAddress] = useState<Address>();
const [finalAddress, setFinalAddress] = useState<string>(""); const [destinations, setDestinations] = useState<Array<Address>>([]);
const [destinations, setDestinations] = useState<Array<string>>([]); const [daysOfWeek, setDaysOfWeek] = useState<string>("0000000");
const [daysOfWeek, setDaysOfWeek] = useState<number>(); const [specificDay, setSpecificDay] = useState<string>("");
const [specificDay, setSpecificDay] = useState<Date>(); const [departureTime, setDepartureTime] = useState<string>("00:00");
const [departureTime, setDepartureTime] = useState<Date>(); const [arrivalTime, setArrivalTime] = useState<string>("00:00");
const [arrivalTime, setArrivalTime] = useState<Date>(); const [monthlyPrice, setMonthlyPrice] = useState<number>(100);
const [monthlyPrice, setMonthlyPrice] = useState<number>(0); const [dailyPrice, setDailyPrice] = useState<number>(40);
const [dailyPrice, setDailyPrice] = useState<number>(0);
const [van, setVan] = useState<string>(""); const [van, setVan] = useState<string>("");
const [nickname, setNickname] = useState<string>(""); const [nickname, setNickname] = useState<string>("");
@@ -149,7 +145,7 @@ export default function CadastrarItinerario() {
userId = refreshSessionRes.userId; userId = refreshSessionRes.userId;
} }
vehiclesRoutes await vehiclesRoutes
.getByUserId(userId) .getByUserId(userId)
.then((response: any) => { .then((response: any) => {
if (response.status === "error") { if (response.status === "error") {
@@ -172,15 +168,90 @@ export default function CadastrarItinerario() {
getUserVans(); getUserVans();
}, []); }, []);
useEffect(() => { // useEffect(() => {
if (initialAddress) { // if (initialAddress) {
nextButton1.current!.disabled = false; // nextButton1.current!.disabled = false;
} else { // } else {
nextButton1.current!.disabled = true; // nextButton1.current!.disabled = true;
} // }
}, [initialAddress]); // }, [initialAddress]);
function addNeighborhoodToList() {} // useEffect(() => {
// if (finalAddress) {
// nextButton3.current!.disabled = false;
// } else {
// nextButton3.current!.disabled = true;
// }
// }, [finalAddress]);
function addNeighborhood(address: Address) {
setNeighborhoods((arr) => [...arr, address]);
nextButton2.current!.disabled = false;
}
function removeNeighborhood(index: number) {
const newNeighborhoods = [...neighborhoods];
newNeighborhoods.splice(index, 1);
setNeighborhoods(newNeighborhoods);
if (newNeighborhoods.length === 0) {
nextButton2.current!.disabled = true;
} else {
nextButton2.current!.disabled = false;
}
}
function removeDestionation(index: number) {
const newDestionations = [...destinations];
newDestionations.splice(index, 1);
setDestinations(newDestionations);
}
function (params:type) {
}
async function cadastrar() {
let itinerary: CreateItineraryRequest = {
vehicle_plate: van,
days_of_week: daysOfWeek,
specific_day: specificDay,
estimate_departure_time: departureTime,
estimate_arrival_time: arrivalTime,
monthly_price: monthlyPrice,
daily_price: dailyPrice,
itinerary_nickname: nickname,
estimated_departure_address: initialAddress!.formatted_address,
departure_latitude: initialAddress!.lat,
departure_longitude: initialAddress!.lng,
neighboorhoods_served: neighborhoods,
destinations: destinations,
};
await createItinerary(itinerary)
.then((response: any) => {
if (response.status === "error") {
setToastColor("danger");
setToastMessage(response.message);
setShowToast(true);
}
history.push({
pathname: "/meus-itinerarios",
state: {
redirectData: {
showToastMessage: true,
toastColor: "success",
toastMessage: "Itinerário cadastrado com sucesso!",
},
},
});
})
.catch((err: any) => {
setToastColor("danger");
setToastMessage(err);
setShowToast(true);
});
}
return ( return (
<IonPage> <IonPage>
@@ -195,7 +266,7 @@ export default function CadastrarItinerario() {
<IonContent fullscreen> <IonContent fullscreen>
<IonSlides ref={mySlides} options={slideOpts}> <IonSlides ref={mySlides} options={slideOpts}>
<IonSlide> {/* <IonSlide>
<div className="m-3"> <div className="m-3">
<h1 className="mb-3 text-xl"> <h1 className="mb-3 text-xl">
Digite o endereço de onde você iniciará a rota do itinerário Digite o endereço de onde você iniciará a rota do itinerário
@@ -247,31 +318,37 @@ export default function CadastrarItinerario() {
<AutoCompleteInput <AutoCompleteInput
placeholder="R. José Paulino, 1234" placeholder="R. José Paulino, 1234"
className="ml-2" className="ml-2"
onAddressSelected={(address: Address) => console.log(address)} onAddressSelected={(address: Address) =>
addNeighborhood(address)
}
/> />
</div> </div>
<div className="flex justify-end mb-3">
<IonButton>
<IonIcon icon={add} />
</IonButton>
</div>
<div className="mb-3"> <div className="mb-3">
<IonList> <IonList class="w-screen">
<IonItem> {neighborhoods.map((neighborhood, index) => (
<IonCheckbox slot="end"></IonCheckbox> <IonItem key={index}>
<IonLabel>Taquaral</IonLabel> <IonButton
</IonItem> slot="end"
<IonItem> color={"light"}
<IonCheckbox slot="end"></IonCheckbox> onClick={() => removeNeighborhood(index)}
<IonLabel>Barão Geraldo</IonLabel> >
</IonItem> <IonIcon icon={trash} />
</IonButton>
<IonLabel>{neighborhood.formatted_address}</IonLabel>
</IonItem>
))}
</IonList> </IonList>
</div> </div>
<div className="flex justify-between mb-3"> <div className="flex justify-between mb-3">
<IonButton onClick={() => onBtnClicked("prev")} color="primary"> <IonButton onClick={() => onBtnClicked("prev")} color="primary">
<IonIcon icon={arrowBack} /> <IonIcon icon={arrowBack} />
</IonButton> </IonButton>
<IonButton onClick={() => onBtnClicked("next")} color="primary"> <IonButton
ref={nextButton2}
disabled
onClick={() => onBtnClicked("next")}
color="primary"
>
<IonIcon icon={arrowForward} /> <IonIcon icon={arrowForward} />
</IonButton> </IonButton>
</div> </div>
@@ -298,7 +375,9 @@ export default function CadastrarItinerario() {
<AutoCompleteInput <AutoCompleteInput
placeholder="R. José Paulino, 1234" placeholder="R. José Paulino, 1234"
className="ml-2" className="ml-2"
onAddressSelected={(address: Address) => console.log(address)} onAddressSelected={(address: Address) =>
setFinalAddress(address)
}
/> />
</div> </div>
<div className="flex justify-between mb-3"> <div className="flex justify-between mb-3">
@@ -306,8 +385,8 @@ export default function CadastrarItinerario() {
<IonIcon icon={arrowBack} /> <IonIcon icon={arrowBack} />
</IonButton> </IonButton>
<IonButton <IonButton
ref={nextButton2} ref={nextButton3}
// disabled disabled
onClick={() => onBtnClicked("next")} onClick={() => onBtnClicked("next")}
color="primary" color="primary"
> >
@@ -337,24 +416,25 @@ export default function CadastrarItinerario() {
<AutoCompleteInput <AutoCompleteInput
placeholder="R. José Paulino, 1234" placeholder="R. José Paulino, 1234"
className="ml-2" className="ml-2"
onAddressSelected={(address: Address) => console.log(address)} onAddressSelected={(address: Address) =>
setDestinations((arr) => [...arr, address])
}
/> />
</div> </div>
<div className="flex justify-end mb-3">
<IonButton>
<IonIcon icon={add} />
</IonButton>
</div>
<div className="mb-3"> <div className="mb-3">
<IonList> <IonList class="w-screen">
<IonItem> {destinations.map((destination, index) => (
<IonCheckbox slot="end"></IonCheckbox> <IonItem key={index}>
<IonLabel>Unicamp</IonLabel> <IonButton
</IonItem> slot="end"
<IonItem> color={"light"}
<IonCheckbox slot="end"></IonCheckbox> onClick={() => removeDestionation(index)}
<IonLabel>CPFL</IonLabel> >
</IonItem> <IonIcon icon={trash} />
</IonButton>
<IonLabel>{destination.formatted_address}</IonLabel>
</IonItem>
))}
</IonList> </IonList>
</div> </div>
<div className="flex justify-between mb-3"> <div className="flex justify-between mb-3">
@@ -377,26 +457,60 @@ export default function CadastrarItinerario() {
</small> </small>
</div> </div>
</div> </div>
</IonSlide> </IonSlide> */}
<IonSlide> <IonSlide>
<div className="m-3"> <div className="m-3">
<h1 className="mb-3 text-xl"> <h1 className="mb-3 text-xl">
Escolha o(s) dia(s) da semana ou um dia específico que o Escolha o(s) dia(s) da semana ou um dia específico que o
itinerário será realizado itinerário será realizado
</h1> </h1>
<div hidden={specificDate} className="flex items-center mb-3"> <div hidden={specificDate} className="mb-3">
<IonRange <div className="grid grid-cols-7 gap-4">
dualKnobs <div>
pin <IonLabel>D</IonLabel>
pinFormatter={(value: number) => formatRange(value)} </div>
ticks <div>
snaps <IonLabel>S</IonLabel>
min={1} </div>
max={7} <div>
> <IonLabel>T</IonLabel>
<IonLabel slot="start">Seg</IonLabel> </div>
<IonLabel slot="end">Dom</IonLabel> <div>
</IonRange> <IonLabel>Q</IonLabel>
</div>
<div>
<IonLabel>Q</IonLabel>
</div>
<div>
<IonLabel>S</IonLabel>
</div>
<div>
<IonLabel>S</IonLabel>
</div>
</div>
<div className="grid grid-cols-7 gap-4">
<div>
<IonCheckbox onClick={() => setDaysOfWeek(daysOfWeek[0] = "1")}></IonCheckbox>
</div>
<div>
<IonCheckbox value="segunda"></IonCheckbox>
</div>
<div>
<IonCheckbox value="terca"></IonCheckbox>
</div>
<div>
<IonCheckbox value="quarta"></IonCheckbox>
</div>
<div>
<IonCheckbox value="quinta"></IonCheckbox>
</div>
<div>
<IonCheckbox value="sexta"></IonCheckbox>
</div>
<div>
<IonCheckbox value="sabado"></IonCheckbox>
</div>
</div>
</div> </div>
<div className="mb-3"> <div className="mb-3">
<IonItem className="mb-3"> <IonItem className="mb-3">
@@ -413,6 +527,11 @@ export default function CadastrarItinerario() {
min={minDate.toISOString()} min={minDate.toISOString()}
presentation="date" presentation="date"
hidden={!specificDate} hidden={!specificDate}
onIonChange={(e) =>
setSpecificDay(
typeof e.detail.value === "string" ? e.detail.value : ""
)
}
></IonDatetime> ></IonDatetime>
</div> </div>
<div className="flex justify-between mb-3"> <div className="flex justify-between mb-3">
@@ -431,18 +550,23 @@ export default function CadastrarItinerario() {
Qual o horário estimado de ínicio do itinerário ? Qual o horário estimado de ínicio do itinerário ?
</h1> </h1>
<div className="mb-3"> <div className="mb-3">
<IonDatetime presentation="time"></IonDatetime> <IonDatetime
presentation="time"
value="00:00"
onIonChange={(event) =>
setDepartureTime(
typeof event.detail.value === "string"
? event.detail.value
: "00:00"
)
}
></IonDatetime>
</div> </div>
<div className="flex justify-between mb-3"> <div className="flex justify-between mb-3">
<IonButton onClick={() => onBtnClicked("prev")} color="primary"> <IonButton onClick={() => onBtnClicked("prev")} color="primary">
<IonIcon icon={arrowBack} /> <IonIcon icon={arrowBack} />
</IonButton> </IonButton>
<IonButton <IonButton onClick={() => onBtnClicked("next")} color="primary">
ref={nextButton2}
// disabled
onClick={() => onBtnClicked("next")}
color="primary"
>
<IonIcon icon={arrowForward} /> <IonIcon icon={arrowForward} />
</IonButton> </IonButton>
</div> </div>
@@ -465,18 +589,23 @@ export default function CadastrarItinerario() {
itinerário ? itinerário ?
</h1> </h1>
<div className="mb-3"> <div className="mb-3">
<IonDatetime presentation="time"></IonDatetime> <IonDatetime
presentation="time"
value="00:00"
onIonChange={(event) =>
setArrivalTime(
typeof event.detail.value === "string"
? event.detail.value
: "00:00"
)
}
></IonDatetime>
</div> </div>
<div className="flex justify-between mb-3"> <div className="flex justify-between mb-3">
<IonButton onClick={() => onBtnClicked("prev")} color="primary"> <IonButton onClick={() => onBtnClicked("prev")} color="primary">
<IonIcon icon={arrowBack} /> <IonIcon icon={arrowBack} />
</IonButton> </IonButton>
<IonButton <IonButton onClick={() => onBtnClicked("next")} color="primary">
ref={nextButton2}
// disabled
onClick={() => onBtnClicked("next")}
color="primary"
>
<IonIcon icon={arrowForward} /> <IonIcon icon={arrowForward} />
</IonButton> </IonButton>
</div> </div>
@@ -544,8 +673,7 @@ export default function CadastrarItinerario() {
<IonIcon icon={arrowBack} /> <IonIcon icon={arrowBack} />
</IonButton> </IonButton>
<IonButton <IonButton
ref={nextButton2} disabled
// disabled
onClick={() => onBtnClicked("next")} onClick={() => onBtnClicked("next")}
color="primary" color="primary"
> >
@@ -579,6 +707,7 @@ export default function CadastrarItinerario() {
<IonSelect <IonSelect
interface="action-sheet" interface="action-sheet"
placeholder="Selecione o veículo" placeholder="Selecione o veículo"
onIonChange={(event) => console.log(event.detail.value)}
> >
{vans ? ( {vans ? (
vans.map((van, index) => { vans.map((van, index) => {
@@ -602,8 +731,8 @@ export default function CadastrarItinerario() {
<IonIcon icon={arrowBack} /> <IonIcon icon={arrowBack} />
</IonButton> </IonButton>
<IonButton <IonButton
ref={nextButton2} ref={nextButton6}
// disabled disabled
onClick={() => onBtnClicked("next")} onClick={() => onBtnClicked("next")}
color="primary" color="primary"
> >
@@ -628,12 +757,7 @@ export default function CadastrarItinerario() {
<IonButton onClick={() => onBtnClicked("prev")} color="primary"> <IonButton onClick={() => onBtnClicked("prev")} color="primary">
<IonIcon icon={arrowBack} /> <IonIcon icon={arrowBack} />
</IonButton> </IonButton>
<IonButton <IonButton onClick={() => cadastrar()} color="primary">
ref={nextButton2}
// disabled
onClick={() => onBtnClicked("next")}
color="primary"
>
<IonIcon icon={checkmark} /> <IonIcon icon={checkmark} />
Cadastrar Cadastrar
</IonButton> </IonButton>

View File

@@ -28,7 +28,7 @@ import {
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useHistory, useLocation } from "react-router"; import { useHistory, useLocation } from "react-router";
import { createUserSearch } from "../../services/api/users"; import { createUserSearch } from "../../services/api/users";
import itinerariesService from "../../services/functions/itinerariesService"; import { searchItineraries } from "../../services/functions/itinerariesService";
import { closeToast } from "../../services/utils"; import { closeToast } from "../../services/utils";
import "./Transportes.css"; import "./Transportes.css";
@@ -56,7 +56,7 @@ const Transportes: React.FC = () => {
}, [props]); }, [props]);
async function buscaItinerarios() { async function buscaItinerarios() {
let data = (await itinerariesService.searchItineraries(props)) as any; let data = (await searchItineraries(props)) as any;
setItinerarios(data); setItinerarios(data);
} }

View File

@@ -1,10 +1,9 @@
import instance from './api'; import instance from "./api";
// import LocalStorage from '../LocalStorage'; // import LocalStorage from '../LocalStorage';
import transportsRoutes from '../../constants/routes/itinerariesRoutes'; import { AxiosRequestHeaders } from "axios";
import { AxiosRequestHeaders } from 'axios'; import transportsRoutes from "../../constants/routes/itinerariesRoutes";
import LocalStorage from '../../LocalStorage'; import LocalStorage from "../../LocalStorage";
import { setStore } from '../../store/RecordsStore';
let token: string; let token: string;
let header: AxiosRequestHeaders; let header: AxiosRequestHeaders;
@@ -13,27 +12,67 @@ function updateHeader() {
token = LocalStorage.getToken(); token = LocalStorage.getToken();
header = { header = {
"Accept": 'application/json', Accept: "application/json",
"Content-Type": 'application/json', "Content-Type": "application/json",
"Authorization": 'Bearer ' + token Authorization: "Bearer " + token,
} };
} }
export interface Coordinates { export interface Coordinates {
lat: number, lat: number;
lng: number lng: number;
}
interface Address {
formatted_address: string;
lat: number;
lng: number;
}
export interface CreateItineraryRequest {
vehicle_plate: string;
days_of_week: string;
specific_day: string;
estimate_departure_time: string;
estimate_arrival_time: string;
monthly_price: number;
daily_price: number;
itinerary_nickname: string;
estimated_departure_address: string;
departure_latitude: number;
departure_longitude: number;
neighboorhoods_served: Array<Address>;
destinations: Array<Address>;
} }
export async function get() { export async function get() {
updateHeader(); updateHeader();
const response = await instance.get(transportsRoutes.get.url, { headers: header }); const response = await instance.get(transportsRoutes.get.url, {
headers: header,
});
return response.data; return response.data;
} }
export async function search(coordinatesOrigin: Coordinates, coordinatesDestination: Coordinates) { export async function create(itinerary: CreateItineraryRequest) {
updateHeader(); updateHeader();
const response = await instance.post(transportsRoutes.search.url, { coordinatesOrigin, coordinatesDestination }, { headers: header }); const response = await instance.post(transportsRoutes.create.url, itinerary, {
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; return response.data;
} }

View File

@@ -39,4 +39,12 @@ export async function searchItineraries({
return res.data; return res.data;
} }
export default { getAllItineraries, searchItineraries }; export async function createItinerary(
itinerary: itinerariesRoutes.CreateItineraryRequest
): Promise<any> {
let res: any;
res = await itinerariesRoutes.create(itinerary);
return res;
}