import { useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router"; import LineIcon from "~/components/LineIcon"; import { usePageTitle } from "~/contexts/PageTitleContext"; import SpecialPlacesProvider, { type SpecialPlace, } from "~/data/SpecialPlacesProvider"; import StopDataProvider, { type Stop } from "~/data/StopDataProvider"; export default function Favourites() { const { t } = useTranslation(); usePageTitle(t("favourites.title", "Favourites")); const [home, setHome] = useState(null); const [work, setWork] = useState(null); const [favouriteStops, setFavouriteStops] = useState([]); const [loading, setLoading] = useState(true); const loadData = useCallback(async () => { try { setLoading(true); // Load special places setHome(SpecialPlacesProvider.getHome()); setWork(SpecialPlacesProvider.getWork()); // Load favourite stops const favouriteIds = StopDataProvider.getFavouriteIds(); const stopsMap = await StopDataProvider.fetchStopsByIds(favouriteIds); const favStops = favouriteIds .map((id) => stopsMap[id]) .filter(Boolean) .map((stop) => ({ ...stop, favourite: true })); setFavouriteStops(favStops); } catch (error) { console.error("Error loading favourites:", error); } finally { setLoading(false); } }, []); useEffect(() => { loadData(); }, [loadData]); const handleRemoveFavourite = (stopId: string) => { StopDataProvider.removeFavourite(stopId); setFavouriteStops((prev) => prev.filter((s) => s.stopId !== stopId)); }; const handleRemoveHome = () => { SpecialPlacesProvider.removeHome(); setHome(null); }; const handleRemoveWork = () => { SpecialPlacesProvider.removeWork(); setWork(null); }; const isEmpty = !home && !work && favouriteStops.length === 0; if (loading) { return (
{t("common.loading", "Loading...")}
); } if (isEmpty) { return (

{t("favourites.empty", "You don't have any favourite stops yet.")}

{t( "favourites.empty_description", "Go to a stop and mark it as favourite to see it here." )}

); } return (
{/* Special Places Section */} {(home || work) && (

{t("favourites.special_places", "Special Places")}

{/* Home */} {/* Work */}
)} {/* Favourite Stops Section */} {favouriteStops.length > 0 && (

{t("favourites.favourite_stops", "Favourite Stops")}

    {favouriteStops.map((stop) => ( ))}
)}
); } interface SpecialPlaceCardProps { icon: string; label: string; place: SpecialPlace | null; onRemove: () => void; editLabel: string; removeLabel: string; notSetLabel: string; setLabel: string; } function SpecialPlaceCard({ icon, label, place, onRemove, editLabel, removeLabel, notSetLabel, setLabel, }: SpecialPlaceCardProps) { return (

{label}

{place ? (

{place.name}

{place.type === "stop" && place.stopId && (

({place.stopId})

)} {place.type === "address" && place.address && (

{place.address}

)}
) : (

{notSetLabel}

)}
{place ? ( <> {place.type === "stop" && place.stopId && ( {editLabel} )} ) : ( )}
); } interface FavouriteStopItemProps { stop: Stop; onRemove: (stopId: string) => void; removeLabel: string; viewLabel: string; } function FavouriteStopItem({ stop, onRemove, removeLabel, viewLabel, }: FavouriteStopItemProps) { const { t } = useTranslation(); const confirmAndRemove = () => { const ok = window.confirm( t("favourites.confirm_remove", "Remove this favourite?") ); if (!ok) return; onRemove(stop.stopId); }; return (
  • ({stop.stopCode || stop.stopId})
    {StopDataProvider.getDisplayName(stop)}
    {stop.lines?.slice(0, 6).map((lineObj) => ( ))} {stop.lines && stop.lines.length > 6 && ( +{stop.lines.length - 6} )}
  • ); }