import { useEffect, useMemo, useRef, useState } from "react"; import StopDataProvider, { type Stop } from "../data/StopDataProvider"; import StopItem from "../components/StopItem"; import Fuse from "fuse.js"; import "./stoplist.css"; import { useTranslation } from "react-i18next"; export default function StopList() { const { t } = useTranslation(); const [data, setData] = useState(null); const [searchResults, setSearchResults] = useState(null); const searchTimeout = useRef(null); const randomPlaceholder = useMemo( () => t("stoplist.search_placeholder"), [t], ); const fuse = useMemo( () => new Fuse(data || [], { threshold: 0.3, keys: ["name.original"] }), [data], ); useEffect(() => { StopDataProvider.getStops().then((stops: Stop[]) => setData(stops)); }, []); const handleStopSearch = (event: React.ChangeEvent) => { const stopName = event.target.value || ""; if (searchTimeout.current) { clearTimeout(searchTimeout.current); } searchTimeout.current = setTimeout(() => { if (stopName.length === 0) { setSearchResults(null); return; } if (!data) { console.error("No data available for search"); return; } const results = fuse.search(stopName); const items = results.map((result) => result.item); setSearchResults(items); }, 300); }; const favouritedStops = useMemo(() => { return data?.filter((stop) => stop.favourite) ?? []; }, [data]); const recentStops = useMemo(() => { // no recent items if data not loaded if (!data) return null; const recentIds = StopDataProvider.getRecent(); if (recentIds.length === 0) return null; // map and filter out missing entries const stopsList = recentIds .map((id) => data.find((stop) => stop.stopId === id)) .filter((s): s is Stop => Boolean(s)); return stopsList.reverse(); }, [data]); if (data === null) return

{t("common.loading")}

; return (

UrbanoVigo Web

{searchResults && searchResults.length > 0 && (

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

    {searchResults.map((stop: Stop) => ( ))}
)}

{t("stoplist.favourites")}

{favouritedStops?.length === 0 && (

{t( "stoplist.no_favourites", "Accede a una parada y márcala como favorita para verla aquí.", )}

)}
    {favouritedStops ?.sort((a, b) => a.stopId - b.stopId) .map((stop: Stop) => )}
{recentStops && recentStops.length > 0 && (

{t("stoplist.recents")}

    {recentStops.map((stop: Stop) => ( ))}
)}

{t("stoplist.all_stops", "Paradas")}

    {data ?.sort((a, b) => a.stopId - b.stopId) .map((stop: Stop) => )}
); }