diff options
Diffstat (limited to 'src/frontend/app/routes')
| -rw-r--r-- | src/frontend/app/routes/favourites.tsx | 5 | ||||
| -rw-r--r-- | src/frontend/app/routes/routes.tsx | 35 | ||||
| -rw-r--r-- | src/frontend/app/routes/settings.tsx | 8 |
3 files changed, 38 insertions, 10 deletions
diff --git a/src/frontend/app/routes/favourites.tsx b/src/frontend/app/routes/favourites.tsx index 3d786b6..1b1d09b 100644 --- a/src/frontend/app/routes/favourites.tsx +++ b/src/frontend/app/routes/favourites.tsx @@ -99,7 +99,10 @@ export default function Favourites() { return routes.reduce( (acc, route) => { const agency = route.agencyName || t("routes.unknown_agency", "Otros"); - if (!isFavoriteAgency(agency)) { + // Match by the agency's own gtfsId (feedId:agencyId) — consistent with + // what routes.tsx stores and with the alert selector format. + const agencyId = route.agencyId ?? route.id.split(":")[0]; + if (!isFavoriteAgency(agencyId)) { return acc; } diff --git a/src/frontend/app/routes/routes.tsx b/src/frontend/app/routes/routes.tsx index 57dfe00..f65adaa 100644 --- a/src/frontend/app/routes/routes.tsx +++ b/src/frontend/app/routes/routes.tsx @@ -63,16 +63,30 @@ export default function RoutesPage() { const sortedAgencyEntries = useMemo(() => { if (!routesByAgency) return []; - return Object.entries(routesByAgency).sort(([a], [b]) => { + return Object.entries(routesByAgency).sort(([a, routesA], [b, routesB]) => { + // Use the agency's own gtfsId (feedId:agencyId) as the stable key — this + // matches the "agency#feedId:agencyId" alert selector format and correctly + // handles feeds that contain multiple agencies. + const agencyIdA = + routesA?.[0]?.agencyId ?? + routesA?.[0]?.id.split(":")[0] ?? + a.toLowerCase(); + const agencyIdB = + routesB?.[0]?.agencyId ?? + routesB?.[0]?.id.split(":")[0] ?? + b.toLowerCase(); + const feedIdA = agencyIdA.split(":")[0]; + const feedIdB = agencyIdB.split(":")[0]; + // First, sort by favorite status - const isFavA = isFavoriteAgency(a); - const isFavB = isFavoriteAgency(b); + const isFavA = isFavoriteAgency(agencyIdA); + const isFavB = isFavoriteAgency(agencyIdB); if (isFavA && !isFavB) return -1; if (!isFavA && isFavB) return 1; // Then by fixed order - const indexA = orderedAgencies.indexOf(a.toLowerCase()); - const indexB = orderedAgencies.indexOf(b.toLowerCase()); + const indexA = orderedAgencies.indexOf(feedIdA); + const indexB = orderedAgencies.indexOf(feedIdB); if (indexA === -1 && indexB === -1) { return a.localeCompare(b); } @@ -156,10 +170,15 @@ export default function RoutesPage() { )} {sortedAgencyEntries.map(([agency, agencyRoutes]) => { - const isFav = isFavoriteAgency(agency); + // Use the agency's own gtfsId (feedId:agencyId) as the stable favourite key. + const agencyId = + agencyRoutes?.[0]?.agencyId ?? + agencyRoutes?.[0]?.id.split(":")[0] ?? + agency.toLowerCase(); + const isFav = isFavoriteAgency(agencyId); const isExpanded = searchQuery ? true - : (expandedAgencies[agency] ?? false); + : (expandedAgencies[agency] ?? isFav); return ( <div @@ -190,7 +209,7 @@ export default function RoutesPage() { </button> <button type="button" - onClick={() => toggleFavoriteAgency(agency)} + onClick={() => toggleFavoriteAgency(agencyId)} className={`rounded-full p-2 transition-colors ${ isFav ? "text-yellow-500" diff --git a/src/frontend/app/routes/settings.tsx b/src/frontend/app/routes/settings.tsx index 0497f34..a716030 100644 --- a/src/frontend/app/routes/settings.tsx +++ b/src/frontend/app/routes/settings.tsx @@ -2,6 +2,7 @@ import { Computer, Moon, Sun, Trash2 } from "lucide-react"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router"; +import { PushNotificationSettings } from "~/components/PushNotificationSettings"; import { usePageTitle } from "~/contexts/PageTitleContext"; import { useApp, type Theme } from "../AppContext"; import "../tailwind-full.css"; @@ -178,7 +179,7 @@ export default function Settings() { className="block text-lg font-medium text-text mb-3" > {t("about.language", "Idioma")} - </label> + </label>{" "} <select id="language" className=" @@ -197,6 +198,11 @@ export default function Settings() { </select> </section> + {/* Push Notifications */} + <div className="mt-8 pt-8 border-t border-border"> + <PushNotificationSettings /> + </div> + {/* Privacy / Clear data */} <section className="mt-8 pt-8 border-t border-border"> <h2 className="text-xl font-semibold mb-4 text-text"> |
