From 49ef6f4af837d4f3f4f367fa831f1ff176036c27 Mon Sep 17 00:00:00 2001
From: Copilot <198982749+Copilot@users.noreply.github.com>
Date: Thu, 5 Mar 2026 18:24:51 +0100
Subject: Show probable traffic restriction warning on Xunta legs within urban
 municipalities (#141)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: arielcostas <94913521+arielcostas@users.noreply.github.com>
Co-authored-by: Ariel Costas Guerrero <ariel@costas.dev>
---
 src/frontend/app/routes/planner.tsx | 42 +++++++++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)

(limited to 'src/frontend/app/routes/planner.tsx')

diff --git a/src/frontend/app/routes/planner.tsx b/src/frontend/app/routes/planner.tsx
index 1f64590..5fd0ce7 100644
--- a/src/frontend/app/routes/planner.tsx
+++ b/src/frontend/app/routes/planner.tsx
@@ -1,4 +1,4 @@
-import { Coins, CreditCard, Footprints } from "lucide-react";
+import { AlertTriangle, Coins, CreditCard, Footprints } from "lucide-react";
 import maplibregl from "maplibre-gl";
 import "maplibre-gl/dist/maplibre-gl.css";
 import React, { useEffect, useMemo, useRef, useState } from "react";
@@ -72,6 +72,25 @@ const sumWalkMetrics = (legs: Itinerary["legs"]) => {
   return { meters, minutes: Math.max(0, Math.round(minutes)) };
 };
 
+const URBAN_MUNICIPALITIES: Record<string, string> = {
+  "15030": "A Coruña",
+  "27028": "Lugo",
+  "32054": "Ourense",
+  "15078": "Santiago de Compostela",
+  "36057": "Vigo",
+};
+
+const getUrbanMunicipalityWarning = (
+  leg: Itinerary["legs"][number]
+): string | null => {
+  if (leg.feedId !== "xunta") return null;
+  const fromMunicipality = leg.from?.zoneId?.substring(0, 5);
+  const toMunicipality = leg.to?.zoneId?.substring(0, 5);
+  if (!fromMunicipality || !toMunicipality) return null;
+  if (fromMunicipality !== toMunicipality) return null;
+  return URBAN_MUNICIPALITIES[fromMunicipality] ?? null;
+};
+
 const ItinerarySummary = ({
   itinerary,
   onClick,
@@ -653,6 +672,25 @@ const ItineraryDetail = ({
                               </ul>
                             </details>
                           )}
+                        {(() => {
+                          const municipality = getUrbanMunicipalityWarning(leg);
+                          if (!municipality) return null;
+                          return (
+                            <div className="mt-2 flex items-start gap-2 rounded-md bg-yellow-50 dark:bg-yellow-900/30 border border-yellow-300 dark:border-yellow-700 px-3 py-2 text-xs text-yellow-800 dark:text-yellow-200">
+                              <AlertTriangle className="w-4 h-4 shrink-0 mt-0.5 text-yellow-600 dark:text-yellow-400" />
+                              <div>
+                                <div className="font-semibold">
+                                  {t("planner.urban_traffic_warning")}
+                                </div>
+                                <div>
+                                  {t("planner.urban_traffic_warning_desc", {
+                                    municipality,
+                                  })}
+                                </div>
+                              </div>
+                            </div>
+                          );
+                        })()}
                       </>
                     )}
                   </div>
@@ -668,7 +706,7 @@ const ItineraryDetail = ({
 
 export default function PlannerPage() {
   const { t } = useTranslation();
-  usePageTitle(t("navbar.planner", "Planificador"));
+  () => usePageTitle(t("navbar.planner", "Planificador"));
   const location = useLocation();
   const {
     plan,
-- 
cgit v1.3

