From 9618229477439d1604869aa68fc21d4eae7d8bb1 Mon Sep 17 00:00:00 2001 From: Ariel Costas Guerrero Date: Sun, 28 Dec 2025 22:40:52 +0100 Subject: feat: Enhance route details to include agency information and update map attribution --- src/Costasdev.Busurbano.Backend/Services/OtpService.cs | 6 +++--- .../Types/Transit/RouteDtos.cs | 1 + .../Queries/RouteDetailsContent.cs | 9 +++++++++ src/frontend/app/api/schema.ts | 1 + src/frontend/app/root.css | 4 ++++ src/frontend/app/routes/routes-$id.tsx | 18 ++++++++++++++++-- 6 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/Costasdev.Busurbano.Backend/Services/OtpService.cs b/src/Costasdev.Busurbano.Backend/Services/OtpService.cs index 37f7e91..fb7413c 100644 --- a/src/Costasdev.Busurbano.Backend/Services/OtpService.cs +++ b/src/Costasdev.Busurbano.Backend/Services/OtpService.cs @@ -56,13 +56,13 @@ public class OtpService LongName = route.LongName, Color = route.Color, TextColor = route.TextColor, - Patterns = route.Patterns.Select(MapPattern).ToList() + AgencyName = route.Agency?.Name, + Patterns = route.Patterns.Select(p => MapPattern(p, feedId)).ToList() }; } - private PatternDto MapPattern(RouteDetailsResponse.PatternItem pattern) + private PatternDto MapPattern(RouteDetailsResponse.PatternItem pattern, string feedId) { - var feedId = pattern.Id.Split(':')[0]; return new PatternDto { Id = pattern.Id, diff --git a/src/Costasdev.Busurbano.Backend/Types/Transit/RouteDtos.cs b/src/Costasdev.Busurbano.Backend/Types/Transit/RouteDtos.cs index f647b5b..816e43d 100644 --- a/src/Costasdev.Busurbano.Backend/Types/Transit/RouteDtos.cs +++ b/src/Costasdev.Busurbano.Backend/Types/Transit/RouteDtos.cs @@ -18,6 +18,7 @@ public class RouteDetailsDto public string? LongName { get; set; } public string? Color { get; set; } public string? TextColor { get; set; } + public string? AgencyName { get; set; } public List Patterns { get; set; } = []; } diff --git a/src/Costasdev.Busurbano.Sources.OpenTripPlannerGql/Queries/RouteDetailsContent.cs b/src/Costasdev.Busurbano.Sources.OpenTripPlannerGql/Queries/RouteDetailsContent.cs index 8683bfd..1ba85fa 100644 --- a/src/Costasdev.Busurbano.Sources.OpenTripPlannerGql/Queries/RouteDetailsContent.cs +++ b/src/Costasdev.Busurbano.Sources.OpenTripPlannerGql/Queries/RouteDetailsContent.cs @@ -17,6 +17,9 @@ public class RouteDetailsContent : IGraphRequest longName color textColor + agency { + name + } patterns { id @@ -61,9 +64,15 @@ public class RouteDetailsResponse : AbstractGraphResponse [JsonPropertyName("longName")] public string? LongName { get; set; } [JsonPropertyName("color")] public string? Color { get; set; } [JsonPropertyName("textColor")] public string? TextColor { get; set; } + [JsonPropertyName("agency")] public AgencyItem? Agency { get; set; } [JsonPropertyName("patterns")] public List Patterns { get; set; } = []; } + public class AgencyItem + { + [JsonPropertyName("name")] public string? Name { get; set; } + } + public class PatternItem { [JsonPropertyName("id")] public required string Id { get; set; } diff --git a/src/frontend/app/api/schema.ts b/src/frontend/app/api/schema.ts index f7f0a39..95c7b6f 100644 --- a/src/frontend/app/api/schema.ts +++ b/src/frontend/app/api/schema.ts @@ -108,6 +108,7 @@ export const RouteDetailsSchema = z.object({ longName: z.string().nullable(), color: z.string().nullable(), textColor: z.string().nullable(), + agencyName: z.string().nullable().optional(), patterns: z.array(PatternSchema), }); diff --git a/src/frontend/app/root.css b/src/frontend/app/root.css index 3f41591..a517be6 100644 --- a/src/frontend/app/root.css +++ b/src/frontend/app/root.css @@ -224,3 +224,7 @@ textarea { .maplibregl-ctrl-attrib-inner { line-height: 1rem !important; } + +.maplibregl-ctrl.maplibregl-ctrl-attrib { + min-height: unset !important; +} diff --git a/src/frontend/app/routes/routes-$id.tsx b/src/frontend/app/routes/routes-$id.tsx index 8dd7e1c..3b61ba6 100644 --- a/src/frontend/app/routes/routes-$id.tsx +++ b/src/frontend/app/routes/routes-$id.tsx @@ -1,7 +1,12 @@ import { useQuery } from "@tanstack/react-query"; import { useRef, useState } from "react"; import { useTranslation } from "react-i18next"; -import { Layer, Source, type MapRef } from "react-map-gl/maplibre"; +import { + AttributionControl, + Layer, + Source, + type MapRef, +} from "react-map-gl/maplibre"; import { useParams } from "react-router"; import { fetchRouteDetails } from "~/api/transit"; import { AppMap } from "~/components/shared/AppMap"; @@ -137,7 +142,9 @@ export default function RouteDetailsPage() { > {patterns.map((pattern) => ( @@ -169,7 +176,14 @@ export default function RouteDetailsPage() { handleStopClick(id, lat, lon, true); } }} + showTraffic={false} + attributionControl={false} > + {selectedPattern?.geometry && (