fix: corregir paradas faltantes, duplicado de ubicación y alineación de botones
This commit is contained in:
@ -4,7 +4,6 @@ import { useDirectionsRoute } from './useDirectionsRoute'
|
|||||||
import { useParadaCercana } from './useParadaCercana'
|
import { useParadaCercana } from './useParadaCercana'
|
||||||
import type { BusStop } from '@/types'
|
import type { BusStop } from '@/types'
|
||||||
import { useRouteStore } from '@/stores/route'
|
import { useRouteStore } from '@/stores/route'
|
||||||
import { useGoogleMaps } from './useGoogleMaps'
|
|
||||||
|
|
||||||
export const useFlujoPrincipal = () => {
|
export const useFlujoPrincipal = () => {
|
||||||
const { limpiarMapa } = useMapState()
|
const { limpiarMapa } = useMapState()
|
||||||
@ -30,6 +29,7 @@ export const useFlujoPrincipal = () => {
|
|||||||
_ruta: { id: string },
|
_ruta: { id: string },
|
||||||
paradas: BusStop[],
|
paradas: BusStop[],
|
||||||
map: google.maps.Map | undefined,
|
map: google.maps.Map | undefined,
|
||||||
|
addCleanMarker: Function,
|
||||||
skipGuidedZoom = false
|
skipGuidedZoom = false
|
||||||
) => {
|
) => {
|
||||||
if (!map) return
|
if (!map) return
|
||||||
@ -40,7 +40,6 @@ export const useFlujoPrincipal = () => {
|
|||||||
cargando.value = true
|
cargando.value = true
|
||||||
|
|
||||||
// ── PASO 2: Obtener ubicación ──
|
// ── PASO 2: Obtener ubicación ──
|
||||||
// Paradas ya vienen precargadas desde store para evitar doble fetch
|
|
||||||
let ubicacion: { lat: number, lng: number } | null = null;
|
let ubicacion: { lat: number, lng: number } | null = null;
|
||||||
try {
|
try {
|
||||||
ubicacion = await obtenerUbicacion();
|
ubicacion = await obtenerUbicacion();
|
||||||
@ -48,7 +47,6 @@ export const useFlujoPrincipal = () => {
|
|||||||
console.warn('SIBU | No se pudo obtener ubicación', err);
|
console.warn('SIBU | No se pudo obtener ubicación', err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format Paradas for trazarRuta
|
|
||||||
const paradasFormateadas = paradas.map((p, i) => ({
|
const paradasFormateadas = paradas.map((p, i) => ({
|
||||||
id: typeof p.id === 'string' ? parseInt(p.id) || i : p.id || i,
|
id: typeof p.id === 'string' ? parseInt(p.id) || i : p.id || i,
|
||||||
nombre: p.name,
|
nombre: p.name,
|
||||||
@ -57,11 +55,9 @@ export const useFlujoPrincipal = () => {
|
|||||||
orden: i
|
orden: i
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Si no hay paradas o muy pocas, abortar
|
|
||||||
if (paradasFormateadas.length < 2) return;
|
if (paradasFormateadas.length < 2) return;
|
||||||
|
|
||||||
if (!ubicacion) {
|
if (!ubicacion) {
|
||||||
// Fallback: solo dibujar la ruta sin parada cercana (o podríamos no hacer zoom guiado)
|
|
||||||
await trazarRuta(paradasFormateadas, map, false);
|
await trazarRuta(paradasFormateadas, map, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -71,7 +67,6 @@ export const useFlujoPrincipal = () => {
|
|||||||
|
|
||||||
// ── PASO 4: Calcular parada más cercana (Omitir si skipGuidedZoom) ───────────────
|
// ── PASO 4: Calcular parada más cercana (Omitir si skipGuidedZoom) ───────────────
|
||||||
if (skipGuidedZoom) {
|
if (skipGuidedZoom) {
|
||||||
// Si omitimos el zoom guiado, solo hacemos un zoom general a la ruta
|
|
||||||
const bounds = new google.maps.LatLngBounds()
|
const bounds = new google.maps.LatLngBounds()
|
||||||
paradasFormateadas.forEach(p => bounds.extend(new google.maps.LatLng(p.latitud, p.longitud)))
|
paradasFormateadas.forEach(p => bounds.extend(new google.maps.LatLng(p.latitud, p.longitud)))
|
||||||
map.fitBounds(bounds, { top: 100, bottom: 100, left: 60, right: 60 })
|
map.fitBounds(bounds, { top: 100, bottom: 100, left: 60, right: 60 })
|
||||||
@ -79,21 +74,13 @@ export const useFlujoPrincipal = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await encontrarParadaCercana(ubicacion, paradas, map)
|
await encontrarParadaCercana(ubicacion, paradas, map)
|
||||||
|
|
||||||
const paradaCercanaFound = paradaCercana.value
|
const paradaCercanaFound = paradaCercana.value
|
||||||
|
if (!paradaCercanaFound) return;
|
||||||
if (!paradaCercanaFound) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const routeStore = useRouteStore()
|
const routeStore = useRouteStore()
|
||||||
if (routeStore.selectedRouteId !== _ruta.id) {
|
if (routeStore.selectedRouteId !== _ruta.id) return;
|
||||||
console.log('Abortando flujo: el mapa fue limpiado o cambió de ruta.')
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── PASO 5: Dibujar tramo relevante (Amarillo Vivo) ───────
|
// ── PASO 5: Dibujar tramo relevante (Amarillo Vivo) ───────
|
||||||
// Usar una comparación más robusta que incluya proximidad o nombre
|
|
||||||
const idx = paradasFormateadas.findIndex(p => {
|
const idx = paradasFormateadas.findIndex(p => {
|
||||||
const samePos = Math.abs(p.longitud - paradaCercanaFound.longitude) < 0.0001 &&
|
const samePos = Math.abs(p.longitud - paradaCercanaFound.longitude) < 0.0001 &&
|
||||||
Math.abs(p.latitud - paradaCercanaFound.latitude) < 0.0001;
|
Math.abs(p.latitud - paradaCercanaFound.latitude) < 0.0001;
|
||||||
@ -107,8 +94,7 @@ export const useFlujoPrincipal = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── PASO 6: Dibujar marcadores de todas las paradas (Restaurado) ──────────
|
// ── PASO 6: Dibujar marcadores de todas las paradas ──────────
|
||||||
const { addCleanMarker } = useGoogleMaps()
|
|
||||||
paradasFormateadas.forEach((p, i) => {
|
paradasFormateadas.forEach((p, i) => {
|
||||||
const esCercana = i === idx;
|
const esCercana = i === idx;
|
||||||
const esPasada = idx !== -1 && i < idx;
|
const esPasada = idx !== -1 && i < idx;
|
||||||
@ -123,10 +109,7 @@ export const useFlujoPrincipal = () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ── PASO 7: Pulso animado en ubicación del usuario ────
|
// ── PASO 7: Zoom centrado en usuario + parada cercana ─
|
||||||
dibujarPulsoUsuario(ubicacion, map)
|
|
||||||
|
|
||||||
// ── PASO 8: Zoom centrado en usuario + parada cercana ─
|
|
||||||
hacerZoomAlTramoRelevante(ubicacion, paradaCercanaFound, map)
|
hacerZoomAlTramoRelevante(ubicacion, paradaCercanaFound, map)
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -137,47 +120,6 @@ export const useFlujoPrincipal = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PULSO ANIMADO EN LA UBICACIÓN DEL USUARIO:
|
|
||||||
const dibujarPulsoUsuario = (
|
|
||||||
ubicacion: { lat: number, lng: number },
|
|
||||||
map: google.maps.Map
|
|
||||||
) => {
|
|
||||||
const { registrarCircle, registrarMarker } = useMapState()
|
|
||||||
|
|
||||||
// Círculo exterior pulsante (efecto ripple)
|
|
||||||
registrarCircle(
|
|
||||||
new google.maps.Circle({
|
|
||||||
map,
|
|
||||||
center: ubicacion,
|
|
||||||
radius: 80, // metros
|
|
||||||
fillColor: '#3B82F6',
|
|
||||||
fillOpacity: 0.15,
|
|
||||||
strokeColor: '#3B82F6',
|
|
||||||
strokeOpacity: 0.4,
|
|
||||||
strokeWeight: 1,
|
|
||||||
zIndex: 1
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
// Punto central sólido del usuario
|
|
||||||
registrarMarker(
|
|
||||||
new google.maps.Marker({
|
|
||||||
position: ubicacion,
|
|
||||||
map,
|
|
||||||
icon: {
|
|
||||||
path: google.maps.SymbolPath.CIRCLE,
|
|
||||||
fillColor: '#3B82F6', // azul
|
|
||||||
fillOpacity: 1,
|
|
||||||
strokeColor: '#FFFFFF',
|
|
||||||
strokeWeight: 3,
|
|
||||||
scale: 9
|
|
||||||
},
|
|
||||||
title: 'Tu ubicación',
|
|
||||||
zIndex: 20 // encima de todo
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ZOOM QUE MUESTRA USUARIO Y PARADA CERCANA:
|
// ZOOM QUE MUESTRA USUARIO Y PARADA CERCANA:
|
||||||
const hacerZoomAlTramoRelevante = (
|
const hacerZoomAlTramoRelevante = (
|
||||||
ubicacion: { lat: number, lng: number },
|
ubicacion: { lat: number, lng: number },
|
||||||
|
|||||||
@ -32,7 +32,7 @@ const mapStore = useMapStore();
|
|||||||
const couponStore = useCouponStore();
|
const couponStore = useCouponStore();
|
||||||
const authStore = useAuthStore();
|
const authStore = useAuthStore();
|
||||||
|
|
||||||
const { map, isLoaded, error: mapsError, initMap, addHtmlMarker, setCenter, setZoom, addMarker } = useGoogleMaps();
|
const { map, isLoaded, error: mapsError, initMap, addHtmlMarker, setCenter, setZoom, addMarker, addCleanMarker } = useGoogleMaps();
|
||||||
const { estasCargando: estasCargandoRuta, errorRuta } = useDirectionsRoute();
|
const { estasCargando: estasCargandoRuta, errorRuta } = useDirectionsRoute();
|
||||||
const { encontrarParadaCercana, paradaCercana, distanciaMetros, duracionCaminata } = useParadaCercana();
|
const { encontrarParadaCercana, paradaCercana, distanciaMetros, duracionCaminata } = useParadaCercana();
|
||||||
const { calcularETA, busesActivos, cargando: etaCargando } = useETA();
|
const { calcularETA, busesActivos, cargando: etaCargando } = useETA();
|
||||||
@ -202,7 +202,7 @@ async function updateMapMarkers(skipZoom = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const selectedRouteObj = routeStore.allRoutes.find(r => r.id === currentRequestRouteId) || { id: currentRequestRouteId, short_name: currentRequestRouteId };
|
const selectedRouteObj = routeStore.allRoutes.find(r => r.id === currentRequestRouteId) || { id: currentRequestRouteId, short_name: currentRequestRouteId };
|
||||||
await procesarSeleccionDeRuta(selectedRouteObj, stops as BusStop[], map.value, skipZoom);
|
await procesarSeleccionDeRuta(selectedRouteObj, stops as BusStop[], map.value, addCleanMarker, skipZoom);
|
||||||
reDrawUserMarker();
|
reDrawUserMarker();
|
||||||
|
|
||||||
if (routeStore.selectedRouteId !== currentRequestRouteId) return;
|
if (routeStore.selectedRouteId !== currentRequestRouteId) return;
|
||||||
@ -553,6 +553,7 @@ watch(() => authStore.userProfile?.auto_location, (canLocate) => {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
z-index: 1001;
|
z-index: 1001;
|
||||||
|
align-items: flex-end; /* Alinea botones a la derecha */
|
||||||
}
|
}
|
||||||
|
|
||||||
.offers-fab {
|
.offers-fab {
|
||||||
|
|||||||
Reference in New Issue
Block a user