From c9e2341a5b1e8dc03ba6e43c4e61ed2e5f4038c9 Mon Sep 17 00:00:00 2001
From: Copilot <198982749+Copilot@users.noreply.github.com>
Date: Fri, 13 Mar 2026 14:20:59 +0100
Subject: Fix favourites button in stop header not toggling (#144)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: arielcostas <94913521+arielcostas@users.noreply.github.com>
---
 src/frontend/app/routes/stops-$id.tsx | 61 +++++++++++++++++++++--------------
 1 file changed, 36 insertions(+), 25 deletions(-)

(limited to 'src/frontend/app/routes/stops-$id.tsx')

diff --git a/src/frontend/app/routes/stops-$id.tsx b/src/frontend/app/routes/stops-$id.tsx
index 4c2075c..a61e925 100644
--- a/src/frontend/app/routes/stops-$id.tsx
+++ b/src/frontend/app/routes/stops-$id.tsx
@@ -1,5 +1,5 @@
 import { CircleHelp, Eye, EyeClosed, Star } from "lucide-react";
-import { useCallback, useEffect, useState } from "react";
+import { useCallback, useEffect, useMemo, useState } from "react";
 import { useTranslation } from "react-i18next";
 import { useParams } from "react-router";
 import { fetchArrivals } from "~/api/arrivals";
@@ -22,6 +22,37 @@ import StopDataProvider from "../data/StopDataProvider";
 import "../tailwind-full.css";
 import "./stops-$id.css";
 
+function StopFavouriteButton({ stopId }: { stopId: string }) {
+  const { t } = useTranslation();
+  const [favourited, setFavourited] = useState(() =>
+    StopDataProvider.isFavourite(stopId)
+  );
+
+  const toggle = () => {
+    if (favourited) {
+      StopDataProvider.removeFavourite(stopId);
+      setFavourited(false);
+    } else {
+      StopDataProvider.addFavourite(stopId);
+      setFavourited(true);
+    }
+  };
+
+  return (
+    <button
+      onClick={toggle}
+      className={`app-header__menu-btn p-2 rounded-full transition-colors ${
+        favourited
+          ? "text-(--star-color)"
+          : "text-slate-500 hover:text-slate-700 dark:text-slate-400 dark:hover:text-slate-200"
+      }`}
+      aria-label={t("stop.toggle_favourite", "Alternar favorito")}
+    >
+      <Star className={favourited ? "fill-current" : ""} size={24} />
+    </button>
+  );
+}
+
 export const getArrivalId = (a: Arrival): string => {
   return a.tripId;
 };
@@ -50,7 +81,6 @@ export default function Estimates() {
   const [dataLoading, setDataLoading] = useState(true);
   const [dataError, setDataError] = useState<ErrorInfo | null>(null);
 
-  const [favourited, setFavourited] = useState(false);
   const [isManualRefreshing, setIsManualRefreshing] = useState(false);
   const [isMapModalOpen, setIsMapModalOpen] = useState(false);
   const [isHelpModalOpen, setIsHelpModalOpen] = useState(false);
@@ -67,29 +97,11 @@ export default function Estimates() {
 
   usePageTitle(getStopDisplayName());
 
-  const toggleFavourite = useCallback(() => {
-    if (favourited) {
-      StopDataProvider.removeFavourite(stopId);
-      setFavourited(false);
-    } else {
-      StopDataProvider.addFavourite(stopId);
-      setFavourited(true);
-    }
-  }, [favourited, stopId]);
-
-  usePageRightNode(
-    <button
-      onClick={toggleFavourite}
-      className={`app-header__menu-btn p-2 rounded-full transition-colors ${
-        favourited
-          ? "text-(--star-color)"
-          : "text-slate-500 hover:text-slate-700 dark:text-slate-400 dark:hover:text-slate-200"
-      }`}
-      aria-label={t("stop.toggle_favourite", "Alternar favorito")}
-    >
-      <Star className={favourited ? "fill-current" : ""} size={24} />
-    </button>
+  const rightNode = useMemo(
+    () => <StopFavouriteButton stopId={stopId} />,
+    [stopId]
   );
+  usePageRightNode(rightNode);
 
   const parseError = (error: any): ErrorInfo => {
     if (!navigator.onLine) {
@@ -153,7 +165,6 @@ export default function Estimates() {
     loadData();
 
     StopDataProvider.pushRecent(stopId);
-    setFavourited(StopDataProvider.isFavourite(stopId));
     setDataLoading(false);
   }, [stopId, loadData]);
 
-- 
cgit v1.3

