From 276e73412abef28c222c52a84334d49f5e414f3c Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 17 Nov 2025 23:39:08 +0100 Subject: Use consolidated data API in map sheet with shared card component (#100) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: arielcostas <94913521+arielcostas@users.noreply.github.com> Co-authored-by: Ariel Costas Guerrero --- src/frontend/app/components/StopSheet.tsx | 105 ++++++++++-------------------- 1 file changed, 34 insertions(+), 71 deletions(-) (limited to 'src/frontend/app/components/StopSheet.tsx') diff --git a/src/frontend/app/components/StopSheet.tsx b/src/frontend/app/components/StopSheet.tsx index 6977d87..2a28d36 100644 --- a/src/frontend/app/components/StopSheet.tsx +++ b/src/frontend/app/components/StopSheet.tsx @@ -1,15 +1,16 @@ -import { Clock, RefreshCw } from "lucide-react"; +import { RefreshCw } from "lucide-react"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { Sheet } from "react-modal-sheet"; import { Link } from "react-router"; import type { Stop } from "~/data/StopDataProvider"; import { useApp } from "../AppContext"; -import { REGIONS, type RegionId, getRegionConfig } from "../data/RegionConfig"; -import { type Estimate } from "../routes/estimates-$id"; +import { type RegionId, getRegionConfig } from "../data/RegionConfig"; +import { type ConsolidatedCirculation } from "../routes/stops-$id"; import { ErrorDisplay } from "./ErrorDisplay"; import LineIcon from "./LineIcon"; import { StopAlert } from "./StopAlert"; +import { ConsolidatedCirculationCard } from "./Stops/ConsolidatedCirculationCard"; import "./StopSheet.css"; import { StopSheetSkeleton } from "./StopSheetSkeleton"; @@ -25,16 +26,19 @@ interface ErrorInfo { message?: string; } -const loadStopData = async ( +const loadConsolidatedData = async ( region: RegionId, - stopId: number, -): Promise => { + stopId: number +): Promise => { const regionConfig = getRegionConfig(region); - const resp = await fetch(`${regionConfig.estimatesEndpoint}?id=${stopId}`, { - headers: { - Accept: "application/json", - }, - }); + const resp = await fetch( + `${regionConfig.consolidatedCirculationsEndpoint}?stopId=${stopId}`, + { + headers: { + Accept: "application/json", + }, + } + ); if (!resp.ok) { throw new Error(`HTTP ${resp.status}: ${resp.statusText}`); @@ -50,7 +54,8 @@ export const StopSheet: React.FC = ({ }) => { const { t } = useTranslation(); const { region } = useApp(); - const [data, setData] = useState(null); + const regionConfig = getRegionConfig(region); + const [data, setData] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [lastUpdated, setLastUpdated] = useState(null); @@ -82,7 +87,7 @@ export const StopSheet: React.FC = ({ setError(null); setData(null); - const stopData = await loadStopData(region, stop.stopId); + const stopData = await loadConsolidatedData(region, stop.stopId); setData(stopData); setLastUpdated(new Date()); } catch (err) { @@ -99,33 +104,15 @@ export const StopSheet: React.FC = ({ } }, [isOpen, stop.stopId, region]); - const formatTime = (minutes: number) => { - if (minutes > 15) { - const now = new Date(); - const arrival = new Date(now.getTime() + minutes * 60000); - return Intl.DateTimeFormat( - typeof navigator !== "undefined" ? navigator.language : "en", - { - hour: "2-digit", - minute: "2-digit", - }, - ).format(arrival); - } else { - return `${minutes} ${t("estimates.minutes", "min")}`; - } - }; - - const formatDistance = (meters: number) => { - if (meters > 1024) { - return `${(meters / 1000).toFixed(1)} km`; - } else { - return `${meters} ${t("estimates.meters", "m")}`; - } - }; - // Show only the next 4 arrivals - const limitedEstimates = - data?.sort((a, b) => a.minutes - b.minutes).slice(0, 4) || []; + const sortedData = data + ? [...data].sort( + (a, b) => + (a.realTime?.minutes ?? a.schedule?.minutes ?? 999) - + (b.realTime?.minutes ?? b.schedule?.minutes ?? 999) + ) + : []; + const limitedEstimates = sortedData.slice(0, 4); return ( @@ -158,7 +145,7 @@ export const StopSheet: React.FC = ({ onRetry={loadData} title={t( "errors.estimates_title", - "Error al cargar estimaciones", + "Error al cargar estimaciones" )} className="compact" /> @@ -176,36 +163,15 @@ export const StopSheet: React.FC = ({ ) : (
{limitedEstimates.map((estimate, idx) => ( -
-
- -
-
-
- {estimate.route} -
-
-
-
- - {formatTime(estimate.minutes)} -
- {REGIONS[region].showMeters && - estimate.meters >= 0 && ( -
- {formatDistance(estimate.meters)} -
- )} -
-
+ ))}
)} - - ) : null} @@ -236,14 +202,11 @@ export const StopSheet: React.FC = ({ - {t( - "map.view_all_estimates", - "Ver todas las estimaciones", - )} + {t("map.view_all_estimates", "Ver todas las estimaciones")} -- cgit v1.3