2026-02-21 09:53:31 -05:00
|
|
|
/** Pinia store for route management */
|
|
|
|
|
import { defineStore } from 'pinia'
|
|
|
|
|
import { ref, computed } from 'vue'
|
|
|
|
|
import type { Route, BusStop } from '@/types'
|
|
|
|
|
import { routesService } from '@/services/routesService'
|
|
|
|
|
|
|
|
|
|
export const useRouteStore = defineStore('route', () => {
|
|
|
|
|
const selectedRouteId = ref<string | null>(null)
|
|
|
|
|
const selectedRouteName = ref<string | null>(null)
|
|
|
|
|
const selectedRouteStops = ref<BusStop[]>([])
|
|
|
|
|
const allRoutes = ref<Route[]>([])
|
|
|
|
|
const isLoadingRoutes = ref(false)
|
|
|
|
|
const isLoadingStops = ref(false)
|
|
|
|
|
const error = ref<string | null>(null)
|
2026-03-01 12:38:04 -05:00
|
|
|
const wasSelectedFromMap = ref(false)
|
2026-02-26 22:17:56 -05:00
|
|
|
const lastFetched = ref<number>(0) // ⚡ CACHÉ ESTÁTICO RUTAS
|
|
|
|
|
const stopsCache = ref<Map<string, { fetchedAt: number, stops: BusStop[] }>>(new Map()) // ⚡ CACHÉ ESTÁTICO PARADAS
|
2026-02-21 09:53:31 -05:00
|
|
|
|
|
|
|
|
const hasSelectedRoute = computed(() => selectedRouteId.value !== null && selectedRouteName.value !== null)
|
|
|
|
|
|
|
|
|
|
async function loadRoutes(filters?: { originCity?: string, destinationCity?: string }, force = false) {
|
2026-02-26 12:50:12 -05:00
|
|
|
const CACHE_TIME = 1000 * 60 * 15; // 15 minutos
|
|
|
|
|
const now = Date.now();
|
|
|
|
|
|
2026-03-01 17:35:13 -05:00
|
|
|
// Guard: Si ya se están cargando rutas, no iniciar otra petición
|
|
|
|
|
if (isLoadingRoutes.value) return;
|
|
|
|
|
|
2026-02-26 12:50:12 -05:00
|
|
|
// Si no forzamos, no hay filtros raros, ya tenemos rutas y aún no expira el caché, omitir llamada
|
|
|
|
|
if (!force && !filters && allRoutes.value.length > 0 && (now - lastFetched.value < CACHE_TIME)) {
|
2026-02-21 09:53:31 -05:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isLoadingRoutes.value = true
|
|
|
|
|
error.value = null
|
|
|
|
|
try {
|
|
|
|
|
allRoutes.value = await routesService.getAllRoutes(filters)
|
2026-02-26 12:50:12 -05:00
|
|
|
if (!filters) lastFetched.value = now; // Solo actualizar timer si es un request general limio
|
2026-02-21 09:53:31 -05:00
|
|
|
} catch (e) {
|
|
|
|
|
error.value = e instanceof Error ? e.message : 'Failed to load routes'
|
|
|
|
|
console.error('Error loading routes:', e)
|
|
|
|
|
} finally {
|
|
|
|
|
isLoadingRoutes.value = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-26 22:17:56 -05:00
|
|
|
async function loadRouteStops(routeId: string, force = false) {
|
|
|
|
|
const CACHE_TIME = 1000 * 60 * 15; // 15 minutos
|
|
|
|
|
const now = Date.now();
|
|
|
|
|
|
2026-03-01 17:35:13 -05:00
|
|
|
if (isLoadingStops.value) return;
|
2026-02-26 22:17:56 -05:00
|
|
|
if (!force && stopsCache.value.has(routeId)) {
|
|
|
|
|
const cacheEntry = stopsCache.value.get(routeId)!;
|
|
|
|
|
if (now - cacheEntry.fetchedAt < CACHE_TIME) {
|
|
|
|
|
selectedRouteStops.value = cacheEntry.stops;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-21 09:53:31 -05:00
|
|
|
isLoadingStops.value = true
|
|
|
|
|
error.value = null
|
|
|
|
|
try {
|
2026-02-26 22:17:56 -05:00
|
|
|
const stops = await routesService.getRouteStops(routeId)
|
|
|
|
|
selectedRouteStops.value = stops
|
|
|
|
|
stopsCache.value.set(routeId, { fetchedAt: now, stops })
|
2026-02-21 09:53:31 -05:00
|
|
|
} catch (e) {
|
|
|
|
|
error.value = e instanceof Error ? e.message : 'Failed to load route stops'
|
|
|
|
|
console.error('Error loading route stops:', e)
|
|
|
|
|
selectedRouteStops.value = []
|
|
|
|
|
} finally {
|
|
|
|
|
isLoadingStops.value = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function selectRoute(routeId: string, routeName: string) {
|
|
|
|
|
if (selectedRouteId.value === routeId) return
|
|
|
|
|
selectedRouteId.value = routeId
|
|
|
|
|
selectedRouteName.value = routeName
|
|
|
|
|
selectedRouteStops.value = [] // Clear old stops immediately
|
|
|
|
|
await loadRouteStops(routeId)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function clearSelection() {
|
|
|
|
|
selectedRouteId.value = null
|
|
|
|
|
selectedRouteName.value = null
|
|
|
|
|
selectedRouteStops.value = []
|
2026-03-01 12:38:04 -05:00
|
|
|
wasSelectedFromMap.value = false
|
2026-02-21 09:53:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
selectedRouteId,
|
|
|
|
|
selectedRouteName,
|
|
|
|
|
selectedRouteStops,
|
|
|
|
|
allRoutes,
|
|
|
|
|
isLoadingRoutes,
|
|
|
|
|
isLoadingStops,
|
|
|
|
|
error,
|
2026-03-01 12:38:04 -05:00
|
|
|
wasSelectedFromMap,
|
2026-02-21 09:53:31 -05:00
|
|
|
hasSelectedRoute,
|
|
|
|
|
loadRoutes,
|
|
|
|
|
loadRouteStops,
|
|
|
|
|
selectRoute,
|
|
|
|
|
clearSelection,
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|