From f81ff82f2a07f87f6eb4f43de49ede64215519e5 Mon Sep 17 00:00:00 2001 From: Ariel Costas Guerrero Date: Sat, 27 Dec 2025 16:39:09 +0100 Subject: Refactor route planner to use new GraphQL backend --- src/frontend/app/routes/planner.tsx | 106 +++++++++++++++--------------------- 1 file changed, 44 insertions(+), 62 deletions(-) (limited to 'src/frontend/app/routes/planner.tsx') diff --git a/src/frontend/app/routes/planner.tsx b/src/frontend/app/routes/planner.tsx index e99cb03..44488c8 100644 --- a/src/frontend/app/routes/planner.tsx +++ b/src/frontend/app/routes/planner.tsx @@ -1,53 +1,24 @@ import { Coins, CreditCard, Footprints } from "lucide-react"; -import maplibregl, { type StyleSpecification } from "maplibre-gl"; +import maplibregl from "maplibre-gl"; import "maplibre-gl/dist/maplibre-gl.css"; import React, { useEffect, useMemo, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { Layer, Source, type MapRef } from "react-map-gl/maplibre"; import { useLocation } from "react-router"; -import { useApp } from "~/AppContext"; +import { type ConsolidatedCirculation, type Itinerary } from "~/api/schema"; import LineIcon from "~/components/LineIcon"; import { PlannerOverlay } from "~/components/PlannerOverlay"; import { AppMap } from "~/components/shared/AppMap"; import { APP_CONSTANTS } from "~/config/constants"; import { usePageTitle } from "~/contexts/PageTitleContext"; -import { type Itinerary } from "~/data/PlannerApi"; import { usePlanner } from "~/hooks/usePlanner"; import "../tailwind-full.css"; -export interface ConsolidatedCirculation { - line: string; - route: string; - schedule?: { - running: boolean; - minutes: number; - serviceId: string; - tripId: string; - shapeId?: string; - }; - realTime?: { - minutes: number; - distance: number; - }; - currentPosition?: { - latitude: number; - longitude: number; - orientationDegrees: number; - shapeIndex?: number; - }; - isPreviousTrip?: boolean; - previousTripShapeId?: string; - nextStreets?: string[]; -} - -const FARE_CASH_PER_BUS = 1.63; -const FARE_CARD_PER_BUS = 0.67; - const formatDistance = (meters: number) => { - const intMeters = Math.round(meters); - if (intMeters >= 1000) return `${(intMeters / 1000).toFixed(1)} km`; - return `${intMeters} m`; + if (meters >= 1000) return `${(meters / 1000).toFixed(1)} km`; + const rounded = Math.round(meters / 100) * 100; + return `${rounded} m`; }; const haversineMeters = (a: [number, number], b: [number, number]) => { @@ -116,12 +87,8 @@ const ItinerarySummary = ({ const busLegsCount = itinerary.legs.filter( (leg) => leg.mode !== "WALK" ).length; - const cashFare = ( - itinerary.cashFareEuro ?? busLegsCount * FARE_CASH_PER_BUS - ).toFixed(2); - const cardFare = ( - itinerary.cardFareEuro ?? busLegsCount * FARE_CARD_PER_BUS - ).toFixed(2); + const cashFare = (itinerary.cashFareEuro ?? 0).toFixed(2); + const cardFare = (itinerary.cardFareEuro ?? 0).toFixed(2); return (
{startTime} - {endTime}
-
- {durationMinutes} min -
+
{durationMinutes} min
@@ -168,6 +133,8 @@ const ItinerarySummary = ({
)} @@ -180,7 +147,7 @@ const ItinerarySummary = ({ {t("planner.walk")}: {formatDistance(walkTotals.meters)} {walkTotals.minutes - ? ` • ${walkTotals.minutes} {t("estimates.minutes")}` + ? ` • ${walkTotals.minutes} ${t("estimates.minutes")}` : ""} @@ -566,7 +533,7 @@ const ItineraryDetail = ({ {/* Details Panel */} -
+

{t("planner.itinerary_details")} @@ -575,7 +542,7 @@ const ItineraryDetail = ({
{itinerary.legs.map((leg, idx) => (
-
+
{leg.mode === "WALK" ? (
)} {idx < itinerary.legs.length - 1 && ( @@ -598,29 +567,42 @@ const ItineraryDetail = ({ {leg.mode === "WALK" ? ( t("planner.walk") ) : ( - <> - +
+ + {t("planner.direction")} + + {leg.headsign || leg.routeLongName || leg.routeName || ""} - +
)}
-
- {new Date(leg.startTime).toLocaleTimeString([], { - hour: "2-digit", - minute: "2-digit", - timeZone: "Europe/Madrid", - })}{" "} - -{" "} - {( - (new Date(leg.endTime).getTime() - - new Date(leg.startTime).getTime()) / - 60000 - ).toFixed(0)}{" "} - {t("estimates.minutes")} +
+ + {new Date(leg.startTime).toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + timeZone: "Europe/Madrid", + })}{" "} + -{" "} + {( + (new Date(leg.endTime).getTime() - + new Date(leg.startTime).getTime()) / + 60000 + ).toFixed(0)}{" "} + {t("estimates.minutes")} + + + {formatDistance(leg.distanceMeters)} + {leg.agencyName && ( + <> + + {leg.agencyName} + + )}
{leg.mode !== "WALK" && leg.from?.stopId && -- cgit v1.3