import { useQuery } from "@tanstack/react-query"; import { ChevronDown, ChevronRight, Star } from "lucide-react"; import { useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router"; import { fetchRoutes } from "~/api/transit"; import RouteIcon from "~/components/RouteIcon"; import { usePageTitle } from "~/contexts/PageTitleContext"; import { useFavorites } from "~/hooks/useFavorites"; import "../tailwind-full.css"; export default function RoutesPage() { const { t } = useTranslation(); usePageTitle(t("navbar.routes", "Rutas")); const [searchQuery, setSearchQuery] = useState(""); const [isFavoritesExpanded, setIsFavoritesExpanded] = useState(true); const { isFavorite: isFavoriteRoute } = useFavorites("favouriteRoutes"); const { toggleFavorite: toggleFavoriteAgency, isFavorite: isFavoriteAgency } = useFavorites("favouriteAgencies"); const [expandedAgencies, setExpandedAgencies] = useState< Record >({}); const toggleAgencyExpanded = (agency: string) => { setExpandedAgencies((prev) => ({ ...prev, [agency]: !prev[agency] })); }; const orderedAgencies = [ "vitrasa", "tranvias", "tussa", "ourense", "lugo", "feve", "shuttle", ]; const { data: routes, isLoading } = useQuery({ queryKey: ["routes"], queryFn: () => fetchRoutes(orderedAgencies), }); const filteredRoutes = useMemo(() => { return routes?.filter( (route) => route.shortName?.toLowerCase().includes(searchQuery.toLowerCase()) || route.longName?.toLowerCase().includes(searchQuery.toLowerCase()) ); }, [routes, searchQuery]); const routesByAgency = useMemo(() => { return filteredRoutes?.reduce( (acc, route) => { const agency = route.agencyName || t("routes.unknown_agency", "Otros"); if (!acc[agency]) acc[agency] = []; acc[agency].push(route); return acc; }, {} as Record ); }, [filteredRoutes, t]); const sortedAgencyEntries = useMemo(() => { if (!routesByAgency) return []; return Object.entries(routesByAgency).sort(([a], [b]) => { // First, sort by favorite status const isFavA = isFavoriteAgency(a); const isFavB = isFavoriteAgency(b); 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()); if (indexA === -1 && indexB === -1) { return a.localeCompare(b); } if (indexA === -1) return 1; if (indexB === -1) return -1; return indexA - indexB; }); }, [routesByAgency, orderedAgencies, isFavoriteAgency]); const favoriteRoutes = useMemo(() => { return filteredRoutes?.filter((route) => isFavoriteRoute(route.id)) || []; }, [filteredRoutes, isFavoriteRoute]); return (
setSearchQuery(e.target.value)} />
{isLoading && (
)}
{favoriteRoutes.length > 0 && !searchQuery && (
{isFavoritesExpanded && (
{favoriteRoutes.map((route) => (

{route.longName}

))}
)}
)} {sortedAgencyEntries.map(([agency, agencyRoutes]) => { const isFav = isFavoriteAgency(agency); const isExpanded = searchQuery ? true : (expandedAgencies[agency] ?? false); return (
{isExpanded && (
{agencyRoutes.map((route) => (

{route.longName}

))}
)}
); })}
); }