Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/danitocsc/transporte-unrc-web-public/llms.txt

Use this file to discover all available pages before exploring further.

La página /mapa-demanda es el corazón interactivo del proyecto Transporte Tijuana. Muestra todas las paradas activas de las dos rutas piloto sobre un mapa basado en MapLibre GL JS, permite al usuario encontrar su parada más cercana con un solo toque, y ofrece un panel lateral con filtros de ruta y horarios estimados por turno.

Cómo funciona la página

La ruta /mapa-demanda es un Server Component marcado con export const dynamic = 'force-dynamic'. En cada petición, el servidor lee dos archivos del sistema de ficheros:
  • public/data/paradas.json — todas las paradas definidas
  • public/data/custom_routes.json — los trazados GeoJSON de las rutas piloto
Antes de enviar los datos al cliente, el servidor aplica dos transformaciones de privacidad:
1

Filtrado de paradas activas

Solo se incluyen las paradas cuyo campo active sea 1 (truthy). Las paradas marcadas como inactivas nunca llegan al navegador.
2

Sanitización de campos

De cada parada se extraen únicamente los campos públicos: id, name, lat, lng, route_id, turno y dias_raw. El campo students[] — que contendría datos personales — nunca se pasa al cliente.
3

Normalización de rutas

Las rutas se normalizan para exponer solo id, name, description, color y points. Los metadatos internos del editor (p. ej. visible, source) se omiten.
4

Renderizado con Suspense

El componente cliente <PublicMapPage> se envuelve en <Suspense> con un fallback de skeleton animado mientras carga el mapa.
El componente <PublicStopsMap> se importa con dynamic(() => import(...), { ssr: false }). Esto es necesario porque MapLibre GL JS accede a las APIs del navegador (window, WebGLRenderingContext) en el momento de importación — cargar el módulo en el servidor Node.js causaría un error. Mientras el mapa inicializa, se muestra un placeholder bg-slate-100 animate-pulse.

Rutas piloto disponibles

El mapa muestra dos rutas trazadas a partir del análisis de demanda de 192 estudiantes encuestados:

La Mesa → UNRC vía Camino Verde

ID de ruta: route-la-mesa-unrc-001
Color en mapa: naranja (#ff9500)
Distancia: 37.3 km · ~59 min
Trayecto: Blvd. Díaz Ordaz (La Mesa) → Lomas del Valle → Camino Verde → UNRC
Estudiantes cubiertos: 83
28 paradas activas, desde Calzapato Carrousel hasta Super Ley Natura

Centro → UNRC vía Corredor 2000

ID de ruta: route-centro-unrc-001
Color en mapa: azul (#0011ff)
Distancia: 39.9 km · ~72 min
Trayecto: Av. Constitución (Centro) → Blvd. Paseo de los Héroes → Corredor 2000 → UNRC
Estudiantes cubiertos: 107
17 paradas activas, desde Sitio Azul y Blanco hasta Parada Sendero

Interfaz de usuario

Panel lateral de paradas

El panel lateral (sidebar) se puede abrir de tres formas distintas:
Navega a /mapa-demanda?sidebar=true para abrir el panel automáticamente al cargar la página. Esto se usa, por ejemplo, desde la página de Informe cuando el usuario hace clic en “Paradas”.
https://transporte-unrc.vercel.app/mapa-demanda?sidebar=true
El parámetro también acepta ?sidebar=false para forzar el estado cerrado.

Botón de geolocalización

El botón “Encontrar mi parada más cercana” aparece tanto en el panel lateral (cuando no hay parada seleccionada) como flotando sobre el mapa (bottom-[4.5rem] md:bottom-6). Al pulsarlo:
  1. Se llama a navigator.geolocation.getCurrentPosition() con enableHighAccuracy: true y timeout: 10000 ms.
  2. Las coordenadas del usuario se ordenan contra todas las paradas activas usando la fórmula de Haversine (radio terrestre = 6371 km).
  3. La parada con menor distancia se marca como nearestStopId y se selecciona automáticamente.
  4. El mapa dibuja un punto azul en la posición del usuario y una línea discontinua hacia la parada más cercana.
  5. El panel lateral se abre mostrando el nombre de la parada, los días activos, el color de la ruta asignada y la distancia en kilómetros.
La geolocalización del navegador requiere que la página se sirva sobre HTTPS. La aplicación envía el encabezado HTTP Permissions-Policy: geolocation=(self), lo que significa que el acceso a la cámara de geolocalización solo está permitido desde el mismo origen (transporte-unrc.vercel.app). Si el componente se embebe en un <iframe> desde otro dominio sin el atributo allow="geolocation", el navegador bloqueará la solicitud.

Filtros de ruta

El panel lateral incluye un grupo de botones para filtrar las paradas visibles en el mapa y en la lista:
BotónfilterRouteEfecto
Todas"all"Muestra las paradas de ambas rutas
La Mesa"route-la-mesa-unrc-001"Solo paradas de la ruta naranja
Centro"route-centro-unrc-001"Solo paradas de la ruta azul
El estado filterRoute controla simultáneamente la lista y los marcadores del mapa mediante el array derivado filteredStops (calculado con useMemo).

Selector de horario por turno

Al seleccionar una parada (ya sea la más cercana o cualquier otra del listado), el panel muestra un <select> con los tres turnos disponibles. Al elegir uno, aparece el horario estimado de salida:
Salida estimada: 06:30 AM
Estos horarios son los del autobús universitario piloto, no del transporte público general.

Marcadores en el mapa

El mapa (PublicStopsMap) usa MapLibre GL JS con tiles de CartoDB Voyager como base cartográfica. Los marcadores de parada son divs SVG generados dinámicamente:
bg
string
Color de fondo del marcador. Azul (#0ea5e9) para la parada más cercana, vino (#7A003C) para la parada seleccionada, gris oscuro (#374151) para el resto.
size
number
Tamaño en píxeles del marcador. 36px para la parada más cercana o seleccionada; 28px para el resto.
border
string
Borde del marcador. Blanco (#fff) cuando está destacado; gris (#9ca3af) por defecto.
Las rutas se renderizan como capas GeoJSON de tipo line con line-width: 5 y line-opacity: 0.85. Al hacer clic sobre una línea de ruta aparece un popup con el nombre y descripción de la ruta. El marcador de la UNRC (destino) es un círculo vino con la letra U fijo en las coordenadas [32.436451, -116.860092].

Diseño responsive

La página usa un layout flex flex-col h-screen que aprovecha toda la altura visible. Los principales puntos de quiebre son:
  • < md (< 768 px): el panel lateral ocupa pantalla completa como overlay; la barra de navegación está fija en la parte inferior con pb-16 de padding para no quedar tapada por ella.
  • md (≥ 768 px): el panel tiene ancho fijo de w-80 (320 px) a la izquierda; el mapa ocupa el resto; la barra de navegación del encabezado es visible y la barra inferior está oculta (hidden).

Build docs developers (and LLMs) love