import { Clock, History, MapPin, Star } from "lucide-react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router"; import { usePageTitle } from "~/contexts/PageTitleContext"; import { usePlanner } from "~/hooks/usePlanner"; import StopItem from "../components/StopItem"; import StopDataProvider, { type Stop } from "../data/StopDataProvider"; import "../tailwind-full.css"; export default function StopList() { const { t } = useTranslation(); usePageTitle(t("navbar.stops", "Paradas")); const navigate = useNavigate(); const { history, loadRoute } = usePlanner({ autoLoad: false }); const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [searchResults, setSearchResults] = useState(null); const [favouriteStops, setFavouriteStops] = useState([]); const [recentStops, setRecentStops] = useState([]); const searchTimeout = useRef(null); const randomPlaceholder = useMemo( () => t("stoplist.search_placeholder"), [t] ); // Load stops from network const loadStops = useCallback(async () => { try { setLoading(true); const favouriteIds = StopDataProvider.getFavouriteIds(); const recentIds = StopDataProvider.getRecent(); const allIds = Array.from(new Set([...favouriteIds, ...recentIds])); const stopsMap = await StopDataProvider.fetchStopsByIds(allIds); const favStops = favouriteIds .map((id) => stopsMap[id]) .filter(Boolean) .map((stop) => ({ ...stop, favourite: true })); setFavouriteStops(favStops); const recStops = recentIds .map((id) => stopsMap[id]) .filter(Boolean) .map((stop) => ({ ...stop, favourite: favouriteIds.includes(stop.stopId), })); setRecentStops(recStops); setData(Object.values(stopsMap)); } catch (error) { console.error("Failed to load stops:", error); } finally { setLoading(false); } }, []); useEffect(() => { loadStops(); }, [loadStops]); const handleStopSearch = (event: React.ChangeEvent) => { const searchQuery = event.target.value || ""; if (searchTimeout.current) { clearTimeout(searchTimeout.current); } searchTimeout.current = setTimeout(async () => { if (searchQuery.length === 0) { setSearchResults(null); return; } try { const response = await fetch( `/api/stops/search?q=${encodeURIComponent(searchQuery)}` ); if (response.ok) { const results = await response.json(); setSearchResults(results); } else { setSearchResults([]); } } catch (error) { console.error("Search failed:", error); setSearchResults([]); } }, 300); }; return (
{/* Planner Section */}
{history.length > 0 && (

{t("planner.recent_routes", "Rutas recientes")}

{history.map((route, idx) => ( ))}
)}
{/* Search Section */}

{t("stoplist.search_label", "Buscar paradas")}

{/* Search Results */} {searchResults && searchResults.length > 0 ? (

{t("stoplist.search_results", "Resultados de la búsqueda")}

    {searchResults.map((stop: Stop, index) => ( ))}
) : searchResults !== null ? (

{t("stoplist.no_results", "No se encontraron resultados")}

) : ( <> {/* Favourites List */} {!loading && favouriteStops.length > 0 && (

{t("stoplist.favourites")}

    {favouriteStops .sort((a, b) => a.stopId.localeCompare(b.stopId)) .map((stop, index) => ( ))}
)} {!loading && favouriteStops.length === 0 && (

{t("stoplist.favourites")}

{t("stoplist.no_favourites")}

)} {/* Recent Stops List - only show if no favourites */} {!loading && favouriteStops.length === 0 && recentStops.length > 0 && (

{t("stoplist.recents")}

    {recentStops.slice(0, 5).map((stop, index) => ( ))}
)} )}
); }