diff options
26 files changed, 148 insertions, 92 deletions
diff --git a/src/Enmarcha.Backend/Controllers/AlertsController.cs b/src/Enmarcha.Backend/Controllers/AlertsController.cs index 4860399..7d19894 100644 --- a/src/Enmarcha.Backend/Controllers/AlertsController.cs +++ b/src/Enmarcha.Backend/Controllers/AlertsController.cs @@ -1,5 +1,4 @@ using Enmarcha.Backend.Data; -using Enmarcha.Backend.Data.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; diff --git a/src/Enmarcha.Backend/Controllers/Backoffice/LoginController.cs b/src/Enmarcha.Backend/Controllers/Backoffice/LoginController.cs index 1e9f12f..2a5a515 100644 --- a/src/Enmarcha.Backend/Controllers/Backoffice/LoginController.cs +++ b/src/Enmarcha.Backend/Controllers/Backoffice/LoginController.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; diff --git a/src/Enmarcha.Backend/Data/Migrations/20260319113819_Initial.cs b/src/Enmarcha.Backend/Data/Migrations/20260319113819_Initial.cs index 2548aa9..b3b8dba 100644 --- a/src/Enmarcha.Backend/Data/Migrations/20260319113819_Initial.cs +++ b/src/Enmarcha.Backend/Data/Migrations/20260319113819_Initial.cs @@ -1,4 +1,3 @@ -using System; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; diff --git a/src/Enmarcha.Backend/Data/Migrations/20260401135403_AddPushNotifications.cs b/src/Enmarcha.Backend/Data/Migrations/20260401135403_AddPushNotifications.cs index 964a86f..c21c754 100644 --- a/src/Enmarcha.Backend/Data/Migrations/20260401135403_AddPushNotifications.cs +++ b/src/Enmarcha.Backend/Data/Migrations/20260401135403_AddPushNotifications.cs @@ -1,4 +1,3 @@ -using System; using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/src/Enmarcha.Backend/Data/Models/ServiceAlert.cs b/src/Enmarcha.Backend/Data/Models/ServiceAlert.cs index 8551117..2a6a48a 100644 --- a/src/Enmarcha.Backend/Data/Models/ServiceAlert.cs +++ b/src/Enmarcha.Backend/Data/Models/ServiceAlert.cs @@ -1,4 +1,4 @@ -using System.ComponentModel; +using System.ComponentModel; using System.ComponentModel.DataAnnotations.Schema; namespace Enmarcha.Backend.Data.Models; diff --git a/src/Enmarcha.Backend/Enmarcha.Backend.csproj.lscache b/src/Enmarcha.Backend/Enmarcha.Backend.csproj.lscache index 0b75fe1..fa4e2b5 100644 --- a/src/Enmarcha.Backend/Enmarcha.Backend.csproj.lscache +++ b/src/Enmarcha.Backend/Enmarcha.Backend.csproj.lscache @@ -109,15 +109,20 @@ Services/ OtpService.cs Processors/ AbstractProcessor.cs - CorunaRealTimeProcessor.cs - CtagShuttleRealTimeProcessor.cs - FeedConfigProcessor.cs FilterAndSortProcessor.cs NextStopsProcessor.cs - RenfeRealTimeProcessor.cs + Normalisation/ + ColourProcessor.cs + TranviasNormalizationProcessor.cs + VitrasaNormalizationProcessor.cs + XuntaNormalizationProcessor.cs + RealTime/ + CorunaRealTimeProcessor.cs + CtagShuttleRealTimeProcessor.cs + RenfeRealTimeProcessor.cs + TussaRealTimeProcessor.cs + VitrasaRealTimeProcessor.cs ShapeProcessor.cs - TussaRealTimeProcessor.cs - VitrasaRealTimeProcessor.cs VitrasaUsageProcessor.cs Providers/XuntaFareProvider.cs PushNotificationService.cs diff --git a/src/Enmarcha.Backend/Helpers/SortingHelper.cs b/src/Enmarcha.Backend/Helpers/SortingHelper.cs index 7fd4e37..bd655a9 100644 --- a/src/Enmarcha.Backend/Helpers/SortingHelper.cs +++ b/src/Enmarcha.Backend/Helpers/SortingHelper.cs @@ -86,6 +86,7 @@ public class SortingHelper /// 1 = Regular numbered routes (4A, 6, 10, A, etc.) /// 2 = Hospital (H, H1, H2, H3) /// 3 = Others (N*, PSA*, U*, LZD, PTL) + /// 4 = Football (MAR, GOL and RIO) /// </summary> private static int GetVitrasaRouteGroup(string shortName) { @@ -125,6 +126,11 @@ public class SortingHelper return 3; } + if (shortName == "MAR" || shortName == "GOL" || shortName == "RIO") + { + return 4; + } + // Everything else is regular (numbered routes like 4A, 6, 10, single letters like A) return 1; } diff --git a/src/Enmarcha.Backend/Helpers/TransitKindClassifier.cs b/src/Enmarcha.Backend/Helpers/TransitKindClassifier.cs index b1fad84..fbda36c 100644 --- a/src/Enmarcha.Backend/Helpers/TransitKindClassifier.cs +++ b/src/Enmarcha.Backend/Helpers/TransitKindClassifier.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Enmarcha.Backend.Helpers; diff --git a/src/Enmarcha.Backend/Program.cs b/src/Enmarcha.Backend/Program.cs index fc62add..785afe5 100644 --- a/src/Enmarcha.Backend/Program.cs +++ b/src/Enmarcha.Backend/Program.cs @@ -8,12 +8,13 @@ using Enmarcha.Backend.Services.Geocoding; using Enmarcha.Backend.Services.Processors; using Enmarcha.Backend.Services.Providers; using Microsoft.AspNetCore.HttpOverrides; -using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.WebUtilities; using Microsoft.EntityFrameworkCore; using OpenTelemetry.Logs; using OpenTelemetry.Resources; using OpenTelemetry.Trace; +using Enmarcha.Backend.Services.Processors.Normalisation; +using Enmarcha.Backend.Services.Processors.RealTime; var builder = WebApplication.CreateBuilder(args); @@ -146,14 +147,16 @@ builder.Services.AddDbContext<AppDbContext>(options => .UseCamelCaseNamingConvention(); }); -builder.Services.AddIdentityApiEndpoints<IdentityUser>() - .AddEntityFrameworkStores<AppDbContext>(); - var auth0Domain = builder.Configuration["Auth0:Domain"] ?? ""; var auth0ClientId = builder.Configuration["Auth0:ClientId"] ?? ""; -builder.Services.AddAuthentication() - .AddCookie("Backoffice", options => { +builder.Services.AddAuthentication(options => + { + options.DefaultScheme = "Backoffice"; + options.DefaultChallengeScheme = "Auth0"; + }) + .AddCookie("Backoffice", options => + { options.LoginPath = "/backoffice/auth/login"; options.Cookie.SameSite = SameSiteMode.None; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; @@ -206,6 +209,14 @@ builder.Services.AddSingleton<FareService>(); builder.Services.AddScoped<IPushNotificationService, PushNotificationService>(); builder.Services.AddHostedService<AlertPhaseNotificationHostedService>(); +builder.Services.AddScoped<IArrivalsProcessor, FilterAndSortProcessor>(); +builder.Services.AddScoped<IArrivalsProcessor, NextStopsProcessor>(); +builder.Services.AddScoped<IArrivalsProcessor, ShapeProcessor>(); +builder.Services.AddScoped<IArrivalsProcessor, VitrasaNormalizationProcessor>(); +builder.Services.AddScoped<IArrivalsProcessor, XuntaNormalizationProcessor>(); +builder.Services.AddScoped<IArrivalsProcessor, TranviasNormalizationProcessor>(); +builder.Services.AddScoped<IArrivalsProcessor, ColourProcessor>(); + builder.Services.AddScoped<IArrivalsProcessor, VitrasaRealTimeProcessor>(); builder.Services.AddScoped<IArrivalsProcessor, CorunaRealTimeProcessor>(); builder.Services.AddScoped<IArrivalsProcessor, TussaRealTimeProcessor>(); @@ -213,10 +224,6 @@ builder.Services.AddScoped<IArrivalsProcessor, CtagShuttleRealTimeProcessor>(); builder.Services.AddScoped<IArrivalsProcessor, VitrasaUsageProcessor>(); builder.Services.AddScoped<IArrivalsProcessor, RenfeRealTimeProcessor>(); -builder.Services.AddScoped<IArrivalsProcessor, FilterAndSortProcessor>(); -builder.Services.AddScoped<IArrivalsProcessor, NextStopsProcessor>(); -builder.Services.AddScoped<IArrivalsProcessor, ShapeProcessor>(); -builder.Services.AddScoped<IArrivalsProcessor, FeedConfigProcessor>(); builder.Services.AddScoped<ArrivalsPipeline>(); // builder.Services.AddKeyedScoped<IGeocodingService, NominatimGeocodingService>("Nominatim"); @@ -235,8 +242,9 @@ var forwardedHeaderOptions = new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost }; + // Crucial: Clear the networks/proxies list if you are in a container or specific Linux setup -forwardedHeaderOptions.KnownNetworks.Clear(); +forwardedHeaderOptions.KnownIPNetworks.Clear(); forwardedHeaderOptions.KnownProxies.Clear(); app.UseForwardedHeaders(forwardedHeaderOptions); @@ -245,8 +253,6 @@ app.UseStaticFiles(); app.UseAuthentication(); app.UseAuthorization(); -app.MapGroup("/api/identity").MapIdentityApi<IdentityUser>(); - app.Use(async (context, next) => { if (context.Request.Headers.TryGetValue("X-Session-Id", out var sessionId)) diff --git a/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs b/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs index 1db215b..4c0b8ac 100644 --- a/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs @@ -1,4 +1,3 @@ -using System.Text; using Enmarcha.Sources.OpenTripPlannerGql.Queries; namespace Enmarcha.Backend.Services.Processors; diff --git a/src/Enmarcha.Backend/Services/Processors/Normalisation/ColourProcessor.cs b/src/Enmarcha.Backend/Services/Processors/Normalisation/ColourProcessor.cs new file mode 100644 index 0000000..ee4379b --- /dev/null +++ b/src/Enmarcha.Backend/Services/Processors/Normalisation/ColourProcessor.cs @@ -0,0 +1,34 @@ +using Enmarcha.Backend.Helpers; + +namespace Enmarcha.Backend.Services.Processors.Normalisation; + +public class ColourProcessor : IArrivalsProcessor +{ + private readonly FeedService _feedService; + + public ColourProcessor(FeedService feedService) + { + _feedService = feedService; + } + + public Task ProcessAsync(ArrivalsContext context) + { + var feedId = context.StopId.Split(':')[0]; + var (fallbackColor, fallbackTextColor) = _feedService.GetFallbackColourForFeed(feedId); + + foreach (var arrival in context.Arrivals) + { + if (string.IsNullOrEmpty(arrival.Route.Colour) || arrival.Route.Colour == "FFFFFF") + { + arrival.Route.Colour = fallbackColor; + arrival.Route.TextColour = fallbackTextColor; + } + else if (string.IsNullOrEmpty(arrival.Route.TextColour) || arrival.Route.TextColour == "000000") + { + arrival.Route.TextColour = ContrastHelper.GetBestTextColour(arrival.Route.Colour); + } + } + + return Task.CompletedTask; + } +} diff --git a/src/Enmarcha.Backend/Services/Processors/Normalisation/TranviasNormalizationProcessor.cs b/src/Enmarcha.Backend/Services/Processors/Normalisation/TranviasNormalizationProcessor.cs new file mode 100644 index 0000000..3d17a37 --- /dev/null +++ b/src/Enmarcha.Backend/Services/Processors/Normalisation/TranviasNormalizationProcessor.cs @@ -0,0 +1,17 @@ +namespace Enmarcha.Backend.Services.Processors.Normalisation; + +public class TranviasNormalizationProcessor : IArrivalsProcessor +{ + public Task ProcessAsync(ArrivalsContext context) + { + if (context.StopId.Split(':')[0] != "tranvias") + return Task.CompletedTask; + + foreach (var arrival in context.Arrivals) + { + arrival.Shift = FeedService.GetShiftBadge("tranvias", arrival.TripId); + } + + return Task.CompletedTask; + } +} diff --git a/src/Enmarcha.Backend/Services/Processors/FeedConfigProcessor.cs b/src/Enmarcha.Backend/Services/Processors/Normalisation/VitrasaNormalizationProcessor.cs index 9fc46c7..2cca672 100644 --- a/src/Enmarcha.Backend/Services/Processors/FeedConfigProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/Normalisation/VitrasaNormalizationProcessor.cs @@ -1,44 +1,19 @@ -using Enmarcha.Backend.Helpers; using Enmarcha.Backend.Types.Arrivals; -namespace Enmarcha.Backend.Services.Processors; +namespace Enmarcha.Backend.Services.Processors.Normalisation; -public class FeedConfigProcessor : IArrivalsProcessor +public class VitrasaNormalizationProcessor : IArrivalsProcessor { - private readonly FeedService _feedService; - - public FeedConfigProcessor(FeedService feedService) - { - _feedService = feedService; - } - public Task ProcessAsync(ArrivalsContext context) { - var feedId = context.StopId.Split(':')[0]; - var (fallbackColor, fallbackTextColor) = _feedService.GetFallbackColourForFeed(feedId); + if (context.StopId.Split(':')[0] != "vitrasa") + return Task.CompletedTask; foreach (var arrival in context.Arrivals) { - arrival.Route.ShortName = _feedService.NormalizeRouteShortName(feedId, arrival.Route.ShortName); - arrival.Headsign.Destination = FeedService.NormalizeStopName(feedId, arrival.Headsign.Destination); - - // Apply Vitrasa-specific line formatting - if (feedId == "vitrasa") - { - FormatVitrasaLine(arrival); - } - - arrival.Shift = FeedService.GetShiftBadge(feedId, arrival.TripId); - - if (string.IsNullOrEmpty(arrival.Route.Colour) || arrival.Route.Colour == "FFFFFF") - { - arrival.Route.Colour = fallbackColor; - arrival.Route.TextColour = fallbackTextColor; - } - else if (string.IsNullOrEmpty(arrival.Route.TextColour) || arrival.Route.TextColour == "000000") - { - arrival.Route.TextColour = ContrastHelper.GetBestTextColour(arrival.Route.Colour); - } + arrival.Headsign.Destination = FeedService.NormalizeStopName("vitrasa", arrival.Headsign.Destination); + FormatVitrasaLine(arrival); + arrival.Shift = FeedService.GetShiftBadge("vitrasa", arrival.TripId); } return Task.CompletedTask; @@ -93,6 +68,7 @@ public class FeedConfigProcessor : IArrivalsProcessor arrival.Route.ShortName = "GOL"; arrival.Headsign.Destination = "GOL ⚽: NAVIA-BOUZAS-URZAIZ-G. ESPINO"; } + arrival.Route.Colour = "6CACE4"; arrival.Route.TextColour = "000000"; break; diff --git a/src/Enmarcha.Backend/Services/Processors/Normalisation/XuntaNormalizationProcessor.cs b/src/Enmarcha.Backend/Services/Processors/Normalisation/XuntaNormalizationProcessor.cs new file mode 100644 index 0000000..9b7e498 --- /dev/null +++ b/src/Enmarcha.Backend/Services/Processors/Normalisation/XuntaNormalizationProcessor.cs @@ -0,0 +1,24 @@ +namespace Enmarcha.Backend.Services.Processors.Normalisation; + +public class XuntaNormalizationProcessor : IArrivalsProcessor +{ + private readonly FeedService _feedService; + + public XuntaNormalizationProcessor(FeedService feedService) + { + _feedService = feedService; + } + + public Task ProcessAsync(ArrivalsContext context) + { + if (context.StopId.Split(':')[0] != "xunta") + return Task.CompletedTask; + + foreach (var arrival in context.Arrivals) + { + arrival.Route.ShortName = _feedService.NormalizeRouteShortName("xunta", arrival.Route.ShortName); + } + + return Task.CompletedTask; + } +} diff --git a/src/Enmarcha.Backend/Services/Processors/CorunaRealTimeProcessor.cs b/src/Enmarcha.Backend/Services/Processors/RealTime/CorunaRealTimeProcessor.cs index 797221f..20dc356 100644 --- a/src/Enmarcha.Backend/Services/Processors/CorunaRealTimeProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/RealTime/CorunaRealTimeProcessor.cs @@ -3,7 +3,7 @@ using Enmarcha.Sources.TranviasCoruna; using Enmarcha.Backend.Types; using Enmarcha.Backend.Types.Arrivals; -namespace Enmarcha.Backend.Services.Processors; +namespace Enmarcha.Backend.Services.Processors.RealTime; public class CorunaRealTimeProcessor : AbstractRealTimeProcessor { diff --git a/src/Enmarcha.Backend/Services/Processors/CtagShuttleRealTimeProcessor.cs b/src/Enmarcha.Backend/Services/Processors/RealTime/CtagShuttleRealTimeProcessor.cs index ce2651f..804b09c 100644 --- a/src/Enmarcha.Backend/Services/Processors/CtagShuttleRealTimeProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/RealTime/CtagShuttleRealTimeProcessor.cs @@ -3,7 +3,7 @@ using Enmarcha.Sources.OpenTripPlannerGql.Queries; using Enmarcha.Backend.Types; using Enmarcha.Backend.Types.Arrivals; -namespace Enmarcha.Backend.Services.Processors; +namespace Enmarcha.Backend.Services.Processors.RealTime; public class CtagShuttleRealTimeProcessor : AbstractRealTimeProcessor { diff --git a/src/Enmarcha.Backend/Services/Processors/RenfeRealTimeProcessor.cs b/src/Enmarcha.Backend/Services/Processors/RealTime/RenfeRealTimeProcessor.cs index 5e5468e..26ffa24 100644 --- a/src/Enmarcha.Backend/Services/Processors/RenfeRealTimeProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/RealTime/RenfeRealTimeProcessor.cs @@ -4,7 +4,7 @@ using Enmarcha.Backend.Types.Arrivals; using Enmarcha.Sources.GtfsRealtime; using Arrival = Enmarcha.Backend.Types.Arrivals.Arrival; -namespace Enmarcha.Backend.Services.Processors; +namespace Enmarcha.Backend.Services.Processors.RealTime; public partial class RenfeRealTimeProcessor : AbstractRealTimeProcessor { diff --git a/src/Enmarcha.Backend/Services/Processors/TussaRealTimeProcessor.cs b/src/Enmarcha.Backend/Services/Processors/RealTime/TussaRealTimeProcessor.cs index 7808a3f..2cfdf28 100644 --- a/src/Enmarcha.Backend/Services/Processors/TussaRealTimeProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/RealTime/TussaRealTimeProcessor.cs @@ -3,7 +3,7 @@ using Enmarcha.Backend.Types.Arrivals; using Enmarcha.Sources.Tussa; using Arrival = Enmarcha.Backend.Types.Arrivals.Arrival; -namespace Enmarcha.Backend.Services.Processors; +namespace Enmarcha.Backend.Services.Processors.RealTime; public class TussaRealTimeProcessor : AbstractRealTimeProcessor { diff --git a/src/Enmarcha.Backend/Services/Processors/VitrasaRealTimeProcessor.cs b/src/Enmarcha.Backend/Services/Processors/RealTime/VitrasaRealTimeProcessor.cs index 5bbbfab..0227f9c 100644 --- a/src/Enmarcha.Backend/Services/Processors/VitrasaRealTimeProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/RealTime/VitrasaRealTimeProcessor.cs @@ -5,7 +5,7 @@ using Enmarcha.Backend.Types; using Enmarcha.Backend.Types.Arrivals; using Microsoft.Extensions.Options; -namespace Enmarcha.Backend.Services.Processors; +namespace Enmarcha.Backend.Services.Processors.RealTime; public class VitrasaRealTimeProcessor : AbstractRealTimeProcessor { diff --git a/src/Enmarcha.Backend/ViewModels/AlertFormViewModel.cs b/src/Enmarcha.Backend/ViewModels/AlertFormViewModel.cs index 6514a5a..d27fc8d 100644 --- a/src/Enmarcha.Backend/ViewModels/AlertFormViewModel.cs +++ b/src/Enmarcha.Backend/ViewModels/AlertFormViewModel.cs @@ -1,5 +1,4 @@ using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; using Enmarcha.Backend.Data.Models; namespace Enmarcha.Backend.ViewModels; diff --git a/src/Enmarcha.Sources.TranviasCoruna/Response.cs b/src/Enmarcha.Sources.TranviasCoruna/Response.cs index 88dc4e2..d94d32d 100644 --- a/src/Enmarcha.Sources.TranviasCoruna/Response.cs +++ b/src/Enmarcha.Sources.TranviasCoruna/Response.cs @@ -4,7 +4,7 @@ namespace Enmarcha.Sources.TranviasCoruna; public class QueryitrResponse { - [JsonPropertyName("buses")] public ArrivalInfo ArrivalInfo { get; set; } + [JsonPropertyName("buses")] public required ArrivalInfo ArrivalInfo { get; set; } } public class ArrivalInfo @@ -12,7 +12,7 @@ public class ArrivalInfo [JsonPropertyName("parada")] public int StopId { get; set; } [JsonPropertyName("lineas")] - public Route[] Routes { get; set; } + public required Route[] Routes { get; set; } } public class Route @@ -20,7 +20,7 @@ public class Route [JsonPropertyName("linea")] public int RouteId { get; set; } [JsonPropertyName("buses")] - public Arrival[] Arrivals { get; set; } + public required Arrival[] Arrivals { get; set; } } public class Arrival @@ -28,7 +28,7 @@ public class Arrival [JsonPropertyName("bus")] public int VehicleNumber { get; set; } [JsonPropertyName("tiempo")] - public string Minutes { get; set; } + public required string Minutes { get; set; } [JsonPropertyName("distancia")] - public string Metres { get; set; } + public required string Metres { get; set; } } diff --git a/src/Enmarcha.Sources.Tussa/Response.cs b/src/Enmarcha.Sources.Tussa/Response.cs index cbb1573..31cb698 100644 --- a/src/Enmarcha.Sources.Tussa/Response.cs +++ b/src/Enmarcha.Sources.Tussa/Response.cs @@ -5,10 +5,10 @@ namespace Enmarcha.Sources.Tussa; public class MaisbusResponse { [JsonPropertyName("id")] public int Id { get; set; } - [JsonPropertyName("codigo")] public string Code { get; set; } - [JsonPropertyName("nombre")] public string Name { get; set; } - [JsonPropertyName("coordenadas")] public Coordinates Coordinates { get; set; } - [JsonPropertyName("lineas")] public Route[] Routes { get; set; } + [JsonPropertyName("codigo")] public required string Code { get; set; } + [JsonPropertyName("nombre")] public required string Name { get; set; } + [JsonPropertyName("coordenadas")] public required Coordinates Coordinates { get; set; } + [JsonPropertyName("lineas")] public required Route[] Routes { get; set; } } public class Coordinates @@ -22,13 +22,13 @@ public class Coordinates public class Route { [JsonPropertyName("id")] public int Id { get; set; } - [JsonPropertyName("sinoptico")] public string Sinoptico { get; set; } - [JsonPropertyName("nombre")] public string Name { get; set; } - [JsonPropertyName("estilo")] public string Colour { get; set; } + [JsonPropertyName("sinoptico")] public required string Sinoptico { get; set; } + [JsonPropertyName("nombre")] public required string Name { get; set; } + [JsonPropertyName("estilo")] public required string Colour { get; set; } /// <example> /// 2025-12-28 23:57 /// </example> - [JsonPropertyName("proximoPaso")] public string NextArrival { get; set; } + [JsonPropertyName("proximoPaso")] public required string NextArrival { get; set; } [JsonPropertyName("minutosProximoPaso")] public int MinutesToArrive { get; set; } } diff --git a/src/frontend/app/api/schema.ts b/src/frontend/app/api/schema.ts index fe90642..64a9e94 100644 --- a/src/frontend/app/api/schema.ts +++ b/src/frontend/app/api/schema.ts @@ -173,10 +173,7 @@ export const ConsolidatedCirculationSchema = z.object({ }) .optional() .nullable(), - currentPosition: z - .object(PositionSchema) - .optional() - .nullable(), + currentPosition: z.object(PositionSchema).optional().nullable(), isPreviousTrip: z.boolean().optional().nullable(), previousTripShapeId: z.string().optional().nullable(), nextStreets: z.array(z.string()).optional().nullable(), diff --git a/src/frontend/app/components/arrivals/ArrivalList.tsx b/src/frontend/app/components/arrivals/ArrivalList.tsx index 18885c8..8fdef06 100644 --- a/src/frontend/app/components/arrivals/ArrivalList.tsx +++ b/src/frontend/app/components/arrivals/ArrivalList.tsx @@ -26,7 +26,10 @@ export const ArrivalList: React.FC<ArrivalListProps> = ({ <div className="flex flex-col flex-1 gap-3"> {arrivals.length === 0 && ( <div className="text-center text-muted mt-16"> - {t("estimates.none", "No hay llegadas próximas disponibles para esta parada.")} + {t( + "estimates.none", + "No hay llegadas próximas disponibles para esta parada." + )} </div> )} {arrivals.map((arrival, index) => diff --git a/src/frontend/app/contexts/JourneyContext.tsx b/src/frontend/app/contexts/JourneyContext.tsx index f513aa8..9c3c3ac 100644 --- a/src/frontend/app/contexts/JourneyContext.tsx +++ b/src/frontend/app/contexts/JourneyContext.tsx @@ -25,9 +25,7 @@ export interface ActiveJourney { interface JourneyContextValue { activeJourney: ActiveJourney | null; - startJourney: ( - journey: Omit<ActiveJourney, "hasNotified"> - ) => void; + startJourney: (journey: Omit<ActiveJourney, "hasNotified">) => void; stopJourney: () => void; markNotified: () => void; } @@ -61,9 +59,7 @@ export function JourneyProvider({ children }: { children: ReactNode }) { }, []); const markNotified = useCallback(() => { - setActiveJourney((prev) => - prev ? { ...prev, hasNotified: true } : null - ); + setActiveJourney((prev) => (prev ? { ...prev, hasNotified: true } : null)); }, []); return ( diff --git a/src/frontend/app/hooks/useJourneyTracker.ts b/src/frontend/app/hooks/useJourneyTracker.ts index e9be393..97bf23d 100644 --- a/src/frontend/app/hooks/useJourneyTracker.ts +++ b/src/frontend/app/hooks/useJourneyTracker.ts @@ -57,10 +57,7 @@ export function useJourneyTracker() { ) { const title = minutes <= 0 - ? t( - "journey.notification_now_title", - "¡Tu autobús está llegando!" - ) + ? t("journey.notification_now_title", "¡Tu autobús está llegando!") : t("journey.notification_approaching_title", { defaultValue: "Tu autobús llega en {{minutes}} min", minutes, |
