From e0ad08318d5834b9eaec2470c98faa2c4a23bd98 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 25 Feb 2026 14:00:51 +0000
Subject: feat: single light style, remove 3D buildings, language labels, stop
 disambiguation

Co-authored-by: arielcostas <94913521+arielcostas@users.noreply.github.com>
---
 src/frontend/app/routes/map.tsx | 87 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 84 insertions(+), 3 deletions(-)

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

diff --git a/src/frontend/app/routes/map.tsx b/src/frontend/app/routes/map.tsx
index 2686222..af94509 100644
--- a/src/frontend/app/routes/map.tsx
+++ b/src/frontend/app/routes/map.tsx
@@ -1,4 +1,4 @@
-import { Check, X } from "lucide-react";
+import { Check, MapPin, X } from "lucide-react";
 import type { FilterSpecification } from "maplibre-gl";
 import { useMemo, useRef, useState } from "react";
 import { useTranslation } from "react-i18next";
@@ -37,6 +37,9 @@ export default function StopMap() {
     StopSheetProps["stop"] | null
   >(null);
   const [isSheetOpen, setIsSheetOpen] = useState(false);
+  const [disambiguationStops, setDisambiguationStops] = useState<
+    Array<StopSheetProps["stop"]>
+  >([]);
   const mapRef = useRef<MapRef>(null);
 
   const {
@@ -105,9 +108,42 @@ export default function StopMap() {
       );
       return;
     }
-    const feature = features[0];
 
-    handlePointClick(feature);
+    // Collect only stop-layer features with valid properties
+    const stopFeatures = features.filter(
+      (f) => f.layer?.id?.startsWith("stops") && f.properties?.id
+    );
+
+    if (stopFeatures.length === 0) return;
+
+    if (stopFeatures.length === 1) {
+      // Single unambiguous stop – open the sheet directly
+      handlePointClick(stopFeatures[0]);
+      return;
+    }
+
+    // Multiple overlapping stops – deduplicate by stop id and ask the user
+    const seen = new Set<string>();
+    const candidates: Array<StopSheetProps["stop"]> = [];
+    for (const f of stopFeatures) {
+      const id: string = f.properties!.id;
+      if (!seen.has(id)) {
+        seen.add(id);
+        candidates.push({
+          stopId: id,
+          stopCode: f.properties!.code,
+          name: f.properties!.name || "Unknown Stop",
+        });
+      }
+    }
+
+    if (candidates.length === 1) {
+      // After deduplication only one stop remains
+      setSelectedStop(candidates[0]);
+      setIsSheetOpen(true);
+    } else {
+      setDisambiguationStops(candidates);
+    }
   };
 
   const stopLayerFilter = useMemo(() => {
@@ -350,6 +386,51 @@ export default function StopMap() {
             stop={selectedStop}
           />
         )}
+
+        {disambiguationStops.length > 1 && (
+          <div className="fixed inset-x-0 bottom-0 z-30 flex justify-center pointer-events-none pb-safe">
+            <div className="pointer-events-auto w-full max-w-md bg-white dark:bg-slate-900 rounded-t-2xl shadow-2xl border border-slate-200 dark:border-slate-700 p-4">
+              <div className="flex items-center justify-between mb-3">
+                <h3 className="font-semibold text-slate-900 dark:text-slate-100 text-base">
+                  {t("map.select_nearby_stop", "Seleccionar parada")}
+                </h3>
+                <button
+                  onClick={() => setDisambiguationStops([])}
+                  className="p-1 rounded-full hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors"
+                  aria-label={t("planner.close", "Cerrar")}
+                >
+                  <X className="w-5 h-5 text-slate-500" />
+                </button>
+              </div>
+              <ul className="divide-y divide-slate-100 dark:divide-slate-800">
+                {disambiguationStops.map((stop) => (
+                  <li key={stop.stopId}>
+                    <button
+                      className="w-full flex items-center gap-3 py-3 text-left hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors rounded-lg px-2"
+                      onClick={() => {
+                        setDisambiguationStops([]);
+                        setSelectedStop(stop);
+                        setIsSheetOpen(true);
+                      }}
+                    >
+                      <MapPin className="w-4 h-4 flex-shrink-0 text-primary-600" />
+                      <div>
+                        <div className="font-medium text-slate-900 dark:text-slate-100 text-sm">
+                          {stop.name}
+                        </div>
+                        {stop.stopCode && (
+                          <div className="text-xs text-slate-500 dark:text-slate-400">
+                            {stop.stopCode}
+                          </div>
+                        )}
+                      </div>
+                    </button>
+                  </li>
+                ))}
+              </ul>
+            </div>
+          </div>
+        )}
       </AppMap>
     </div>
   );
-- 
cgit v1.3

