fix(eta): update to 12h format and ensure ETA always shows in minutes (e.g., 70 min)

This commit is contained in:
2026-03-07 22:18:37 -05:00
parent f2e96c4cdf
commit 999cd75c11
4 changed files with 33 additions and 10 deletions

View File

@ -23,7 +23,7 @@
<div class="eta-loader"></div>
</template>
<template v-else-if="hasActiveBuses">
<span class="eta-value">{{ etaValue }}</span>
<span class="eta-value">{{ typeof etaValue === 'number' ? formatDurationMinutes(etaValue) : etaValue }}</span>
<span class="eta-unit">min</span>
</template>
</div>
@ -41,6 +41,7 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { formatDurationMinutes } from '@/utils/durationFormatter'
const props = defineProps<{
isVisible: boolean

View File

@ -104,7 +104,7 @@
<div class="flex flex-col items-end text-right shrink-0 ml-4">
<!-- ETA gigante -->
<div v-if="bus.estado !== 'pasó'" class="text-2xl font-black text-gray-900 dark:text-white flex items-baseline gap-1" :class="{ 'text-green-600 dark:text-green-400': bus.estado === 'en_camino' }">
<span>~{{ bus.etaMinutos }}</span>
<span>~{{ formatDurationMinutes(bus.etaMinutos) }}</span>
<span class="text-sm font-bold text-gray-500 dark:text-gray-400">min</span>
</div>
@ -143,6 +143,7 @@
import { ref, onMounted, onUnmounted } from 'vue';
import { useI18n } from 'vue-i18n';
import type { BusETA } from '@/composables/useETA';
import { formatDurationMinutes } from '@/utils/durationFormatter';
const { t } = useI18n();

View File

@ -126,10 +126,21 @@ export function useETA() {
const [hStr, mStr] = salida.split(':');
const minutosSalida = parseInt(hStr) * 60 + parseInt(mStr);
const minutosLlegadaParada = minutosSalida + minutosHastaParada;
const etaMinutos = minutosLlegadaParada - minutosAhora;
const horaLlegada = minutosAHora(minutosLlegadaParada);
const horaSalidaFormato = `${hStr.padStart(2, '0')}:${mStr.padStart(2, '0')}`;
// 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 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 horaLlegada = format12h(minutosLlegadaEstablecidos);
const horaSalidaFormato = format12h(minutosSalida);
let estado: BusETA['estado'];
if (etaMinutos > 5) {
@ -165,13 +176,15 @@ export function useETA() {
}
};
// Helper: convierte minutos desde medianoche a "HH:mm"
function minutosAHora(minutos: number): string {
// Helper: convierte minutos desde medianoche a formato 12h (hh:mm am/pm)
function format12h(minutos: number): string {
const totalMinutes = Math.round(minutos);
const m = ((totalMinutes % 1440) + 1440) % 1440; // normalizar 0-1439
const h = Math.floor(m / 60);
let h = Math.floor(m / 60);
const min = Math.floor(m % 60);
return `${String(h).padStart(2, '0')}:${String(min).padStart(2, '0')}`;
const ampm = h >= 12 ? 'PM' : 'AM';
const h12 = h % 12 || 12;
return `${h12}:${String(min).padStart(2, '0')} ${ampm}`;
}
return { calcularETA, busesActivos, cargando };

View File

@ -0,0 +1,8 @@
/**
* Formats a duration in minutes to a human-readable string.
* It will always show minutes, even if it's more than 60, e.g., "70 min".
*/
export function formatDurationMinutes(minutes: number): string {
const rounded = Math.round(minutes);
return `${rounded}`;
}