From 120a3c6bddd0fb8d9fa05df4763596956554c025 Mon Sep 17 00:00:00 2001 From: Ariel Costas Guerrero Date: Sun, 28 Dec 2025 23:08:25 +0100 Subject: Improve planning widget --- src/frontend/app/routes/map.tsx | 178 +++++++++++++++++++++++++++++++--------- 1 file changed, 141 insertions(+), 37 deletions(-) (limited to 'src/frontend/app/routes') diff --git a/src/frontend/app/routes/map.tsx b/src/frontend/app/routes/map.tsx index b8f179c..a651893 100644 --- a/src/frontend/app/routes/map.tsx +++ b/src/frontend/app/routes/map.tsx @@ -1,6 +1,4 @@ -import StopDataProvider from "../data/StopDataProvider"; -import "./map.css"; - +import { Check, X } from "lucide-react"; import type { FilterSpecification } from "maplibre-gl"; import { useMemo, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -19,8 +17,11 @@ import { import { PlannerOverlay } from "~/components/PlannerOverlay"; import { AppMap } from "~/components/shared/AppMap"; import { usePageTitle } from "~/contexts/PageTitleContext"; +import { reverseGeocode } from "~/data/PlannerApi"; import { usePlanner } from "~/hooks/usePlanner"; +import StopDataProvider from "../data/StopDataProvider"; import "../tailwind-full.css"; +import "./map.css"; // Componente principal del mapa export default function StopMap() { @@ -38,7 +39,52 @@ export default function StopMap() { const [isSheetOpen, setIsSheetOpen] = useState(false); const mapRef = useRef(null); - const { searchRoute } = usePlanner({ autoLoad: false }); + const { + searchRoute, + pickingMode, + setPickingMode, + setOrigin, + setDestination, + addRecentPlace, + } = usePlanner({ autoLoad: false }); + + const [isConfirming, setIsConfirming] = useState(false); + + const handleConfirmPick = async () => { + if (!mapRef.current || !pickingMode) return; + const center = mapRef.current.getCenter(); + setIsConfirming(true); + + try { + const result = await reverseGeocode(center.lat, center.lng); + const finalResult = { + name: + result?.name || `${center.lat.toFixed(5)}, ${center.lng.toFixed(5)}`, + label: result?.label || "Map location", + lat: center.lat, + lon: center.lng, + layer: "map-pick", + }; + + if (pickingMode === "origin") { + setOrigin(finalResult); + } else { + setDestination(finalResult); + } + addRecentPlace(finalResult); + setPickingMode(null); + } catch (err) { + console.error("Failed to reverse geocode:", err); + } finally { + setIsConfirming(false); + } + }; + + const onMapInteraction = () => { + if (!pickingMode) { + window.dispatchEvent(new CustomEvent("plannerOverlay:collapse")); + } + }; const favouriteIds = useMemo(() => StopDataProvider.getFavouriteIds(), []); @@ -120,22 +166,78 @@ export default function StopMap() { return (
- searchRoute(o, d, time, arriveBy)} - onNavigateToPlanner={() => navigate("/planner")} - clearPickerOnOpen={true} - showLastDestinationWhenCollapsed={false} - cardBackground="bg-white/95 dark:bg-slate-900/90" - autoLoad={false} - /> + {!pickingMode && ( + searchRoute(o, d, time, arriveBy)} + onNavigateToPlanner={() => navigate("/planner")} + clearPickerOnOpen={true} + showLastDestinationWhenCollapsed={false} + cardBackground="bg-white/95 dark:bg-slate-900/90" + autoLoad={false} + /> + )} + + {pickingMode && ( +
+
+
+

+ {pickingMode === "origin" + ? t("planner.pick_origin", "Select origin") + : t("planner.pick_destination", "Select destination")} +

+ +
+

+ {t( + "planner.pick_instruction", + "Move the map to place the target on the desired location" + )} +

+ +
+
+ )} + + {pickingMode && ( +
+
+ {/* Modern discrete target */} +
+
+
+
+
+ )} - + {!pickingMode && ( + + )}