diff --git a/frontend/src/components/BottomNav.vue b/frontend/src/components/BottomNav.vue
index db5e520..e06c027 100644
--- a/frontend/src/components/BottomNav.vue
+++ b/frontend/src/components/BottomNav.vue
@@ -15,11 +15,14 @@ const navItems = [
]
const isNavigating = ref(false)
+const optimisticActivePath = ref('')
const navigateTo = async (path: string) => {
- // Prevent rapid multiple navigations (debounce guard)
- if (isNavigating.value) return
if (route.path === path) return
+ if (isNavigating.value) return
+
+ // Instant visual feedback
+ optimisticActivePath.value = path
try {
isNavigating.value = true
@@ -28,13 +31,18 @@ const navigateTo = async (path: string) => {
if (e?.name !== 'NavigationDuplicated') {
console.error('SIBU | Error de navegación en el menú inferior:', e)
}
+ // Revert on error
+ optimisticActivePath.value = ''
} finally {
- // Add a small delay to prevent rapid double-taps
- setTimeout(() => { isNavigating.value = false }, 300)
+ // Ultra-short lock to avoid mechanical double-taps only
+ setTimeout(() => { isNavigating.value = false }, 50)
}
}
const isActive = (path: string) => {
+ if (optimisticActivePath.value) {
+ return optimisticActivePath.value === path
+ }
return route.path === path || route.path.startsWith(path + '/')
}
@@ -67,9 +75,8 @@ onUnmounted(() => {
v-for="item in navItems"
:key="item.name"
class="nav-item"
- :class="{ active: isActive(item.path), 'opacity-50 pointer-events-none': isNavigating }"
- @click.prevent="navigateTo(item.path)"
- @touchend.prevent="navigateTo(item.path)"
+ :class="{ active: isActive(item.path) }"
+ @click.stop="navigateTo(item.path)"
>
{{ item.icon }}
{{ t('navigation.' + item.name) }}