Rename system to SIB: update translations, logos, views, stores and logs

This commit is contained in:
2026-03-09 12:19:37 -05:00
parent 027cb80aec
commit d5763cd6d6
25 changed files with 66 additions and 74 deletions

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -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)
} }
} }

View File

@ -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;

View File

@ -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 -->

View File

@ -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;
} }

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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)
} }
} }

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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) => {

View File

@ -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'

View File

@ -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`
} }

View File

@ -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">

View File

@ -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>

View File

@ -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 -->

View File

@ -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();
} }
} }

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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)