feat(itineraries): Allows create an itinerary

This commit is contained in:
Hugo Falcao
2022-09-18 19:21:09 -03:00
parent 158c5e67c0
commit 62847b012e
4 changed files with 247 additions and 133 deletions

View File

@@ -11,6 +11,7 @@ import {
IonInput, IonInput,
IonItem, IonItem,
IonLabel, IonLabel,
IonList,
IonPage, IonPage,
IonSelect, IonSelect,
IonSelectOption, IonSelectOption,
@@ -18,7 +19,7 @@ import {
IonSlides, IonSlides,
IonTitle, IonTitle,
IonToast, IonToast,
IonToolbar IonToolbar,
} from "@ionic/react"; } from "@ionic/react";
import { import {
addCircleOutline, addCircleOutline,
@@ -27,10 +28,14 @@ import {
checkmark, checkmark,
close, close,
informationCircle, informationCircle,
removeCircleOutline locateOutline,
locationOutline,
removeCircleOutline,
trash,
} 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 { 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 { createItinerary } from "../../services/functions/itinerariesService";
@@ -60,6 +65,10 @@ interface Address {
lng: number; lng: number;
} }
interface Destinations extends Address {
is_final?: boolean;
}
export default function CadastrarItinerario() { export default function CadastrarItinerario() {
const minDate = new Date(); const minDate = new Date();
@@ -83,9 +92,9 @@ export default function CadastrarItinerario() {
//Infos //Infos
const [initialAddress, setInitialAddress] = useState<Address>(); const [initialAddress, setInitialAddress] = useState<Address>();
const [neighborhoods, setNeighborhoods] = useState<Array<Address>>([]); const [neighborhoods, setNeighborhoods] = useState<Address[]>([]);
const [finalAddress, setFinalAddress] = useState<Address>(); const [finalAddress, setFinalAddress] = useState<Address>();
const [destinations, setDestinations] = useState<Array<Address>>([]); const [destinations, setDestinations] = useState<Destinations[]>([]);
const [daysOfWeek, setDaysOfWeek] = useState<string>("0000000"); const [daysOfWeek, setDaysOfWeek] = useState<string>("0000000");
const [specificDay, setSpecificDay] = useState<string>(""); const [specificDay, setSpecificDay] = useState<string>("");
const [departureTime, setDepartureTime] = useState<string>("00:00"); const [departureTime, setDepartureTime] = useState<string>("00:00");
@@ -168,21 +177,33 @@ 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]);
// useEffect(() => { useEffect(() => {
// if (finalAddress) { if (finalAddress) {
// nextButton3.current!.disabled = false; nextButton3.current!.disabled = false;
// } else { } else {
// nextButton3.current!.disabled = true; nextButton3.current!.disabled = true;
// } }
// }, [finalAddress]); }, [finalAddress]);
useEffect(() => {
if (van) {
nextButton6.current!.disabled = false;
} else {
nextButton6.current!.disabled = true;
}
}, [van]);
useEffect(() => {
}, [destinations]);
function addNeighborhood(address: Address) { function addNeighborhood(address: Address) {
setNeighborhoods((arr) => [...arr, address]); setNeighborhoods((arr) => [...arr, address]);
@@ -206,47 +227,137 @@ export default function CadastrarItinerario() {
setDestinations(newDestionations); setDestinations(newDestionations);
} }
function setDayOfWeekSeleted(day:string) { function setDayOfWeekSeleted(day: string, checked: boolean) {
switch (day) { switch (day) {
case "Domingo":
setDaysOfWeek((value) => {
if (checked) {
let newDaysOfWeek = value.split("");
newDaysOfWeek[0] = "1";
let finalString = newDaysOfWeek.join("");
return finalString;
} else {
let newDaysOfWeek = value.split("");
newDaysOfWeek[0] = "0";
let finalString = newDaysOfWeek.join("");
return finalString;
}
});
break;
case "Segunda": case "Segunda":
setDaysOfWeek((value) => {
if (checked) {
let newDaysOfWeek = value.split("");
newDaysOfWeek[1] = "1";
let finalString = newDaysOfWeek.join("");
return finalString;
} else {
let newDaysOfWeek = value.split("");
newDaysOfWeek[1] = "0";
let finalString = newDaysOfWeek.join("");
return finalString;
}
});
break; break;
case "Terça": case "Terça":
setDaysOfWeek((value) => {
if (checked) {
let newDaysOfWeek = value.split("");
newDaysOfWeek[2] = "1";
let finalString = newDaysOfWeek.join("");
return finalString;
} else {
let newDaysOfWeek = value.split("");
newDaysOfWeek[2] = "0";
let finalString = newDaysOfWeek.join("");
return finalString;
}
});
break; break;
case "Quarta": case "Quarta":
setDaysOfWeek((value) => {
if (checked) {
let newDaysOfWeek = value.split("");
newDaysOfWeek[3] = "1";
let finalString = newDaysOfWeek.join("");
return finalString;
} else {
let newDaysOfWeek = value.split("");
newDaysOfWeek[3] = "0";
let finalString = newDaysOfWeek.join("");
return finalString;
}
});
break; break;
case "Quinta": case "Quinta":
setDaysOfWeek((value) => {
if (checked) {
let newDaysOfWeek = value.split("");
newDaysOfWeek[4] = "1";
let finalString = newDaysOfWeek.join("");
return finalString;
} else {
let newDaysOfWeek = value.split("");
newDaysOfWeek[4] = "0";
let finalString = newDaysOfWeek.join("");
return finalString;
}
});
break; break;
case "Sexta": case "Sexta":
setDaysOfWeek((value) => {
if (checked) {
let newDaysOfWeek = value.split("");
newDaysOfWeek[5] = "1";
let finalString = newDaysOfWeek.join("");
return finalString;
} else {
let newDaysOfWeek = value.split("");
newDaysOfWeek[5] = "0";
let finalString = newDaysOfWeek.join("");
return finalString;
}
});
break; break;
case "Sábado": case "Sábado":
setDaysOfWeek((value) => {
break; if (checked) {
case "Domingo": let newDaysOfWeek = value.split("");
newDaysOfWeek[6] = "1";
let finalString = newDaysOfWeek.join("");
return finalString;
} else {
let newDaysOfWeek = value.split("");
newDaysOfWeek[6] = "0";
let finalString = newDaysOfWeek.join("");
return finalString;
}
});
break; break;
} }
} }
useEffect(() => {}, [daysOfWeek]);
async function cadastrar() { async function cadastrar() {
let newDestinations: Destinations[] = [{...finalAddress!, is_final: true}];
newDestinations = newDestinations.concat(destinations);
let itinerary: CreateItineraryRequest = { let itinerary: CreateItineraryRequest = {
vehicle_plate: van, vehicle_plate: van,
days_of_week: daysOfWeek, days_of_week: daysOfWeek,
specific_day: specificDay, specific_day: specificDate ? specificDay : undefined,
estimate_departure_time: departureTime, estimated_departure_time: departureTime,
estimate_arrival_time: arrivalTime, estimated_arrival_time: arrivalTime,
monthly_price: monthlyPrice, monthly_price: monthlyPrice,
daily_price: dailyPrice, daily_price: dailyPrice,
accept_daily: singleVacancy,
itinerary_nickname: nickname, itinerary_nickname: nickname,
estimated_departure_address: initialAddress!.formatted_address, estimated_departure_address: initialAddress!.formatted_address,
departure_latitude: initialAddress!.lat, departure_latitude: initialAddress!.lat,
departure_longitude: initialAddress!.lng, departure_longitude: initialAddress!.lng,
neighboorhoods_served: neighborhoods, neighborhoods_served: neighborhoods,
destinations: destinations, destinations: newDestinations,
}; };
await createItinerary(itinerary) await createItinerary(itinerary)
@@ -257,15 +368,19 @@ export default function CadastrarItinerario() {
setShowToast(true); setShowToast(true);
} }
setToastColor("success");
setToastMessage(response.message);
setShowToast(true);
history.push({ history.push({
pathname: "/meus-itinerarios", pathname: "/meus-itinerarios",
state: { // state: {
redirectData: { // redirectData: {
showToastMessage: true, // showToastMessage: true,
toastColor: "success", // toastColor: "success",
toastMessage: "Itinerário cadastrado com sucesso!", // toastMessage: "Itinerário cadastrado com sucesso!",
}, // },
}, // },
}); });
}) })
.catch((err: any) => { .catch((err: any) => {
@@ -288,7 +403,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
@@ -479,7 +594,7 @@ 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">
@@ -512,25 +627,53 @@ export default function CadastrarItinerario() {
</div> </div>
<div className="grid grid-cols-7 gap-4"> <div className="grid grid-cols-7 gap-4">
<div> <div>
<IonCheckbox ></IonCheckbox> <IonCheckbox
onIonChange={(e) =>
setDayOfWeekSeleted("Domingo", e.target.checked)
}
></IonCheckbox>
</div> </div>
<div> <div>
<IonCheckbox value="segunda"></IonCheckbox> <IonCheckbox
onIonChange={(e) =>
setDayOfWeekSeleted("Segunda", e.target.checked)
}
></IonCheckbox>
</div> </div>
<div> <div>
<IonCheckbox value="terca"></IonCheckbox> <IonCheckbox
onIonChange={(e) =>
setDayOfWeekSeleted("Terça", e.target.checked)
}
></IonCheckbox>
</div> </div>
<div> <div>
<IonCheckbox value="quarta"></IonCheckbox> <IonCheckbox
onIonChange={(e) =>
setDayOfWeekSeleted("Quarta", e.target.checked)
}
></IonCheckbox>
</div> </div>
<div> <div>
<IonCheckbox value="quinta"></IonCheckbox> <IonCheckbox
onIonChange={(e) =>
setDayOfWeekSeleted("Quinta", e.target.checked)
}
></IonCheckbox>
</div> </div>
<div> <div>
<IonCheckbox value="sexta"></IonCheckbox> <IonCheckbox
onIonChange={(e) =>
setDayOfWeekSeleted("Sexta", e.target.checked)
}
></IonCheckbox>
</div> </div>
<div> <div>
<IonCheckbox value="sabado"></IonCheckbox> <IonCheckbox
onIonChange={(e) =>
setDayOfWeekSeleted("Sábado", e.target.checked)
}
></IonCheckbox>
</div> </div>
</div> </div>
</div> </div>
@@ -549,6 +692,7 @@ export default function CadastrarItinerario() {
min={minDate.toISOString()} min={minDate.toISOString()}
presentation="date" presentation="date"
hidden={!specificDate} hidden={!specificDate}
value={specificDay}
onIonChange={(e) => onIonChange={(e) =>
setSpecificDay( setSpecificDay(
typeof e.detail.value === "string" ? e.detail.value : "" typeof e.detail.value === "string" ? e.detail.value : ""
@@ -574,7 +718,7 @@ export default function CadastrarItinerario() {
<div className="mb-3"> <div className="mb-3">
<IonDatetime <IonDatetime
presentation="time" presentation="time"
value="00:00" value={departureTime}
onIonChange={(event) => onIonChange={(event) =>
setDepartureTime( setDepartureTime(
typeof event.detail.value === "string" typeof event.detail.value === "string"
@@ -613,7 +757,7 @@ export default function CadastrarItinerario() {
<div className="mb-3"> <div className="mb-3">
<IonDatetime <IonDatetime
presentation="time" presentation="time"
value="00:00" value={arrivalTime}
onIonChange={(event) => onIonChange={(event) =>
setArrivalTime( setArrivalTime(
typeof event.detail.value === "string" typeof event.detail.value === "string"
@@ -694,11 +838,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={() => onBtnClicked("next")} color="primary">
disabled
onClick={() => onBtnClicked("next")}
color="primary"
>
<IonIcon icon={arrowForward} /> <IonIcon icon={arrowForward} />
</IonButton> </IonButton>
</div> </div>
@@ -729,7 +869,8 @@ 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)} onIonChange={(event) => setVan(event.detail.value)}
className="w-screen"
> >
{vans ? ( {vans ? (
vans.map((van, index) => { vans.map((van, index) => {

View File

@@ -15,82 +15,46 @@ import {
IonToolbar, IonToolbar,
} from "@ionic/react"; } from "@ionic/react";
import { add, locateOutline, locationOutline } from "ionicons/icons"; import { add, locateOutline, locationOutline } from "ionicons/icons";
import { useState } from "react"; import { useEffect, useState } from "react";
import { getItineraries } from "../../services/api/itineraries";
import { PageHeader } from "../../components/PageHeader"; import { PageHeader } from "../../components/PageHeader";
import "./MeusItinerarios.css"; import "./MeusItinerarios.css";
interface Address {
formatted_address: string;
lat: number;
lng: number;
}
interface Destination extends Address {
is_final?: boolean;
}
interface ItineraryInfo { interface ItineraryInfo {
id_itinerary: number; id_itinerary: number;
vehicle_plate: string; vehicle_plate: string;
days_of_week: number; days_of_week?: string;
specific_day: string; specific_day?: string;
estimated_departure_time: string; estimated_departure_time: string;
estimated_arrival_time: string; estimated_arrival_time: string;
available_seats: number; monthly_price: number;
price: number; daily_price?: number;
accept_daily: boolean;
itinerary_nickname: string; itinerary_nickname: string;
estimated_departure_address: string;
departure_latitude: number;
departure_longitude: number;
neighborhoods_served: Address[];
destinations: Destination[];
} }
export default function MeusItinerarios() { export default function MeusItinerarios() {
const [routes, setRoutes] = useState<ItineraryInfo[]>( const [routes, setRoutes] = useState<ItineraryInfo[]>([]);
[
{ useEffect(() => {
id_itinerary: 1, getItineraries().then((response) => {
vehicle_plate: 'FSS1918', setRoutes(response.data);
days_of_week: 3, });
specific_day: '24/08/2022', }, [])
estimated_departure_time: '10:00',
estimated_arrival_time: '12:00',
available_seats: 20,
price: 108.20,
itinerary_nickname: 'Itinerário teste',
},
{
id_itinerary: 1,
vehicle_plate: 'FSS1918',
days_of_week: 3,
specific_day: '24/08/2022',
estimated_departure_time: '10:00',
estimated_arrival_time: '12:00',
available_seats: 20,
price: 108.20,
itinerary_nickname: 'Itinerário teste 2',
},
{
id_itinerary: 1,
vehicle_plate: 'FSS1918',
days_of_week: 3,
specific_day: '24/08/2022',
estimated_departure_time: '10:00',
estimated_arrival_time: '12:00',
available_seats: 20,
price: 108.20,
itinerary_nickname: 'Itinerário teste',
},
{
id_itinerary: 1,
vehicle_plate: 'FSS1918',
days_of_week: 3,
specific_day: '24/08/2022',
estimated_departure_time: '10:00',
estimated_arrival_time: '12:00',
available_seats: 20,
price: 108.20,
itinerary_nickname: 'Itinerário teste',
},
{
id_itinerary: 1,
vehicle_plate: 'FSS1918',
days_of_week: 3,
specific_day: '24/08/2022',
estimated_departure_time: '10:00',
estimated_arrival_time: '12:00',
available_seats: 20,
price: 108.20,
itinerary_nickname: 'Itinerário teste',
},
]
);
return ( return (
<IonPage> <IonPage>
@@ -109,15 +73,23 @@ export default function MeusItinerarios() {
</IonCardHeader> </IonCardHeader>
<IonCardContent> <IonCardContent>
<div className="addresses-itinerary"> <div className="addresses-itinerary">
<IonIcon icon={locateOutline}></IonIcon> <IonIcon icon={locateOutline} className="mr-1"></IonIcon>
Rua Francisco Glicerio, 100, Vila Novam aaaaaaaaaaaaaaaaaaaaaaaaaaa {itinerary.estimated_departure_address}
</div> </div>
<div className="icons-location-divider"> <div className="icons-location-divider">
| |
</div> </div>
<div className="addresses-itinerary"> <div className="addresses-itinerary">
<IonIcon icon={locationOutline}></IonIcon> <IonIcon icon={locationOutline} className="mr-1"></IonIcon>
PUC Campinas H15 Campus 1 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa {itinerary.destinations.map((destination) => {
if (destination.is_final) {
return (
<>
{destination.formatted_address}
</>
)
}
})}
</div> </div>
</IonCardContent> </IonCardContent>
</IonCard> </IonCard>

View File

@@ -31,21 +31,22 @@ interface Address {
export interface CreateItineraryRequest { export interface CreateItineraryRequest {
vehicle_plate: string; vehicle_plate: string;
days_of_week: string; days_of_week?: string;
specific_day: string; specific_day?: string;
estimate_departure_time: string; estimated_departure_time: string;
estimate_arrival_time: string; estimated_arrival_time: string;
monthly_price: number; monthly_price: number;
daily_price: number; daily_price?: number;
accept_daily: boolean;
itinerary_nickname: string; itinerary_nickname: string;
estimated_departure_address: string; estimated_departure_address: string;
departure_latitude: number; departure_latitude: number;
departure_longitude: number; departure_longitude: number;
neighboorhoods_served: Array<Address>; neighborhoods_served: Array<Address>;
destinations: Array<Address>; destinations: Array<Address>;
} }
export async function get() { export async function getItineraries() {
updateHeader(); updateHeader();
const response = await instance.get(transportsRoutes.get.url, { const response = await instance.get(transportsRoutes.get.url, {

View File

@@ -17,7 +17,7 @@ export async function getAllItineraries(): Promise<any> {
let res: any; let res: any;
try { try {
res = await itinerariesRoutes.get(); res = await itinerariesRoutes.getItineraries();
} catch (error) { } catch (error) {
// TODO // TODO
} }