From f65b4e1e0d5648038823962349279be4badc68ed Mon Sep 17 00:00:00 2001
From: Ariel Costas Guerrero <ariel@costas.dev>
Date: Tue, 24 Jun 2025 16:02:02 +0200
Subject: Refactor navigation structure: move NavBar to its own component,
 implement geolocation handling, and remove unused isWithinVigo function from
 AppContext.

---
 src/frontend/app/components/NavBar.tsx | 84 ++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)
 create mode 100644 src/frontend/app/components/NavBar.tsx

(limited to 'src/frontend/app/components/NavBar.tsx')

diff --git a/src/frontend/app/components/NavBar.tsx b/src/frontend/app/components/NavBar.tsx
new file mode 100644
index 0000000..091cc21
--- /dev/null
+++ b/src/frontend/app/components/NavBar.tsx
@@ -0,0 +1,84 @@
+import { Link } from "react-router";
+import { Map, MapPin, Settings } from "lucide-react";
+import { useApp } from "../AppContext";
+import type { LngLatLike } from "maplibre-gl";
+
+// Helper: check if coordinates are within Vigo bounds
+function isWithinVigo(lngLat: LngLatLike): boolean {
+  let lng: number, lat: number;
+  if (Array.isArray(lngLat)) {
+    [lng, lat] = lngLat;
+  } else if ('lng' in lngLat && 'lat' in lngLat) {
+    lng = lngLat.lng;
+    lat = lngLat.lat;
+  } else {
+    return false;
+  }
+  // Rough bounding box for Vigo
+  return lat >= 42.18 && lat <= 42.30 && lng >= -8.78 && lng <= -8.65;
+}
+
+export default function NavBar() {
+  const { mapState, updateMapState, mapPositionMode } = useApp();
+
+  const navItems = [
+    {
+      name: 'Paradas',
+      icon: MapPin,
+      path: '/stops'
+    },
+    {
+      name: 'Mapa',
+      icon: Map,
+      path: '/map',
+      callback: () => {
+        if (mapPositionMode !== 'gps') {
+          return;
+        }
+
+        if (!('geolocation' in navigator)) {
+          return;
+        }
+
+        navigator.geolocation.getCurrentPosition(
+          (position) => {
+            const { latitude, longitude } = position.coords;
+            const coords: LngLatLike = [latitude, longitude];
+            if (isWithinVigo(coords)) {
+              updateMapState(coords, 16);
+            }
+          },
+          () => { }
+        );
+      }
+    },
+    {
+      name: 'Ajustes',
+      icon: Settings,
+      path: '/settings'
+    }
+  ];
+
+  return (
+    <nav className="navigation-bar">
+      {navItems.map(item => {
+        const Icon = item.icon;
+        const isActive = location.pathname.startsWith(item.path);
+
+        return (
+          <Link
+            key={item.name}
+            to={item.path}
+            className={`navigation-bar__link ${isActive ? 'active' : ''}`}
+            onClick={item.callback ? item.callback : undefined}
+            title={item.name}
+            aria-label={item.name}
+          >
+            <Icon size={24} />
+            <span>{item.name}</span>
+          </Link>
+        );
+      })}
+    </nav>
+  );
+}
-- 
cgit v1.3

