From 2729b6e8667ffbd604560b743c6a22f5e916d4e8 Mon Sep 17 00:00:00 2001 From: Ebubeker Date: Sun, 10 Dec 2023 00:11:44 +0100 Subject: [PATCH 1/2] fix: using use form to make the code a bit cleaner --- .../components/map/panels/toolbox/Toolbox.tsx | 1 + .../map/panels/toolbox/tools/InputLayer.tsx | 51 ++- .../map/panels/toolbox/tools/SaveResult.tsx | 34 +- .../isochrone/Isochrone.tsx | 319 ++++++++++-------- .../isochrone/IsochroneSettings.tsx | 161 +++++---- .../isochrone/StartingPoint.tsx | 97 +++--- .../toolbox/tools/join/FieldsToMatch.tsx | 69 ++-- .../map/panels/toolbox/tools/join/Join.tsx | 167 ++++----- .../panels/toolbox/tools/join/Statistics.tsx | 57 ++-- apps/web/lib/validations/isochrone.ts | 127 ++++--- 10 files changed, 616 insertions(+), 467 deletions(-) diff --git a/apps/web/components/map/panels/toolbox/Toolbox.tsx b/apps/web/components/map/panels/toolbox/Toolbox.tsx index da263120..c7f59abf 100644 --- a/apps/web/components/map/panels/toolbox/Toolbox.tsx +++ b/apps/web/components/map/panels/toolbox/Toolbox.tsx @@ -48,6 +48,7 @@ const ToolboxPanel = () => { setDefaultRoute={setDefaultRoute} /> } + disablePadding /> ); }; diff --git a/apps/web/components/map/panels/toolbox/tools/InputLayer.tsx b/apps/web/components/map/panels/toolbox/tools/InputLayer.tsx index 0f6d5159..49651d10 100644 --- a/apps/web/components/map/panels/toolbox/tools/InputLayer.tsx +++ b/apps/web/components/map/panels/toolbox/tools/InputLayer.tsx @@ -14,16 +14,27 @@ import { useProjectLayers } from "@/lib/api/projects"; import { useParams } from "next/navigation"; import type { SelectChangeEvent } from "@mui/material"; +import type { UseFormGetValues, UseFormRegister } from "react-hook-form"; +import type { PostJoin, PostAggregate } from "@/lib/validations/tools"; interface PickLayerProps { + register: UseFormRegister | UseFormRegister; + getValues: UseFormGetValues | UseFormGetValues; multiple?: boolean; - inputValues: string | string[]; - setInputValues: (value: string | string[]) => void; - layerTypes: string[]; + // inputValues: string | string[]; + // setInputValues: (value: string | string[]) => void; + // layerTypes: string[]; } const InputLayer = (props: PickLayerProps) => { - const { multiple = false, inputValues, setInputValues, layerTypes } = props; + const { + register, + getValues, + multiple = false, + // inputValues, + // setInputValues, + // layerTypes + } = props; const theme = useTheme(); const { t } = useTranslation("maps"); @@ -35,15 +46,15 @@ const InputLayer = (props: PickLayerProps) => { ); const handleSingleChange = (event: SelectChangeEvent) => { - setInputValues(event.target.value as string); + // setInputValues(event.target.value as string); }; const handleMultipleChange = (event: SelectChangeEvent, inputNr: number) => { - const multipleValues = - typeof inputValues !== "string" ? [...inputValues] : ["", ""]; - multipleValues[inputNr] = event.target.value as string; + // const multipleValues = + // typeof inputValues !== "string" ? [...inputValues] : ["", ""]; + // multipleValues[inputNr] = event.target.value as string; - setInputValues(multipleValues); + // setInputValues(multipleValues); }; return ( @@ -68,7 +79,8 @@ const InputLayer = (props: PickLayerProps) => { - {projectLayers ? projectLayers.map((layer) => - layerTypes.includes(layer.feature_layer_geometry_type) ? ( - - {layer.name} - - ) : null, - ) : null} + {projectLayers + ? projectLayers.map((layer) => + layerTypes.includes(layer.feature_layer_geometry_type) ? ( + + {layer.name} + + ) : null, + ) + : null} diff --git a/apps/web/components/map/panels/toolbox/tools/SaveResult.tsx b/apps/web/components/map/panels/toolbox/tools/SaveResult.tsx index f925d90b..6259b396 100644 --- a/apps/web/components/map/panels/toolbox/tools/SaveResult.tsx +++ b/apps/web/components/map/panels/toolbox/tools/SaveResult.tsx @@ -19,24 +19,32 @@ import { v4 } from "uuid"; import { useTranslation } from "@/i18n/client"; import { useGetUniqueLayerName } from "@/hooks/map/ToolsHooks"; -import type { SelectChangeEvent } from "@mui/material"; +// import type { SelectChangeEvent } from "@mui/material"; +import type { UseFormGetValues, UseFormRegister } from "react-hook-form"; +import type { PostAggregate, PostJoin } from "@/lib/validations/tools"; +import type { PostIsochrone } from "@/lib/validations/isochrone"; interface SaveResultProps { - outputName: string | undefined; - setOutputName: (value: string) => void; - folderSaveId: string | undefined; - setFolderSaveID: (value: string) => void; + register: UseFormRegister | UseFormRegister | UseFormRegister; + watch: PostJoin | PostAggregate | PostIsochrone; + // outputName: string | undefined; + // setOutputName: (value: string) => void; + // folderSaveId: string | undefined; + // setFolderSaveID: (value: string) => void; } const SaveResult = (props: SaveResultProps) => { - const { outputName, setOutputName, folderSaveId, setFolderSaveID } = props; + const { + register, + watch, + } = props; const theme = useTheme(); const { t } = useTranslation("maps"); const { folders } = useFolders(); - const { uniqueName } = useGetUniqueLayerName(outputName ? outputName : ""); + const { uniqueName } = useGetUniqueLayerName(watch.result_target.layer_name ? watch.result_target.layer_name : ""); return ( @@ -93,9 +101,10 @@ const SaveResult = (props: SaveResultProps) => { value={uniqueName ? uniqueName : ""} label="Name" size="small" - onChange={(event: React.ChangeEvent) => - setOutputName(event.target.value as string) - } + {...register("result_target.layer_name")} + // onChange={(event: React.ChangeEvent) => + // setOutputName(event.target.value as string) + // } /> @@ -108,10 +117,7 @@ const SaveResult = (props: SaveResultProps) => { ) => { - setRouting(event.target.value as RoutingTypes); + if (event.target.value === "pt") { + setValue("routing_type", { + mode: [], + egress_mode: "walk", + access_mode: "walk", + }); + } else { + setValue("routing_type", event.target.value); + } dispatch(removeMarker()); }} > @@ -299,7 +291,7 @@ const IsochroneSettings = (props: PickLayerProps) => { {/*--------------------------PT Options--------------------------*/} - {routing === ("pt" as RoutingTypes) ? ( + {watch.routing_type === ("pt" as RoutingTypes) ? ( { )} fullWidth - defaultValue={ptModes.filter( - (mode) => getPtModes?.includes(mode.value as PTModeTypes), - )} + {...register("routing_type.mode")} size="small" renderInput={(params) => ( { placeholder={t("panels.isochrone.routing.pt_type")} /> )} - onChange={(_, value) => { - setPtModes(value.map((val) => val.value) as PTModeTypes[]); - }} /> ) : null} {/*--------------------------------------------------------------*/} { setTab(newValue as "distance" | "time"); + setValue( + "travel_cost", + newValue === "distance" + ? { + max_distance: 10, + distance_step: 10, + } + : { + max_traveltime: 10, + traveltime_step: 10, + speed: 10, + }, + ); }} variant="fullWidth" > - + { - {routing !== ("pt" as RoutingTypes) ? speedFunctionality() : null} + {typeof watch.routing_type === "string" ? speedFunctionality() : null} {travelTimeFunctionality()} {stepFunctionality()} diff --git a/apps/web/components/map/panels/toolbox/tools/accessibility_indicators/isochrone/StartingPoint.tsx b/apps/web/components/map/panels/toolbox/tools/accessibility_indicators/isochrone/StartingPoint.tsx index c5ae09da..bf0d8598 100644 --- a/apps/web/components/map/panels/toolbox/tools/accessibility_indicators/isochrone/StartingPoint.tsx +++ b/apps/web/components/map/panels/toolbox/tools/accessibility_indicators/isochrone/StartingPoint.tsx @@ -25,33 +25,28 @@ import { useDispatch } from "react-redux"; import { addMarker, removeMarker } from "@/lib/store/map/slice"; import type { StartingPointType } from "@/types/map/isochrone"; -import type { SelectChangeEvent } from "@mui/material"; import type { Result } from "@/types/map/controllers"; import type { FeatureCollection } from "geojson"; -import type { RoutingTypes } from "@/types/map/isochrone"; +import type { UseFormRegister, UseFormSetValue } from "react-hook-form"; +import type { PostIsochrone } from "@/lib/validations/isochrone"; +import type { SelectChangeEvent } from "@mui/material"; interface PickLayerProps { - routing: RoutingTypes | undefined; + register: UseFormRegister; + // getValues: UseFormGetValues; + setValue: UseFormSetValue; + watch: PostIsochrone; startingType: StartingPointType | undefined; setStartingType: (value: StartingPointType) => void; - startingPoint: string[] | string; - setStartingPoint: (value: string[] | string) => void; } -const isochroneMarkerIcons = { - walking: ICON_NAME.RUN, - padelec: ICON_NAME.PEDELEC, - bicycle: ICON_NAME.BICYCLE, - pt: ICON_NAME.BUS, - car_peak: ICON_NAME.CAR, -}; - const StartingPoint = (props: PickLayerProps) => { const { - routing, + register, + // getValues, + setValue: setFormValue, startingType, - setStartingPoint, - startingPoint, + watch, setStartingType, } = props; // const { projectLayers } = useProjectLayers(); @@ -94,17 +89,21 @@ const StartingPoint = (props: PickLayerProps) => { useEffect(() => { const handleMapClick = (event) => { - if (getCoordinates && typeof startingPoint !== "string") { - startingPoint?.push(`${event.lngLat.lat},${event.lngLat.lng}`); - setStartingPoint(startingPoint); + if (getCoordinates) { dispatch( addMarker({ - id: `isochrone-${(startingPoint ? startingPoint?.length : 0) + 1}`, + id: `isochrone-${watch.starting_points.latitude.length}`, lat: event.lngLat.lat, long: event.lngLat.lng, - iconName: isochroneMarkerIcons[routing ? routing : "walking"], + iconName: ICON_NAME.LOCATION, }), ); + watch.starting_points.latitude.push(event.lngLat.lat); + watch.starting_points.longitude.push(event.lngLat.lat); + setFormValue("starting_points", { + latitude: watch.starting_points.latitude, + longitude: watch.starting_points.longitude, + }); } }; @@ -114,7 +113,7 @@ const StartingPoint = (props: PickLayerProps) => { map.off("click", handleMapClick); }; // eslint-disable-next-line react-hooks/exhaustive-deps - }, [getCoordinates, routing]); + }, [getCoordinates, watch.routing_type]); useEffect(() => { let active = true; @@ -125,6 +124,9 @@ const StartingPoint = (props: PickLayerProps) => { const resultCoordinates = testForCoordinates(inputValue); if (resultCoordinates[0]) { const [_, latitude, longitude] = resultCoordinates; + + setFormValue("starting_points", {latitude: [latitude], longitude: [longitude]}) + setOptions([ { feature: { @@ -214,11 +216,16 @@ const StartingPoint = (props: PickLayerProps) => { { - setStartingPoint(event.target.value as string); - }} + {...register("starting_points.layer_id")} > {projectLayers ? projectLayers.map((layer) => @@ -302,13 +306,32 @@ const StartingPoint = (props: PickLayerProps) => { > + `${el},${watch.starting_points.longitude[index]}`, + ) + .join(";") : "" } size="small" onChange={(event: React.ChangeEvent) => { - setStartingPoint(event.target.value.split(";") as string[]); + const inputCoords = event.target.value; + const [latitudes, longitudes] = inputCoords + .split(";") + .map((pair) => pair.split(",")) + .reduce( + ([latAcc, lonAcc], [latitude, longitude]) => [ + [...latAcc, parseFloat(latitude)], + [...lonAcc, parseFloat(longitude)], + ], + [[], []], + ); + setFormValue("starting_points", { + latitude: latitudes, + longitude: longitudes, + }); }} sx={{ margin: `${theme.spacing(1)} 0`, @@ -345,13 +368,6 @@ const StartingPoint = (props: PickLayerProps) => { }} onChange={(_event: unknown, newValue: Result | null) => { setOptions(newValue ? [newValue, ...options] : options); - setStartingPoint( - newValue?.feature.center - ? newValue?.feature.center - .reverse() - .map((coord) => coord.toString()) - : [], - ); setValue(newValue); }} onInputChange={(_event, newInputValue) => { @@ -361,7 +377,8 @@ const StartingPoint = (props: PickLayerProps) => { )} /> diff --git a/apps/web/components/map/panels/toolbox/tools/join/FieldsToMatch.tsx b/apps/web/components/map/panels/toolbox/tools/join/FieldsToMatch.tsx index a64b2e74..e1ce3152 100644 --- a/apps/web/components/map/panels/toolbox/tools/join/FieldsToMatch.tsx +++ b/apps/web/components/map/panels/toolbox/tools/join/FieldsToMatch.tsx @@ -13,34 +13,43 @@ import { Icon, ICON_NAME } from "@p4b/ui/components/Icon"; import { useTranslation } from "@/i18n/client"; import { useGetLayerKeys } from "@/hooks/map/ToolsHooks"; -import type { SelectChangeEvent } from "@mui/material"; +// import type { SelectChangeEvent } from "@mui/material"; +import type { UseFormGetValues, UseFormRegister } from "react-hook-form"; +import type { PostJoin } from "@/lib/validations/tools"; interface FieldsToMatchProps { - setFirstField: (value: string) => void; - firstField: string | undefined; - setSecondField: (value: string) => void; - secondField: string | undefined; - firstLayerId: string; - secondLayerId: string; + register: UseFormRegister; + getValues: UseFormGetValues; + // setFirstField: (value: string) => void; + // firstField: string | undefined; + // setSecondField: (value: string) => void; + // secondField: string | undefined; + // firstLayerId: string; + // secondLayerId: string; } const FieldsToMatch = (props: FieldsToMatchProps) => { const { - firstLayerId, - secondLayerId, - setFirstField, - setSecondField, - firstField, - secondField, + register, + getValues, + // firstLayerId, + // secondLayerId, + // setFirstField, + // setSecondField, + // firstField, + // secondField, } = props; const { t } = useTranslation("maps"); const theme = useTheme(); - - const firstLayerKeys = useGetLayerKeys(`user_data.${firstLayerId.split("-").join("")}`); - const secondLayerKeys = useGetLayerKeys(`user_data.${secondLayerId.split("-").join("")}`); - + const firstLayerKeys = useGetLayerKeys( + `user_data.${getValues("target_layer_id").split("-").join("")}`, + ); + const secondLayerKeys = useGetLayerKeys( + `user_data.${getValues("join_layer_id").split("-").join("")}`, + ); + return ( @@ -68,14 +77,15 @@ const FieldsToMatch = (props: FieldsToMatchProps) => { {t("panels.tools.select_field")} { - setSecondField(event.target.value as string); - }} + {...register("join_field")} + // value={secondField} + // onChange={(event: SelectChangeEvent) => { + // setSecondField(event.target.value as string); + // }} > - {secondLayerId.length + {getValues("join_layer_id").length ? secondLayerKeys.keys.map((key) => ( {key.name} diff --git a/apps/web/components/map/panels/toolbox/tools/join/Join.tsx b/apps/web/components/map/panels/toolbox/tools/join/Join.tsx index eea39030..a3248217 100644 --- a/apps/web/components/map/panels/toolbox/tools/join/Join.tsx +++ b/apps/web/components/map/panels/toolbox/tools/join/Join.tsx @@ -1,84 +1,76 @@ -import React, { useState } from "react"; +import React from "react"; import InputLayer from "@/components/map/panels/toolbox/tools/InputLayer"; import FieldsToMatch from "@/components/map/panels/toolbox/tools/join/FieldsToMatch"; import Statistics from "@/components/map/panels/toolbox/tools/join/Statistics"; import { Divider, useTheme, Box, Button } from "@mui/material"; -import { SendJoinFeatureRequest } from "@/lib/api/tools"; +// import { SendJoinFeatureRequest } from "@/lib/api/tools"; import { useTranslation } from "@/i18n/client"; import SaveResult from "@/components/map/panels/toolbox/tools/SaveResult"; +import { useForm } from "react-hook-form"; import type { PostJoin } from "@/lib/validations/tools"; -type ColumStatisticsOperation = - | "count" - | "sum" - | "mean" - | "median" - | "min" - | "max"; +// type ColumStatisticsOperation = +// | "count" +// | "sum" +// | "mean" +// | "median" +// | "min" +// | "max"; -interface JoinProps { - projectId: string; -} - -const Join = (props: JoinProps) => { - const { projectId } = props; - - const [inputValues, setInputValues] = useState(["", ""]); - const [firstField, setFirstField] = useState(undefined); - const [secondField, setSecondField] = useState(undefined); - const [method, setMethod] = useState( - undefined, - ); - const [statisticField, setStatisticField] = useState( - undefined, - ); - const [outputName, setOutputName] = useState("join"); - const [folderSaveID, setFolderSaveID] = useState( - undefined, - ); +const Join = () => { + // const [inputValues, setInputValues] = useState(["", ""]); const theme = useTheme(); const { t } = useTranslation("maps"); + const { + // handleSubmit, + register, + // reset, + // watch, + getValues, + // formState: { errors }, + // control, + } = useForm(); + const handleReset = () => { - setInputValues(["", ""]); - setFirstField(undefined); - setSecondField(undefined); - setMethod(undefined); - setStatisticField(undefined); + // setInputValues(["", ""]); + // setFirstField(undefined); + // setSecondField(undefined); + // setMethod(undefined); + // setStatisticField(undefined); }; const handleRun = () => { - if ( - inputValues[0].length && - inputValues[1].length && - firstField && - secondField && - method && - statisticField - ) { - const requestBody: PostJoin = { - target_layer_id: inputValues[0], - target_field: firstField, - join_layer_id: inputValues[1], - join_field: secondField, - column_statistics: { - operation: method, - field: statisticField, - }, - result_target: { - layer_name: outputName ? outputName : `${statisticField}_${method}`, - folder_id: "159cc0f9-81e9-497d-8823-d9d37507ed54", - project_id: projectId - }, - }; - - console.log(requestBody); - SendJoinFeatureRequest(requestBody); - } else { - console.log("Error: Not all fields are filled"); - } + // if ( + // inputValues[0].length && + // inputValues[1].length && + // firstField && + // secondField && + // method && + // statisticField + // ) { + // const requestBody: PostJoin = { + // target_layer_id: inputValues[0], + // target_field: firstField, + // join_layer_id: inputValues[1], + // join_field: secondField, + // column_statistics: { + // operation: method, + // field: statisticField, + // }, + // result_target: { + // layer_name: outputName ? outputName : `${statisticField}_${method}`, + // folder_id: "159cc0f9-81e9-497d-8823-d9d37507ed54", + // project_id: projectId, + // }, + // }; + // console.log(requestBody); + // SendJoinFeatureRequest(requestBody); + // } else { + // console.log("Error: Not all fields are filled"); + // } }; return ( @@ -90,10 +82,12 @@ const Join = (props: JoinProps) => { > { }} /> - {secondField && method ? ( + {getValues("join_layer_id") && + getValues("column_statistics.operation") ? ( ) : null} diff --git a/apps/web/components/map/panels/toolbox/tools/join/Statistics.tsx b/apps/web/components/map/panels/toolbox/tools/join/Statistics.tsx index 828a889e..7425ccf9 100644 --- a/apps/web/components/map/panels/toolbox/tools/join/Statistics.tsx +++ b/apps/web/components/map/panels/toolbox/tools/join/Statistics.tsx @@ -12,30 +12,35 @@ import { import { useTranslation } from "@/i18n/client"; import { useGetLayerKeys } from "@/hooks/map/ToolsHooks"; -import type { SelectChangeEvent } from "@mui/material"; -import type { ColumStatisticsOperation } from "@/types/map/toolbox"; +import type { UseFormGetValues, UseFormRegister } from "react-hook-form"; +import type { PostJoin } from "@/lib/validations/tools"; interface StatisticsProps { - secondLayerId: string; - secondField: string | undefined; - setMethod: (value: ColumStatisticsOperation | undefined) => void; - method: ColumStatisticsOperation | undefined; - setStatisticField: (value: string) => void; - statisticField: string | undefined; + register: UseFormRegister; + getValues: UseFormGetValues; + // secondLayerId: string; + // secondField: string | undefined; + // setMethod: (value: ColumStatisticsOperation | undefined) => void; + // method: ColumStatisticsOperation | undefined; + // setStatisticField: (value: string) => void; + // statisticField: string | undefined; } const Statistics = (props: StatisticsProps) => { const { - secondLayerId, - secondField, - setMethod, - method, - setStatisticField, - statisticField + register, + getValues, + // secondLayerId, + // secondField, + // setMethod, + // method, + // setStatisticField, + // statisticField } = props; const theme = useTheme(); const { t } = useTranslation("maps"); + const method = getValues("column_statistics.operation"); const methods = [ { @@ -64,7 +69,7 @@ const Statistics = (props: StatisticsProps) => { }, ]; - const saveFieldKeys = useGetLayerKeys(`user_data.${secondLayerId.split("-").join("")}`); + const saveFieldKeys = useGetLayerKeys(`user_data.${getValues("join_layer_id").split("-").join("")}`); function checkType() { return saveFieldKeys.keys.map((key) => @@ -97,12 +102,13 @@ const Statistics = (props: StatisticsProps) => { {t("panels.tools.select_method")} { - setStatisticField(event.target.value as string); - }} + // value={statisticField} + // onChange={(event: SelectChangeEvent) => { + // setStatisticField(event.target.value as string); + // }} + {...register("column_statistics.field")} > - {secondLayerId.length ? checkType() : null} + {register("join_layer_id").length ? checkType() : null} diff --git a/apps/web/lib/validations/isochrone.ts b/apps/web/lib/validations/isochrone.ts index 9dc7bfde..7e4f95e8 100644 --- a/apps/web/lib/validations/isochrone.ts +++ b/apps/web/lib/validations/isochrone.ts @@ -1,69 +1,102 @@ import * as z from "zod"; -const StartingPoint = z.object({ - latitude: z.array(z.number()), - longitude: z.array(z.number()) -}).or(z.object({ - layer_id: z.string() -})) +const StartingPoint = z + .object({ + latitude: z.array(z.number()), + longitude: z.array(z.number()), + }) + .or( + z.object({ + layer_id: z.string(), + }), + ); -export const IsochroneBaseSchema = z.object({ - starting_points: StartingPoint, - routing_type: z.string().or(z.object({ - mode: z.array(z.string()), - egress_mode: z.string(), - access_mode: z.string() - })), - travel_cost: z.object({ +const TraveltimeCost = z + .object({ max_traveltime: z.number(), traveltime_step: z.number(), speed: z.number().optional(), - }).or(z.object({ - max_distance: z.number(), - distance_step: z.number() - })), - time_window: z.object({ - weekday: z.string(), - from_time: z.number(), - to_time: z.number(), - }).optional(), + }) + .refine((schema) => { + return !( + schema.traveltime_step <= schema.max_traveltime + ); + }); + +const DistanceCost = z.object({ + max_distance: z.number(), + distance_step: z.number(), + speed: z.number().optional(), +}).refine((schema) => { + return !( + schema.distance_step <= schema.max_distance + ); +}); + +export const IsochroneBaseSchema = z.object({ + starting_points: StartingPoint, + routing_type: z.string().or( + z.object({ + mode: z.array(z.string()), + egress_mode: z.string(), + access_mode: z.string(), + }), + ), + travel_cost: TraveltimeCost.or(DistanceCost), + time_window: z + .object({ + weekday: z.string(), + from_time: z.number(), + to_time: z.number(), + }) + .optional(), result_target: z.object({ layer_name: z.string(), folder_id: z.string(), - project_id: z.string().optional() - }) + project_id: z.string().optional(), + }), }); export const IsochronePTSchema = z.object({ - starting_points: z.object({ - latitude: z.array(z.number()), - longitude: z.array(z.number()) - }).or(z.object({ - layer_id: z.string() - })), + starting_points: z + .object({ + latitude: z.array(z.number()), + longitude: z.array(z.number()), + }) + .or( + z.object({ + layer_id: z.string(), + }), + ), routing_type: z.object({ mode: z.array(z.string()), egress_mode: z.string(), - access_mode: z.string() + access_mode: z.string(), }), - travel_cost: z.object({ - max_traveltime: z.number(), - traveltime_step: z.number(), - speed: z.number().optional(), - }).or(z.object({ - max_distance: z.number(), - distance_step: z.number() - })), - time_window: z.object({ - weekday: z.string(), - from_time: z.number(), - to_time: z.number(), - }).optional(), + travel_cost: z + .object({ + max_traveltime: z.number(), + traveltime_step: z.number(), + speed: z.number().optional(), + }) + .or( + z.object({ + max_distance: z.number(), + distance_step: z.number(), + }), + ), + time_window: z + .object({ + weekday: z.string(), + from_time: z.number(), + to_time: z.number(), + }) + .optional(), result_target: z.object({ layer_name: z.string(), folder_id: z.string(), - project_id: z.string().optional() - }) + project_id: z.string().optional(), + }), }); export type StartingPointType = z.infer; From b3e050b7cbae809ebf4e39bcfc3564ba8a4cd5fa Mon Sep 17 00:00:00 2001 From: Ebubeker Date: Sun, 10 Dec 2023 19:28:12 +0100 Subject: [PATCH 2/2] fix: using use form to make the code a bit cleaner --- .../map/panels/toolbox/tools/InputLayer.tsx | 7 +- .../map/panels/toolbox/tools/SaveResult.tsx | 3 +- .../isochrone/Isochrone.tsx | 142 +++--------------- .../isochrone/IsochroneSettings.tsx | 44 ++++-- apps/web/lib/validations/isochrone.ts | 68 ++------- 5 files changed, 65 insertions(+), 199 deletions(-) diff --git a/apps/web/components/map/panels/toolbox/tools/InputLayer.tsx b/apps/web/components/map/panels/toolbox/tools/InputLayer.tsx index 49651d10..6ed4b75b 100644 --- a/apps/web/components/map/panels/toolbox/tools/InputLayer.tsx +++ b/apps/web/components/map/panels/toolbox/tools/InputLayer.tsx @@ -29,7 +29,7 @@ interface PickLayerProps { const InputLayer = (props: PickLayerProps) => { const { register, - getValues, + // getValues, multiple = false, // inputValues, // setInputValues, @@ -45,11 +45,12 @@ const InputLayer = (props: PickLayerProps) => { typeof projectId === "string" ? projectId : "", ); - const handleSingleChange = (event: SelectChangeEvent) => { + const handleSingleChange = (_: SelectChangeEvent) => { // setInputValues(event.target.value as string); }; - const handleMultipleChange = (event: SelectChangeEvent, inputNr: number) => { + const handleMultipleChange = (_: SelectChangeEvent, inputNr: number) => { + console.log(inputNr); // const multipleValues = // typeof inputValues !== "string" ? [...inputValues] : ["", ""]; // multipleValues[inputNr] = event.target.value as string; diff --git a/apps/web/components/map/panels/toolbox/tools/SaveResult.tsx b/apps/web/components/map/panels/toolbox/tools/SaveResult.tsx index 6259b396..a5c78af7 100644 --- a/apps/web/components/map/panels/toolbox/tools/SaveResult.tsx +++ b/apps/web/components/map/panels/toolbox/tools/SaveResult.tsx @@ -20,7 +20,7 @@ import { useTranslation } from "@/i18n/client"; import { useGetUniqueLayerName } from "@/hooks/map/ToolsHooks"; // import type { SelectChangeEvent } from "@mui/material"; -import type { UseFormGetValues, UseFormRegister } from "react-hook-form"; +import type { UseFormRegister } from "react-hook-form"; import type { PostAggregate, PostJoin } from "@/lib/validations/tools"; import type { PostIsochrone } from "@/lib/validations/isochrone"; @@ -39,6 +39,7 @@ const SaveResult = (props: SaveResultProps) => { watch, } = props; + const theme = useTheme(); const { t } = useTranslation("maps"); diff --git a/apps/web/components/map/panels/toolbox/tools/accessibility_indicators/isochrone/Isochrone.tsx b/apps/web/components/map/panels/toolbox/tools/accessibility_indicators/isochrone/Isochrone.tsx index 824700d0..cfb39e0c 100644 --- a/apps/web/components/map/panels/toolbox/tools/accessibility_indicators/isochrone/Isochrone.tsx +++ b/apps/web/components/map/panels/toolbox/tools/accessibility_indicators/isochrone/Isochrone.tsx @@ -4,22 +4,16 @@ import IsochroneSettings from "@/components/map/panels/toolbox/tools/accessibili import StartingPoint from "@/components/map/panels/toolbox/tools/accessibility_indicators/isochrone/StartingPoint"; import { useTranslation } from "@/i18n/client"; import SaveResult from "@/components/map/panels/toolbox/tools/SaveResult"; +// import { useDispatch } from "react-redux"; +import { useForm } from "react-hook-form"; import { - SendIsochroneRequest, SendPTIsochroneRequest, SendCarIsochroneRequest, + SendIsochroneRequest, } from "@/lib/api/isochrone"; -import { useDispatch } from "react-redux"; -import { removeMarker } from "@/lib/store/map/slice"; -import { useForm, useWatch } from "react-hook-form"; import type { StartingPointType } from "@/types/map/isochrone"; -import type { RoutingTypes, PTModeTypes } from "@/types/map/isochrone"; -import type { StartingPointType as StartingPointTypeForm } from "@/lib/validations/isochrone"; -import type { - PostIsochrone, - PostPTIsochrone, -} from "@/lib/validations/isochrone"; +import type { PostIsochrone } from "@/lib/validations/isochrone"; const Isochrone = () => { // Isochrone Settings states @@ -43,7 +37,7 @@ const Isochrone = () => { const [startingType, setStartingType] = useState< StartingPointType | undefined >(undefined); - const [startingPoint, setStartingPoint] = useState([]); + // const [startingPoint, setStartingPoint] = useState([]); // Save Result states // const [outputName, setOutputName] = useState(`isochrone`); @@ -53,17 +47,15 @@ const Isochrone = () => { const theme = useTheme(); const { t } = useTranslation("maps"); - const dispatch = useDispatch(); + // const dispatch = useDispatch(); const { - // handleSubmit, register, reset, watch, getValues, setValue, // formState: { errors }, - control, } = useForm({ defaultValues: { routing_type: "", @@ -73,15 +65,10 @@ const Isochrone = () => { }, travel_cost: { max_traveltime: 10, - traveltime_step: 10, + traveltime_step: 50, speed: 10, }, time_window: undefined, - // { - // weekday: z.string(), - // from_time: z.number(), - // to_time: z.number(), - // }, result_target: { layer_name: "isochrone", folder_id: "", @@ -94,107 +81,23 @@ const Isochrone = () => { const handleReset = () => { reset(); - // setRouting(undefined); - // setSpeed(undefined); - // setDistance(undefined); - // setTravelTime(undefined); - // setSteps(undefined); - // setOutputName(`isochrone`); - // setFolderSaveID(undefined); - // setStartingType(undefined); - // setStartingPoint([]); - // dispatch(removeMarker()); - }; - // const getStartingPoint = (): StartingPointTypeForm => { - // switch (startingType) { - // case "place_on_map": - // return { - // latitude: [ - // ...(typeof startingPoint !== "string" - // ? startingPoint.map((startPoint) => - // parseFloat(startPoint.split(",")[0]), - // ) - // : []), - // ], - // longitude: [ - // ...(typeof startingPoint !== "string" - // ? startingPoint.map((startPoint) => - // parseFloat(startPoint.split(",")[1]), - // ) - // : []), - // ], - // }; - // case "address_input": - // return { - // latitude: [parseFloat(startingPoint[1])], - // longitude: [parseFloat(startingPoint[0])], - // }; - // case "browse_layers": - // return { - // layer_id: startingPoint === "string" ? startingPoint : "", - // }; - // // never gonna happen, but just to remove the linting issue - // default: - // return { - // layer_id: "", - // }; - // } - // }; - const handleRun = () => { console.log("body of the request: ", getValues()); - // if ( - // routing && - // startingPoint && - // startingPoint.length && - // startingType && - // steps && - // outputName && - // folderSaveID - // ) { - // const isochroneBody: PostIsochrone | PostPTIsochrone = { - // starting_points: getStartingPoint(), - // result_target: { - // layer_name: outputName, - // folder_id: folderSaveID, - // }, - // travel_cost: distance - // ? { - // max_distance: distance, - // distance_step: steps, - // } - // : { - // max_traveltime: travelTime ? travelTime : 10, - // traveltime_step: steps, - // speed: speed ?? undefined, - // }, - // ...(routing === "pt" - // ? { - // routing_type: { - // mode: ptModes as string[], - // egress_mode: "walk", - // access_mode: "walk", - // }, - // time_window: { - // weekday: "weekday", - // from_time: 25200, - // to_time: 32400, - // }, - // } - // : { - // routing_type: routing, - // }), - // }; - // if (routing === "pt") { - // SendPTIsochroneRequest(isochroneBody); - // } else if (routing === "car_peak") { - // SendCarIsochroneRequest(isochroneBody); - // } else { - // SendIsochroneRequest(isochroneBody); - // } + if (typeof watchFormValues.routing_type !== "string") { + setValue("time_window", { + weekday: "weekday", + from_time: 25200, + to_time: 32400, + }); + SendPTIsochroneRequest(getValues()); + } else if (watchFormValues.routing_type === "car_peak") { + SendCarIsochroneRequest(getValues()); + } else { + SendIsochroneRequest(getValues()); + } // } }; @@ -202,13 +105,6 @@ const Isochrone = () => { return watchFormValues; }, [watchFormValues]); - // useEffect(() => { - // const subscription = watch((value) => - // console.log(value) - // ) - // return () => subscription.unsubscribe() - // }, [watch]) - return ( ; @@ -57,8 +57,6 @@ const IsochroneSettings = (props: PickLayerProps) => { })), ]; - // console.log("routing: ", watch); - function speedFunctionality() { return ( { } function stepFunctionality() { - // const isValidStep = steps - // ? steps % 5 !== 0 || steps > (travelTime ? travelTime : 0) - // : false; - return ( { ); } + // useEffect(() => { + // if(watch.routing_type === "pt"){ + // setValue("routing_type", ) + // } + // }, []) + return ( <> {