UI: Refine 'no buses available' flow and fix decimal bug

This commit is contained in:
2026-03-01 22:06:42 -05:00
parent e0284f7518
commit fa8551b19d
3 changed files with 28 additions and 11 deletions

View File

@ -27,8 +27,8 @@
Desliza hacia abajo para cerrar Desliza hacia abajo para cerrar
</p> </p>
<!-- Cabecera de la parada --> <!-- Cabecera de la parada (Ocultar si no hay buses para modo minimalista) -->
<div class="mt-4 flex items-start gap-4 pb-4 border-b border-gray-100 dark:border-gray-800"> <div v-if="buses.length > 0" class="mt-4 flex items-start gap-4 pb-4 border-b border-gray-100 dark:border-gray-800">
<div class="bg-blue-100 dark:bg-blue-900/40 p-3 rounded-2xl flex-shrink-0"> <div class="bg-blue-100 dark:bg-blue-900/40 p-3 rounded-2xl flex-shrink-0">
<span class="material-icons text-blue-600 dark:text-blue-400 text-3xl">place</span> <span class="material-icons text-blue-600 dark:text-blue-400 text-3xl">place</span>
</div> </div>
@ -54,11 +54,17 @@
<span class="mt-4 text-gray-500 dark:text-gray-400 font-medium animate-pulse">Calculando satélites...</span> <span class="mt-4 text-gray-500 dark:text-gray-400 font-medium animate-pulse">Calculando satélites...</span>
</div> </div>
<!-- Sin servicio --> <!-- Sin servicio (Actualizado según petición) -->
<div v-else-if="buses.length === 0" class="bg-gray-50 dark:bg-gray-800/50 rounded-2xl p-6 text-center border dashed border-gray-200 dark:border-gray-700"> <div v-else-if="buses.length === 0" class="bg-gray-50 dark:bg-gray-800/50 rounded-2xl p-8 text-center border-2 border-dashed border-gray-300 dark:border-gray-700 my-4">
<span class="material-icons text-4xl text-gray-400 mb-2">directions_bus</span> <div class="w-16 h-16 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center mx-auto mb-4">
<h4 class="text-gray-700 dark:text-gray-300 font-bold mb-1">Sin servicio programado</h4> <span class="material-icons text-4xl text-gray-400">no_bus</span>
<p class="text-sm text-gray-500 dark:text-gray-400">No hay buses en ruta para hoy en esta línea.</p> </div>
<h4 class="text-gray-900 dark:text-white font-black text-lg mb-2">
{{ t('map.noBusesAvailable') }}
</h4>
<p class="text-sm text-gray-500 dark:text-gray-400">
{{ t('schedules.noSchedules') }}
</p>
</div> </div>
<!-- Lista de llegadas (Max 2) --> <!-- Lista de llegadas (Max 2) -->
@ -125,8 +131,8 @@
</template> </template>
</div> </div>
<!-- Legal Disclaimer Intocable --> <!-- Legal Disclaimer Intocable (Solo si hay buses) -->
<div class="mt-2 p-3 bg-yellow-50 dark:bg-yellow-900/20 rounded-xl flex items-start gap-3 border border-yellow-100 dark:border-yellow-900/50"> <div v-if="buses.length > 0" class="mt-2 p-3 bg-yellow-50 dark:bg-yellow-900/20 rounded-xl flex items-start gap-3 border border-yellow-100 dark:border-yellow-900/50">
<span class="material-icons text-yellow-600 dark:text-yellow-500 text-lg mt-0.5 shrink-0">info</span> <span class="material-icons text-yellow-600 dark:text-yellow-500 text-lg mt-0.5 shrink-0">info</span>
<p class="text-[11px] leading-snug text-yellow-800 dark:text-yellow-600/90 font-medium"> <p class="text-[11px] leading-snug text-yellow-800 dark:text-yellow-600/90 font-medium">
<strong>Aviso:</strong> Este es un tiempo estimado basado en la velocidad promedio de las unidades en la ciudad. No existe rastreo GPS en tiempo real. <strong>Aviso:</strong> Este es un tiempo estimado basado en la velocidad promedio de las unidades en la ciudad. No existe rastreo GPS en tiempo real.
@ -140,8 +146,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'; import { ref, onMounted, onUnmounted } from 'vue';
import { useI18n } from 'vue-i18n';
import type { BusETA } from '@/composables/useETA'; import type { BusETA } from '@/composables/useETA';
const { t } = useI18n();
defineProps<{ defineProps<{
isOpen: boolean; isOpen: boolean;
stopName: string; stopName: string;

View File

@ -182,7 +182,8 @@ export function useETA() {
// Helper: convierte minutos desde medianoche a "HH:mm" // Helper: convierte minutos desde medianoche a "HH:mm"
function minutosAHora(minutos: number): string { function minutosAHora(minutos: number): string {
const m = ((minutos % 1440) + 1440) % 1440; // normalizar 0-1439 const totalMinutes = Math.round(minutos);
const m = ((totalMinutes % 1440) + 1440) % 1440; // normalizar 0-1439
const h = Math.floor(m / 60); const h = Math.floor(m / 60);
const min = m % 60; const min = m % 60;
return `${String(h).padStart(2, '0')}:${String(min).padStart(2, '0')}`; return `${String(h).padStart(2, '0')}:${String(min).padStart(2, '0')}`;

View File

@ -329,6 +329,13 @@ const sonarHtml = `
`; `;
// Watch for route selection changes // Watch for route selection changes
// Watch for ETA loading to automatically show ETACard if no buses are available
watch([etaCargando, () => busesActivos.value.length], ([loading, count]) => {
if (!loading && count === 0 && routeStore.selectedRouteId && routeStore.wasSelectedFromMap) {
showETACard.value = true;
}
});
watch(() => routeStore.selectedRouteId, (routeId) => { watch(() => routeStore.selectedRouteId, (routeId) => {
if (routeId) { if (routeId) {
if (routeStore.wasSelectedFromMap) { if (routeStore.wasSelectedFromMap) {
@ -393,7 +400,7 @@ function handleImageError(event: Event) {
> >
<template #extra-triggers> <template #extra-triggers>
<ArrivalBanner <ArrivalBanner
:is-visible="!!(paradaCercana && routeStore.selectedRouteId && !isBannerClosing && routeStore.wasSelectedFromMap)" :is-visible="!!(paradaCercana && routeStore.selectedRouteId && !isBannerClosing && routeStore.wasSelectedFromMap && busesActivos.length > 0)"
:stop-name="paradaCercana?.name || ''" :stop-name="paradaCercana?.name || ''"
:is-loading="etaCargando" :is-loading="etaCargando"
:has-active-buses="busesActivos.length > 0" :has-active-buses="busesActivos.length > 0"