Rename system to SIB: update translations, logos, views, stores and logs
This commit is contained in:
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
@ -40,12 +40,12 @@ async function dispatchRefocus(reason: string) {
|
|||||||
// Debounce: no disparar dos eventos seguidos en menos de 1 segundo
|
// Debounce: no disparar dos eventos seguidos en menos de 1 segundo
|
||||||
if (refocusDebounceTimer) return
|
if (refocusDebounceTimer) return
|
||||||
refocusDebounceTimer = setTimeout(() => { refocusDebounceTimer = null }, 1000)
|
refocusDebounceTimer = setTimeout(() => { refocusDebounceTimer = null }, 1000)
|
||||||
console.log(`SIBU | App.vue dispatching auth check and refocus — motivo: ${reason}`)
|
console.log(`SIB | App.vue dispatching auth check and refocus — motivo: ${reason}`)
|
||||||
|
|
||||||
// 🛡 HIGIENE TRANSACCIONAL: Solo verificamos sesión si el usuario estaba logueado.
|
// 🛡 HIGIENE TRANSACCIONAL: Solo verificamos sesión si el usuario estaba logueado.
|
||||||
// Si Guest, omitimos el Refresh para no fallar
|
// Si Guest, omitimos el Refresh para no fallar
|
||||||
if (authStore.isAuthenticated) {
|
if (authStore.isAuthenticated) {
|
||||||
console.log(`SIBU | Verificando sanidad de sesión Supabase...`)
|
console.log(`SIB | Verificando sanidad de sesión Supabase...`)
|
||||||
const timeoutMs = 5000
|
const timeoutMs = 5000
|
||||||
|
|
||||||
const refreshWithTimeout = Promise.race([
|
const refreshWithTimeout = Promise.race([
|
||||||
@ -58,12 +58,12 @@ async function dispatchRefocus(reason: string) {
|
|||||||
try {
|
try {
|
||||||
await refreshWithTimeout
|
await refreshWithTimeout
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.warn("SIBU | Error al verificar sesión en refocus (timeout o red).", err)
|
console.warn("SIB | Error al verificar sesión en refocus (timeout o red).", err)
|
||||||
// FIX CRÍTICO: Si el error es de timeout (5s), la persona estaba eligiendo ruta o
|
// FIX CRÍTICO: Si el error es de timeout (5s), la persona estaba eligiendo ruta o
|
||||||
// subiendo archivo y la red tardó. NUNCA expulsarla automáticamente en timeout.
|
// subiendo archivo y la red tardó. NUNCA expulsarla automáticamente en timeout.
|
||||||
// El caché local de Supabase ya mantiene su sesión válida bajo el capó.
|
// El caché local de Supabase ya mantiene su sesión válida bajo el capó.
|
||||||
if (err.message === "Auth refresh timeout") {
|
if (err.message === "Auth refresh timeout") {
|
||||||
console.log("SIBU | Ignorando timeout, manteniendo sesión optimista.")
|
console.log("SIB | Ignorando timeout, manteniendo sesión optimista.")
|
||||||
} else {
|
} else {
|
||||||
// Solo si hay un error real de Auth (sesión vencida rechazada por Supabase)
|
// Solo si hay un error real de Auth (sesión vencida rechazada por Supabase)
|
||||||
// se cierra sesión, pero no haremos signOut agresivo sin confirmar.
|
// se cierra sesión, pero no haremos signOut agresivo sin confirmar.
|
||||||
@ -96,9 +96,9 @@ function forceResetAllLoadingStates() {
|
|||||||
if (authStore.isAuthenticated) {
|
if (authStore.isAuthenticated) {
|
||||||
useFavoritesStore().$patch({ isLoading: false })
|
useFavoritesStore().$patch({ isLoading: false })
|
||||||
}
|
}
|
||||||
console.log('SIBU | ✅ Loading states reseteados tras regreso del background')
|
console.log('SIB | ✅ Loading states reseteados tras regreso del background')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('SIBU | No se pudo resetear loading states:', e)
|
console.warn('SIB | No se pudo resetear loading states:', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,8 +21,8 @@
|
|||||||
</Transition>
|
</Transition>
|
||||||
|
|
||||||
<Transition name="menu-slide">
|
<Transition name="menu-slide">
|
||||||
<div v-if="showMenu" class="menu-dropdown sibu-sidebar">
|
<div v-if="showMenu" class="menu-dropdown sib-sidebar">
|
||||||
<div class="sibu-header-plain">
|
<div class="sib-header-plain">
|
||||||
<div class="user-profile-optimized">
|
<div class="user-profile-optimized">
|
||||||
<div class="user-avatar-main">
|
<div class="user-avatar-main">
|
||||||
<span class="material-icons user-icon-accent">person</span>
|
<span class="material-icons user-icon-accent">person</span>
|
||||||
@ -81,7 +81,7 @@
|
|||||||
<button v-else class="session-btn logout-solid" @click="handleLogout">
|
<button v-else class="session-btn logout-solid" @click="handleLogout">
|
||||||
<span class="material-icons">logout</span> {{ t('menu.logout') }}
|
<span class="material-icons">logout</span> {{ t('menu.logout') }}
|
||||||
</button>
|
</button>
|
||||||
<div class="sibu-tag-footer">SIBU SYSTEM v1.2.0</div>
|
<div class="sib-tag-footer">SIB SYSTEM v1.2.0</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
@ -229,10 +229,10 @@ const handleLogout = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* SIBU SIDEBAR STYLES (SOLID) */
|
/* SIB SIDEBAR STYLES (SOLID) */
|
||||||
|
|
||||||
/* SIBU SIDEBAR OPTIMIZED */
|
/* SIB SIDEBAR OPTIMIZED */
|
||||||
.sibu-sidebar {
|
.sib-sidebar {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -251,7 +251,7 @@ const handleLogout = () => {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sibu-header-plain {
|
.sib-header-plain {
|
||||||
padding: 50px 24px 20px;
|
padding: 50px 24px 20px;
|
||||||
background: var(--bg-primary);
|
background: var(--bg-primary);
|
||||||
border-bottom: 2px solid var(--active-color);
|
border-bottom: 2px solid var(--active-color);
|
||||||
@ -420,7 +420,7 @@ const handleLogout = () => {
|
|||||||
transform: scale(0.98);
|
transform: scale(0.98);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sibu-tag-footer {
|
.sib-tag-footer {
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
|
|||||||
@ -32,7 +32,7 @@ const handleLogin = async () => {
|
|||||||
else router.push('/map')
|
else router.push('/map')
|
||||||
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('SIBU | Error Login:', error)
|
console.error('SIB | Error Login:', error)
|
||||||
if (error.message?.includes('Invalid login credentials')) {
|
if (error.message?.includes('Invalid login credentials')) {
|
||||||
errorMessage.value = t('auth.invalidCreds')
|
errorMessage.value = t('auth.invalidCreds')
|
||||||
} else {
|
} else {
|
||||||
@ -50,7 +50,7 @@ const handleLogin = async () => {
|
|||||||
<!-- Welcome Text (Mobile-ish) -->
|
<!-- Welcome Text (Mobile-ish) -->
|
||||||
<div class="welcome-header">
|
<div class="welcome-header">
|
||||||
<h2>{{ t('auth.loginTab') }}</h2>
|
<h2>{{ t('auth.loginTab') }}</h2>
|
||||||
<p>Bienvenido de vuelta a SIBU</p>
|
<p>Bienvenido de vuelta a SIB</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Input Group -->
|
<!-- Input Group -->
|
||||||
|
|||||||
@ -135,21 +135,13 @@ export function useETA() {
|
|||||||
const [hStr, mStr] = salida.split(':');
|
const [hStr, mStr] = salida.split(':');
|
||||||
const minutosSalida = parseInt(hStr) * 60 + parseInt(mStr);
|
const minutosSalida = parseInt(hStr) * 60 + parseInt(mStr);
|
||||||
|
|
||||||
// Cálculo explícito: tiempo que falta para salir + tiempo de trayecto hasta la parada
|
|
||||||
// Si el bus ya salió, el tiempo de espera para salir es 0 y el tiempo de trayecto se reduce
|
|
||||||
const minutosEsperaSalida = Math.max(0, minutosSalida - minutosAhora);
|
|
||||||
const minutosTransitoBase = minutosHastaParada;
|
const minutosTransitoBase = minutosHastaParada;
|
||||||
const minutosTranscurridosDesdeSalida = Math.max(0, minutosAhora - minutosSalida);
|
|
||||||
|
|
||||||
// Si ya salió, el trayecto restante es base - transcurrido. Si no ha salido, es el base completo.
|
|
||||||
const minutosTransitoRestante = Math.max(0, minutosTransitoBase - minutosTranscurridosDesdeSalida);
|
|
||||||
const etaMinutos = minutosEsperaSalida + minutosTransitoRestante;
|
|
||||||
|
|
||||||
const minutosLlegadaEstablecidos = minutosSalida + minutosTransitoBase;
|
const minutosLlegadaEstablecidos = minutosSalida + minutosTransitoBase;
|
||||||
|
const etaMinutos = minutosLlegadaEstablecidos - minutosAhora;
|
||||||
|
|
||||||
// Logging para depuración (solo en desarrollo)
|
// Logging para depuración (solo en desarrollo)
|
||||||
if (import.meta.env.DEV) {
|
if (import.meta.env.DEV) {
|
||||||
console.log(`SIBU | Bus ${salida}: Ahora=${minutosAhora}, Salida=${minutosSalida}, Espera=${minutosEsperaSalida}, TransitoRest=${Math.round(minutosTransitoRestante)}, ETA=${Math.round(etaMinutos)}`);
|
console.log(`SIB | Bus ${salida}: Ahora=${minutosAhora}, Salida=${minutosSalida}, LlegadaEst=${minutosLlegadaEstablecidos}, ETA=${Math.round(etaMinutos)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const horaLlegada = format12h(minutosLlegadaEstablecidos);
|
const horaLlegada = format12h(minutosLlegadaEstablecidos);
|
||||||
@ -160,13 +152,13 @@ export function useETA() {
|
|||||||
|
|
||||||
if (etaMinutos > 5) {
|
if (etaMinutos > 5) {
|
||||||
estado = busYaSalio ? 'en_camino' : 'próximo';
|
estado = busYaSalio ? 'en_camino' : 'próximo';
|
||||||
} else if (etaMinutos >= -2) {
|
|
||||||
estado = 'en_camino';
|
|
||||||
} else {
|
} else {
|
||||||
estado = 'pasó';
|
estado = 'en_camino';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (etaMinutos < -45) continue;
|
// Filtrar buses que ya pasaron (ETA < 0)
|
||||||
|
// Solo mostramos buses a los que el usuario tiene posibilidad de llegar
|
||||||
|
if (etaMinutos < 0) continue;
|
||||||
|
|
||||||
resultados.push({
|
resultados.push({
|
||||||
horario_id: h.id,
|
horario_id: h.id,
|
||||||
@ -185,7 +177,7 @@ export function useETA() {
|
|||||||
|
|
||||||
busesActivos.value = resultados.slice(0, 5);
|
busesActivos.value = resultados.slice(0, 5);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('SIBU | Error calculando ETA:', e);
|
console.error('SIB | Error calculando ETA:', e);
|
||||||
} finally {
|
} finally {
|
||||||
cargando.value = false;
|
cargando.value = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,7 +44,7 @@ export const useFlujoPrincipal = () => {
|
|||||||
|
|
||||||
// ── PASO 2: Sincronización (Promise.all) ──
|
// ── PASO 2: Sincronización (Promise.all) ──
|
||||||
// Disparamos Supabase (paradas) y GPS al mismo tiempo
|
// Disparamos Supabase (paradas) y GPS al mismo tiempo
|
||||||
console.log('SIBU | Iniciando carga síncrona de Datos + GPS...');
|
console.log('SIB | Iniciando carga síncrona de Datos + GPS...');
|
||||||
|
|
||||||
const [ubicacionRes, paradasRes] = await Promise.allSettled([
|
const [ubicacionRes, paradasRes] = await Promise.allSettled([
|
||||||
obtenerUbicacion(),
|
obtenerUbicacion(),
|
||||||
@ -53,7 +53,7 @@ export const useFlujoPrincipal = () => {
|
|||||||
|
|
||||||
// Guard: abandono si el token fue cancelado o la ruta ya no está activa
|
// Guard: abandono si el token fue cancelado o la ruta ya no está activa
|
||||||
if (cancelToken?.cancelled || routeStore.selectedRouteId !== _ruta.id) {
|
if (cancelToken?.cancelled || routeStore.selectedRouteId !== _ruta.id) {
|
||||||
console.log('SIBU | procesarSeleccionDeRuta abortado tras Promise.allSettled (ruta ya no activa o cancelada)');
|
console.log('SIB | procesarSeleccionDeRuta abortado tras Promise.allSettled (ruta ya no activa o cancelada)');
|
||||||
limpiarMapa(); // limpiar cualquier polyline ya dibujada
|
limpiarMapa(); // limpiar cualquier polyline ya dibujada
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ export const useFlujoPrincipal = () => {
|
|||||||
if (ubicacionRes.status === 'fulfilled') {
|
if (ubicacionRes.status === 'fulfilled') {
|
||||||
ubicacion = ubicacionRes.value;
|
ubicacion = ubicacionRes.value;
|
||||||
} else {
|
} else {
|
||||||
console.warn('SIBU | GPS falló o fue denegado');
|
console.warn('SIB | GPS falló o fue denegado');
|
||||||
}
|
}
|
||||||
|
|
||||||
let paradas: BusStop[] = [];
|
let paradas: BusStop[] = [];
|
||||||
@ -81,7 +81,7 @@ export const useFlujoPrincipal = () => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
if (paradasFormateadas.length < 2) {
|
if (paradasFormateadas.length < 2) {
|
||||||
console.warn('SIBU | No hay suficientes paradas para trazar ruta');
|
console.warn('SIB | No hay suficientes paradas para trazar ruta');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ export const useFlujoPrincipal = () => {
|
|||||||
hacerZoomAlTramoRelevante(ubicacion, paradaCercanaFound, map)
|
hacerZoomAlTramoRelevante(ubicacion, paradaCercanaFound, map)
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('SIBU | Error procesando ruta:', error)
|
console.error('SIB | Error procesando ruta:', error)
|
||||||
errorMsg.value = 'No se pudo cargar la ruta'
|
errorMsg.value = 'No se pudo cargar la ruta'
|
||||||
} finally {
|
} finally {
|
||||||
// Apagar estado de carga
|
// Apagar estado de carga
|
||||||
|
|||||||
@ -76,7 +76,7 @@
|
|||||||
"details": "View details →"
|
"details": "View details →"
|
||||||
},
|
},
|
||||||
"header": {
|
"header": {
|
||||||
"title": "SIBU",
|
"title": "SIB",
|
||||||
"switchToLightMode": "Switch to light mode",
|
"switchToLightMode": "Switch to light mode",
|
||||||
"switchToDarkMode": "Switch to dark mode"
|
"switchToDarkMode": "Switch to dark mode"
|
||||||
},
|
},
|
||||||
@ -285,7 +285,7 @@
|
|||||||
"title": "Profile",
|
"title": "Profile",
|
||||||
"myCoupons": "My Coupons",
|
"myCoupons": "My Coupons",
|
||||||
"emptyCoupons": "You don't have any coupons",
|
"emptyCoupons": "You don't have any coupons",
|
||||||
"exploreOffers": "Explore the benefits we have for you for using SIBU.",
|
"exploreOffers": "Explore the benefits we have for you for using SIB.",
|
||||||
"viewOffers": "View Offers",
|
"viewOffers": "View Offers",
|
||||||
"viewCode": "View Code",
|
"viewCode": "View Code",
|
||||||
"usedAt": "Used on:",
|
"usedAt": "Used on:",
|
||||||
@ -318,7 +318,7 @@
|
|||||||
"loginTab": "Login",
|
"loginTab": "Login",
|
||||||
"registerTab": "Create Account",
|
"registerTab": "Create Account",
|
||||||
"sessionExpired": "Your session has expired. Please log in again.",
|
"sessionExpired": "Your session has expired. Please log in again.",
|
||||||
"footer": "SIBU © 2026 • Chiriquí Transport System",
|
"footer": "SIB © 2026 • Chiriquí Transport System",
|
||||||
"googleLogin": "Continue with Google",
|
"googleLogin": "Continue with Google",
|
||||||
"googleRegister": "Sign up with Google",
|
"googleRegister": "Sign up with Google",
|
||||||
"orEmail": "or with email",
|
"orEmail": "or with email",
|
||||||
@ -362,7 +362,7 @@
|
|||||||
},
|
},
|
||||||
"splash": {
|
"splash": {
|
||||||
"subtitle": "Boquete Public Transport",
|
"subtitle": "Boquete Public Transport",
|
||||||
"starting": "Starting SIBU...",
|
"starting": "Starting SIB...",
|
||||||
"offline": "Starting offline mode...",
|
"offline": "Starting offline mode...",
|
||||||
"verifying": "Verifying data...",
|
"verifying": "Verifying data...",
|
||||||
"ready": "Ready to use"
|
"ready": "Ready to use"
|
||||||
|
|||||||
@ -77,7 +77,7 @@
|
|||||||
"details": "Ver detalles →"
|
"details": "Ver detalles →"
|
||||||
},
|
},
|
||||||
"header": {
|
"header": {
|
||||||
"title": "SIBU",
|
"title": "SIB",
|
||||||
"switchToLightMode": "Cambiar a modo claro",
|
"switchToLightMode": "Cambiar a modo claro",
|
||||||
"switchToDarkMode": "Cambiar a modo oscuro"
|
"switchToDarkMode": "Cambiar a modo oscuro"
|
||||||
},
|
},
|
||||||
@ -289,7 +289,7 @@
|
|||||||
"title": "Perfil",
|
"title": "Perfil",
|
||||||
"myCoupons": "Mis Cupones",
|
"myCoupons": "Mis Cupones",
|
||||||
"emptyCoupons": "No tienes cupones",
|
"emptyCoupons": "No tienes cupones",
|
||||||
"exploreOffers": "Explora los beneficios que tenemos para ti por usar SIBU.",
|
"exploreOffers": "Explora los beneficios que tenemos para ti por usar SIB.",
|
||||||
"viewOffers": "Ver Ofertas",
|
"viewOffers": "Ver Ofertas",
|
||||||
"viewCode": "Ver Código",
|
"viewCode": "Ver Código",
|
||||||
"usedAt": "Usado el:",
|
"usedAt": "Usado el:",
|
||||||
@ -322,7 +322,7 @@
|
|||||||
"loginTab": "Iniciar Sesión",
|
"loginTab": "Iniciar Sesión",
|
||||||
"registerTab": "Crear Cuenta",
|
"registerTab": "Crear Cuenta",
|
||||||
"sessionExpired": "Tu sesión ha expirado. Por favor, inicia sesión nuevamente.",
|
"sessionExpired": "Tu sesión ha expirado. Por favor, inicia sesión nuevamente.",
|
||||||
"footer": "SIBU © 2026 • Sistema de Transporte de Chiriquí",
|
"footer": "SIB © 2026 • Sistema de Transporte de Chiriquí",
|
||||||
"googleLogin": "Continuar con Google",
|
"googleLogin": "Continuar con Google",
|
||||||
"googleRegister": "Registrarse con Google",
|
"googleRegister": "Registrarse con Google",
|
||||||
"orEmail": "o con correo",
|
"orEmail": "o con correo",
|
||||||
@ -366,7 +366,7 @@
|
|||||||
},
|
},
|
||||||
"splash": {
|
"splash": {
|
||||||
"subtitle": "Transporte Público Boquete",
|
"subtitle": "Transporte Público Boquete",
|
||||||
"starting": "Iniciando SIBU...",
|
"starting": "Iniciando SIB...",
|
||||||
"offline": "Iniciando modo sin conexión...",
|
"offline": "Iniciando modo sin conexión...",
|
||||||
"verifying": "Verificando datos...",
|
"verifying": "Verificando datos...",
|
||||||
"ready": "Listo para usar"
|
"ready": "Listo para usar"
|
||||||
|
|||||||
@ -140,7 +140,7 @@ export const useAuthStore = defineStore('auth', () => {
|
|||||||
if (!error) {
|
if (!error) {
|
||||||
userProfile.value = { ...userProfile.value, ...updates }
|
userProfile.value = { ...userProfile.value, ...updates }
|
||||||
} else {
|
} else {
|
||||||
console.error('SIBU | Error al actualizar perfil:', error)
|
console.error('SIB | Error al actualizar perfil:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@ export const useFavoritesStore = defineStore('favorites', () => {
|
|||||||
// Safety: si la red está inestable al awakening del background, no quedar cargando
|
// Safety: si la red está inestable al awakening del background, no quedar cargando
|
||||||
const safetyTimer = setTimeout(() => {
|
const safetyTimer = setTimeout(() => {
|
||||||
if (isLoading.value) {
|
if (isLoading.value) {
|
||||||
console.warn('SIBU | favoritesStore: safety timeout — reseteando isLoading')
|
console.warn('SIB | favoritesStore: safety timeout — reseteando isLoading')
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
}, 12000)
|
}, 12000)
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export const useRouteStore = defineStore('route', () => {
|
|||||||
if (_routesSafetyTimer) clearTimeout(_routesSafetyTimer)
|
if (_routesSafetyTimer) clearTimeout(_routesSafetyTimer)
|
||||||
_routesSafetyTimer = setTimeout(() => {
|
_routesSafetyTimer = setTimeout(() => {
|
||||||
if (isLoadingRoutes.value) {
|
if (isLoadingRoutes.value) {
|
||||||
console.warn('SIBU | routeStore: routes safety timeout — reseteando isLoadingRoutes')
|
console.warn('SIB | routeStore: routes safety timeout — reseteando isLoadingRoutes')
|
||||||
isLoadingRoutes.value = false
|
isLoadingRoutes.value = false
|
||||||
}
|
}
|
||||||
}, 12000)
|
}, 12000)
|
||||||
@ -34,7 +34,7 @@ export const useRouteStore = defineStore('route', () => {
|
|||||||
if (_stopsSafetyTimer) clearTimeout(_stopsSafetyTimer)
|
if (_stopsSafetyTimer) clearTimeout(_stopsSafetyTimer)
|
||||||
_stopsSafetyTimer = setTimeout(() => {
|
_stopsSafetyTimer = setTimeout(() => {
|
||||||
if (isLoadingStops.value) {
|
if (isLoadingStops.value) {
|
||||||
console.warn('SIBU | routeStore: stops safety timeout — reseteando isLoadingStops')
|
console.warn('SIB | routeStore: stops safety timeout — reseteando isLoadingStops')
|
||||||
isLoadingStops.value = false
|
isLoadingStops.value = false
|
||||||
}
|
}
|
||||||
}, 12000)
|
}, 12000)
|
||||||
|
|||||||
@ -15,7 +15,7 @@ export const useScheduleStore = defineStore('schedule', () => {
|
|||||||
_clearSafetyTimer()
|
_clearSafetyTimer()
|
||||||
_safetyTimer = setTimeout(() => {
|
_safetyTimer = setTimeout(() => {
|
||||||
if (isLoading.value) {
|
if (isLoading.value) {
|
||||||
console.warn('SIBU | scheduleStore: safety timeout — reseteando isLoading')
|
console.warn('SIB | scheduleStore: safety timeout — reseteando isLoading')
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
}, 12000)
|
}, 12000)
|
||||||
|
|||||||
@ -16,7 +16,7 @@ export const useShuttleStore = defineStore('shuttle', () => {
|
|||||||
_clearSafetyTimer()
|
_clearSafetyTimer()
|
||||||
_safetyTimer = setTimeout(() => {
|
_safetyTimer = setTimeout(() => {
|
||||||
if (isLoading.value) {
|
if (isLoading.value) {
|
||||||
console.warn('SIBU | shuttleStore: safety timeout — reseteando isLoading')
|
console.warn('SIB | shuttleStore: safety timeout — reseteando isLoading')
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
}, 12000)
|
}, 12000)
|
||||||
|
|||||||
@ -16,7 +16,7 @@ export const useTaxiStore = defineStore('taxi', () => {
|
|||||||
_clearSafetyTimer()
|
_clearSafetyTimer()
|
||||||
_safetyTimer = setTimeout(() => {
|
_safetyTimer = setTimeout(() => {
|
||||||
if (isLoading.value) {
|
if (isLoading.value) {
|
||||||
console.warn('SIBU | taxiStore: safety timeout — reseteando isLoading')
|
console.warn('SIB | taxiStore: safety timeout — reseteando isLoading')
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
}, 12000)
|
}, 12000)
|
||||||
|
|||||||
@ -4,7 +4,7 @@ export const SUPABASE_URL = import.meta.env.VITE_SUPABASE_URL
|
|||||||
export const SUPABASE_ANON_KEY = import.meta.env.VITE_SUPABASE_ANON_KEY
|
export const SUPABASE_ANON_KEY = import.meta.env.VITE_SUPABASE_ANON_KEY
|
||||||
|
|
||||||
if (!SUPABASE_URL || !SUPABASE_ANON_KEY) {
|
if (!SUPABASE_URL || !SUPABASE_ANON_KEY) {
|
||||||
const errorMsg = 'SIBU | ERROR: Credenciales de Supabase no encontradas en las variables de entorno (.env).'
|
const errorMsg = 'SIB | ERROR: Credenciales de Supabase no encontradas en las variables de entorno (.env).'
|
||||||
console.error(errorMsg, {
|
console.error(errorMsg, {
|
||||||
url: !!SUPABASE_URL,
|
url: !!SUPABASE_URL,
|
||||||
key: !!SUPABASE_ANON_KEY
|
key: !!SUPABASE_ANON_KEY
|
||||||
@ -15,7 +15,7 @@ if (!SUPABASE_URL || !SUPABASE_ANON_KEY) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SIBU | Hybrid Storage: Maneja persistencia según la voluntad del usuario
|
// SIB | Hybrid Storage: Maneja persistencia según la voluntad del usuario
|
||||||
const authStorage = {
|
const authStorage = {
|
||||||
getItem: (key: string) => localStorage.getItem(key) || sessionStorage.getItem(key),
|
getItem: (key: string) => localStorage.getItem(key) || sessionStorage.getItem(key),
|
||||||
setItem: (key: string, val: string) => {
|
setItem: (key: string, val: string) => {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
/** Type definitions for the SIBU transportation app */
|
/** Type definitions for the SIB transportation app */
|
||||||
|
|
||||||
export type RouteStatus = 'ACTIVE' | 'INACTIVE' | 'MAINTENANCE'
|
export type RouteStatus = 'ACTIVE' | 'INACTIVE' | 'MAINTENANCE'
|
||||||
export type StopType = 'TERMINAL' | 'REGULAR' | 'EXPRESS_ONLY'
|
export type StopType = 'TERMINAL' | 'REGULAR' | 'EXPRESS_ONLY'
|
||||||
|
|||||||
@ -14,7 +14,7 @@ export function getImageUrl(path?: string | null, type: 'taxi' | 'shuttle' | 'bu
|
|||||||
business: 'Negocio',
|
business: 'Negocio',
|
||||||
coupon: 'Oferta'
|
coupon: 'Oferta'
|
||||||
}
|
}
|
||||||
const name = defaultNames[type] || 'SIBU'
|
const name = defaultNames[type] || 'SIB'
|
||||||
return `https://ui-avatars.com/api/?name=${name}&background=fee715&color=101820&size=256&bold=true`
|
return `https://ui-avatars.com/api/?name=${name}&background=fee715&color=101820&size=256&bold=true`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<div class="header-section">
|
<div class="header-section">
|
||||||
<div class="badge">SISTEMA CENTRAL</div>
|
<div class="badge">SISTEMA CENTRAL</div>
|
||||||
<h1>Panel de Control</h1>
|
<h1>Panel de Control</h1>
|
||||||
<p class="subtitle">Ecosistema Administrativo SIBU</p>
|
<p class="subtitle">Ecosistema Administrativo SIB</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="dashboard-sections">
|
<div class="dashboard-sections">
|
||||||
|
|||||||
@ -223,7 +223,7 @@ async function saveShuttle() {
|
|||||||
|
|
||||||
<button class="deploy-btn" :disabled="isLoading" @click="saveShuttle">
|
<button class="deploy-btn" :disabled="isLoading" @click="saveShuttle">
|
||||||
<span class="material-icons">{{ isLoading ? 'sync' : 'rocket_launch' }}</span>
|
<span class="material-icons">{{ isLoading ? 'sync' : 'rocket_launch' }}</span>
|
||||||
{{ isLoading ? 'PROCESANDO...' : 'PUBLICAR EN SIBU' }}
|
{{ isLoading ? 'PROCESANDO...' : 'PUBLICAR EN SIB' }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<p v-if="showMessage.text" :class="['message', showMessage.type]">{{ showMessage.text }}</p>
|
<p v-if="showMessage.text" :class="['message', showMessage.type]">{{ showMessage.text }}</p>
|
||||||
|
|||||||
@ -45,8 +45,8 @@ const toggleAuth = () => {
|
|||||||
<div class="auth-content-grid">
|
<div class="auth-content-grid">
|
||||||
<!-- Branding Side (Desktop only) -->
|
<!-- Branding Side (Desktop only) -->
|
||||||
<div class="branding-section">
|
<div class="branding-section">
|
||||||
<img src="/sibu.png" alt="SIBU Logo" class="brand-logo" />
|
<img src="/sib.png" alt="SIB Logo" class="brand-logo" />
|
||||||
<h1 class="brand-title">SIBU</h1>
|
<h1 class="brand-title">SIB</h1>
|
||||||
<p class="brand-tagline">{{ t('auth.brandingSubtitle') }}</p>
|
<p class="brand-tagline">{{ t('auth.brandingSubtitle') }}</p>
|
||||||
<div class="brand-features">
|
<div class="brand-features">
|
||||||
<div class="feature-item">
|
<div class="feature-item">
|
||||||
@ -69,7 +69,7 @@ const toggleAuth = () => {
|
|||||||
<div class="glass-card auth-card">
|
<div class="glass-card auth-card">
|
||||||
<!-- Mobile Logo -->
|
<!-- Mobile Logo -->
|
||||||
<div class="mobile-header">
|
<div class="mobile-header">
|
||||||
<img src="/sibu.png" alt="SIBU Logo" class="mobile-logo" />
|
<img src="/sib.png" alt="SIB Logo" class="mobile-logo" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tab Selector -->
|
<!-- Tab Selector -->
|
||||||
|
|||||||
@ -174,7 +174,7 @@ async function handleRefocus() {
|
|||||||
updateActiveUnits();
|
updateActiveUnits();
|
||||||
} else {
|
} else {
|
||||||
// El mapa fue destruido por el browser al suspender la pestaña — reinicializar
|
// El mapa fue destruido por el browser al suspender la pestaña — reinicializar
|
||||||
console.log('SIBU | Mapa perdido tras refocus, reinicializando...');
|
console.log('SIB | Mapa perdido tras refocus, reinicializando...');
|
||||||
if (isLoaded.value) {
|
if (isLoaded.value) {
|
||||||
await initializeMap();
|
await initializeMap();
|
||||||
} else {
|
} else {
|
||||||
@ -450,7 +450,7 @@ function locateUser(): Promise<void> {
|
|||||||
resolve();
|
resolve();
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
console.error('SIBU | Error obteniendo ubicación:', error);
|
console.error('SIB | Error obteniendo ubicación:', error);
|
||||||
// Si falló por falta de permisos o error y el usuario tenía auto_location activo,
|
// Si falló por falta de permisos o error y el usuario tenía auto_location activo,
|
||||||
// lo desactivamos para no re-intentar infinitamente
|
// lo desactivamos para no re-intentar infinitamente
|
||||||
if (authStore.userProfile?.auto_location) {
|
if (authStore.userProfile?.auto_location) {
|
||||||
@ -504,7 +504,7 @@ watch([etaCargando, () => busesActivos.value.length], ([loading, count]) => {
|
|||||||
if (showETACard.value && busesActivos.value.length === 0 && routeStore.selectedRouteId) {
|
if (showETACard.value && busesActivos.value.length === 0 && routeStore.selectedRouteId) {
|
||||||
routeStore.clearSelection();
|
routeStore.clearSelection();
|
||||||
router.replace({ query: {} });
|
router.replace({ query: {} });
|
||||||
console.log("SIBU | Ruta autolimpiada por falta de buses");
|
console.log("SIB | Ruta autolimpiada por falta de buses");
|
||||||
}
|
}
|
||||||
}, 300);
|
}, 300);
|
||||||
}
|
}
|
||||||
@ -566,7 +566,7 @@ watch([() => authStore.userProfile?.auto_location, isLoaded], ([canLocate, loade
|
|||||||
// Extra guard: no re-disparar si auto_location no cambió (solo isLoaded cambió)
|
// Extra guard: no re-disparar si auto_location no cambió (solo isLoaded cambió)
|
||||||
// Esto previene relocalización innecesaria al volver del background
|
// Esto previene relocalización innecesaria al volver del background
|
||||||
if (prevCanLocate !== undefined || !userCoords.value) {
|
if (prevCanLocate !== undefined || !userCoords.value) {
|
||||||
console.log('SIBU | Iniciando geolocalización automática...');
|
console.log('SIB | Iniciando geolocalización automática...');
|
||||||
locateUser();
|
locateUser();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,7 +85,7 @@ const correlimientos = computed(() => {
|
|||||||
<button @click="router.back()" class="size-10 flex items-center justify-center rounded-full bg-slate-100 dark:bg-card-dark text-slate-600 dark:text-gray-300 active:scale-95 transition-transform">
|
<button @click="router.back()" class="size-10 flex items-center justify-center rounded-full bg-slate-100 dark:bg-card-dark text-slate-600 dark:text-gray-300 active:scale-95 transition-transform">
|
||||||
<span class="material-icons text-[20px]">arrow_back</span>
|
<span class="material-icons text-[20px]">arrow_back</span>
|
||||||
</button>
|
</button>
|
||||||
<h1 class="text-xl font-extrabold tracking-tight text-primary uppercase italic">SIBU</h1>
|
<h1 class="text-xl font-extrabold tracking-tight text-primary uppercase italic">SIB</h1>
|
||||||
<div class="size-10"></div>
|
<div class="size-10"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ const routeStore = useRouteStore()
|
|||||||
const dropdownOpen = ref(false)
|
const dropdownOpen = ref(false)
|
||||||
const dayFilter = ref<'all' | 'today' | 'tomorrow'>('today')
|
const dayFilter = ref<'all' | 'today' | 'tomorrow'>('today')
|
||||||
|
|
||||||
// SIBU | Estado local para independizar el selector de horarios del mapa
|
// SIB | Estado local para independizar el selector de horarios del mapa
|
||||||
const localSelectedRouteId = ref<string | null>(null)
|
const localSelectedRouteId = ref<string | null>(null)
|
||||||
const localSelectedRouteName = ref<string | null>(null)
|
const localSelectedRouteName = ref<string | null>(null)
|
||||||
const hasLocalSelection = computed(() => localSelectedRouteId.value !== null)
|
const hasLocalSelection = computed(() => localSelectedRouteId.value !== null)
|
||||||
@ -132,7 +132,7 @@ function pickRoute(id: string, name: string) {
|
|||||||
properties: { route_id: id }
|
properties: { route_id: id }
|
||||||
})
|
})
|
||||||
|
|
||||||
// SIBU | Solo actualizamos estado local (Independiente del mapa)
|
// SIB | Solo actualizamos estado local (Independiente del mapa)
|
||||||
localSelectedRouteId.value = id
|
localSelectedRouteId.value = id
|
||||||
localSelectedRouteName.value = name
|
localSelectedRouteName.value = name
|
||||||
scheduleStore.loadRouteSchedules(id)
|
scheduleStore.loadRouteSchedules(id)
|
||||||
@ -170,7 +170,7 @@ onMounted(async () => {
|
|||||||
const found = routeStore.allRoutes.find(r => r.id === queryRouteId)
|
const found = routeStore.allRoutes.find(r => r.id === queryRouteId)
|
||||||
if (found) pickRoute(found.id, found.name)
|
if (found) pickRoute(found.id, found.name)
|
||||||
} else if (routeStore.selectedRouteId) {
|
} else if (routeStore.selectedRouteId) {
|
||||||
// SIBU | Inicializamos con la ruta del mapa, pero a partir de aquí son independientes
|
// SIB | Inicializamos con la ruta del mapa, pero a partir de aquí son independientes
|
||||||
const mapRoute = routeStore.allRoutes.find(r => r.id === routeStore.selectedRouteId)
|
const mapRoute = routeStore.allRoutes.find(r => r.id === routeStore.selectedRouteId)
|
||||||
if (mapRoute) {
|
if (mapRoute) {
|
||||||
localSelectedRouteId.value = mapRoute.id
|
localSelectedRouteId.value = mapRoute.id
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<!-- Logo with animation -->
|
<!-- Logo with animation -->
|
||||||
<div class="logo-container" :class="{ 'logo-visible': logoVisible }">
|
<div class="logo-container" :class="{ 'logo-visible': logoVisible }">
|
||||||
<div class="logo-box">
|
<div class="logo-box">
|
||||||
<img src="/icon-192.png" alt="SIBU" class="logo-icon" />
|
<img src="/icon-192.png" alt="SIB" class="logo-icon" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
<div class="badge">INTELIGENCIA ESTRATÉGICA</div>
|
<div class="badge">INTELIGENCIA ESTRATÉGICA</div>
|
||||||
</div>
|
</div>
|
||||||
<h1>Centro de Operaciones</h1>
|
<h1>Centro de Operaciones</h1>
|
||||||
<p class="subtitle">Análisis segmentado de rendimiento SIBU</p>
|
<p class="subtitle">Análisis segmentado de rendimiento SIB</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- TACTICAL TAB SELECTOR -->
|
<!-- TACTICAL TAB SELECTOR -->
|
||||||
@ -299,7 +299,7 @@
|
|||||||
<div class="info-box">
|
<div class="info-box">
|
||||||
<span class="material-icons">shopping_bag</span>
|
<span class="material-icons">shopping_bag</span>
|
||||||
<h4>Retorno Comercial</h4>
|
<h4>Retorno Comercial</h4>
|
||||||
<p>Analice qué negocios están monetizando mejor el tráfico de SIBU. Use estos datos para ofrecer espacios publicitarios premium a los negocios con salud 'Baja'.</p>
|
<p>Analice qué negocios están monetizando mejor el tráfico de SIB. Use estos datos para ofrecer espacios publicitarios premium a los negocios con salud 'Baja'.</p>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
@ -354,7 +354,7 @@ const generateReport = async () => {
|
|||||||
doc.setTextColor(254, 231, 21); // Amarillo Activo
|
doc.setTextColor(254, 231, 21); // Amarillo Activo
|
||||||
doc.setFontSize(22);
|
doc.setFontSize(22);
|
||||||
doc.setFont('helvetica', 'bold');
|
doc.setFont('helvetica', 'bold');
|
||||||
doc.text('SIBU COMMAND CENTER', 15, 20);
|
doc.text('SIB COMMAND CENTER', 15, 20);
|
||||||
|
|
||||||
doc.setTextColor(255, 255, 255);
|
doc.setTextColor(255, 255, 255);
|
||||||
doc.setFontSize(10);
|
doc.setFontSize(10);
|
||||||
@ -432,10 +432,10 @@ const generateReport = async () => {
|
|||||||
doc.setPage(i);
|
doc.setPage(i);
|
||||||
doc.setFontSize(8);
|
doc.setFontSize(8);
|
||||||
doc.setTextColor(150);
|
doc.setTextColor(150);
|
||||||
doc.text(`SIBU Command Center - Página ${i} de ${totalPages} - Confidencial Admin`, pageWidth / 2, 285, { align: 'center' });
|
doc.text(`SIB Command Center - Página ${i} de ${totalPages} - Confidencial Admin`, pageWidth / 2, 285, { align: 'center' });
|
||||||
}
|
}
|
||||||
|
|
||||||
doc.save(`Informe_Estrategico_SIBU_${date.replace(/ /g, '_')}.pdf`);
|
doc.save(`Informe_Estrategico_SIB_${date.replace(/ /g, '_')}.pdf`);
|
||||||
};
|
};
|
||||||
|
|
||||||
// CHARTS CONFIGURATION (MISMOS DATOS QUE ANTES)
|
// CHARTS CONFIGURATION (MISMOS DATOS QUE ANTES)
|
||||||
|
|||||||
Reference in New Issue
Block a user