diff options
| author | Ariel Costas Guerrero <ariel@costas.dev> | 2025-12-22 18:16:57 +0100 |
|---|---|---|
| committer | Ariel Costas Guerrero <ariel@costas.dev> | 2025-12-22 18:16:57 +0100 |
| commit | 4b7eaa318f22d7cc768491c421cb7aeac477f95d (patch) | |
| tree | 0b39abce444679396475e4f48885479e2ae0650f /src/frontend/app/components/map/StopSummarySheet.tsx | |
| parent | 91f7d7dd5a4ca8453cfdbc9a3beeb216b6638ef7 (diff) | |
Implement retrieving next arrivals for a stop (scheduled only)
Diffstat (limited to 'src/frontend/app/components/map/StopSummarySheet.tsx')
| -rw-r--r-- | src/frontend/app/components/map/StopSummarySheet.tsx | 109 |
1 files changed, 18 insertions, 91 deletions
diff --git a/src/frontend/app/components/map/StopSummarySheet.tsx b/src/frontend/app/components/map/StopSummarySheet.tsx index b24e71c..16a9cbe 100644 --- a/src/frontend/app/components/map/StopSummarySheet.tsx +++ b/src/frontend/app/components/map/StopSummarySheet.tsx @@ -1,11 +1,10 @@ import { RefreshCw } from "lucide-react"; -import React, { useEffect, useState } from "react"; +import React from "react"; import { useTranslation } from "react-i18next"; import { Sheet } from "react-modal-sheet"; import { Link } from "react-router"; -import { ConsolidatedCirculationList } from "~/components/Stops/ConsolidatedCirculationList"; -import { APP_CONSTANTS } from "~/config/constants"; -import { type ConsolidatedCirculation } from "../../routes/stops-$id"; +import { ArrivalList } from "~/components/Stops/ArrivalList"; +import { useStopArrivals } from "../../hooks/useArrivals"; import { ErrorDisplay } from "../ErrorDisplay"; import LineIcon from "../LineIcon"; import "./StopSummarySheet.css"; @@ -27,95 +26,24 @@ export interface StopSheetProps { }; } -interface ErrorInfo { - type: "network" | "server" | "unknown"; - status?: number; - message?: string; -} - -const loadConsolidatedData = async ( - stopId: string -): Promise<ConsolidatedCirculation[]> => { - const resp = await fetch( - `${APP_CONSTANTS.consolidatedCirculationsEndpoint}?stopId=${stopId}`, - { - headers: { - Accept: "application/json", - }, - } - ); - - if (!resp.ok) { - throw new Error(`HTTP ${resp.status}: ${resp.statusText}`); - } - - return await resp.json(); -}; - export const StopSheet: React.FC<StopSheetProps> = ({ isOpen, onClose, stop, }) => { const { t } = useTranslation(); - const [data, setData] = useState<ConsolidatedCirculation[] | null>(null); - const [loading, setLoading] = useState(false); - const [error, setError] = useState<ErrorInfo | null>(null); - const [lastUpdated, setLastUpdated] = useState<Date | null>(null); - - const parseError = (error: any): ErrorInfo => { - if (!navigator.onLine) { - return { type: "network", message: "No internet connection" }; - } - - if ( - error.message?.includes("Failed to fetch") || - error.message?.includes("NetworkError") - ) { - return { type: "network" }; - } - - if (error.message?.includes("HTTP")) { - const statusMatch = error.message.match(/HTTP (\d+):/); - const status = statusMatch ? parseInt(statusMatch[1]) : undefined; - return { type: "server", status }; - } - - return { type: "unknown", message: error.message }; - }; - - const loadData = async () => { - try { - setLoading(true); - setError(null); - setData(null); - - const stopData = await loadConsolidatedData(stop.stopId); - setData(stopData); - setLastUpdated(new Date()); - } catch (err) { - console.error("Failed to load stop data:", err); - setError(parseError(err)); - } finally { - setLoading(false); - } - }; + const { + data, + isLoading: loading, + error, + refetch: loadData, + dataUpdatedAt, + } = useStopArrivals(stop.stopId, true, isOpen); - useEffect(() => { - if (isOpen && stop.stopId) { - loadData(); - } - }, [isOpen, stop.stopId]); + const lastUpdated = dataUpdatedAt ? new Date(dataUpdatedAt) : null; // Show only the next 4 arrivals - 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); + const limitedEstimates = data?.arrivals.slice(0, 4) ?? []; return ( <Sheet isOpen={isOpen} onClose={onClose} detent="content"> @@ -147,8 +75,11 @@ export const StopSheet: React.FC<StopSheetProps> = ({ <StopSummarySheetSkeleton /> ) : error ? ( <ErrorDisplay - error={error} - onRetry={loadData} + error={{ + type: error.message.includes("HTTP") ? "server" : "network", + message: error.message, + }} + onRetry={() => loadData()} title={t( "errors.estimates_title", "Error al cargar estimaciones" @@ -167,11 +98,7 @@ export const StopSheet: React.FC<StopSheetProps> = ({ {t("estimates.none", "No hay estimaciones disponibles")} </div> ) : ( - <ConsolidatedCirculationList - data={data.slice(0, 4)} - driver={stop.stopFeed} - reduced - /> + <ArrivalList arrivals={limitedEstimates} reduced /> )} </div> </> |
