From 4b7eaa318f22d7cc768491c421cb7aeac477f95d Mon Sep 17 00:00:00 2001
From: Ariel Costas Guerrero <ariel@costas.dev>
Date: Mon, 22 Dec 2025 18:16:57 +0100
Subject: Implement retrieving next arrivals for a stop (scheduled only)

---
 .../app/components/map/StopSummarySheet.tsx        | 109 ++++-----------------
 1 file changed, 18 insertions(+), 91 deletions(-)

(limited to 'src/frontend/app/components/map/StopSummarySheet.tsx')

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>
               </>
-- 
cgit v1.3

