fix(favorites): adjust favorite button visibility and functionality

- removed favorite button from Discover cards

- added call button for taxis in Favorites view

- added favorite button in Shuttle details

- added Shuttles category in Favorites view
This commit is contained in:
2026-03-04 16:34:47 -05:00
parent ef5955cea2
commit 35e2a6d632
6 changed files with 94 additions and 31 deletions

View File

@ -3,6 +3,7 @@ import { ref, computed, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useFavoritesStore } from '@/stores/favorites'
import { useAuthStore } from '@/stores/auth'
import { useTaxiStore } from '@/stores/taxi'
import { useI18n } from 'vue-i18n'
import { getImageUrl as utilGetImageUrl } from '@/utils/imageUrl'
import LoadingBranded from '@/components/common/LoadingBranded.vue'
@ -11,11 +12,13 @@ const router = useRouter()
const { t } = useI18n()
const favoritesStore = useFavoritesStore()
const authStore = useAuthStore()
const taxiStore = useTaxiStore()
const selectedFilter = ref('all')
const filters = computed(() => [
{ key: 'all', label: t('common.all'), icon: 'star' },
{ key: 'routes', label: t('favorites.tabs.routes'), icon: 'directions_bus' },
{ key: 'shuttles', label: 'Viajes Turísticos', icon: 'airport_shuttle' },
{ key: 'taxis', label: t('favorites.tabs.taxis'), icon: 'local_taxi' },
{ key: 'businesses',label: t('favorites.tabs.businesses'), icon: 'store' },
{ key: 'coupons', label: t('favorites.tabs.coupons'), icon: 'confirmation_number' },
@ -28,11 +31,17 @@ watch(
(authenticated) => {
if (authenticated) {
favoritesStore.loadFavorites()
taxiStore.silentReload()
}
},
{ immediate: true }
)
function getTaxiPhone(id: string) {
const taxi = taxiStore.taxis.find(t => t.id === id)
return taxi?.phone_number || ''
}
function getImageUrl(path?: string) {
return utilGetImageUrl(path, 'business')
}
@ -44,10 +53,11 @@ async function removeFavorite(event: Event, itemType: string, itemId: string) {
function navigateToItem(item: any) {
if (item.item_type === 'route') router.push({ path: '/schedules', query: { routeId: item.item_id } })
else if (item.item_type === 'taxi') router.push('/taxi')
else if (item.item_type === 'taxi') router.push('/transporte/taxis')
else if (item.item_type === 'business') router.push('/business/' + item.item_id)
else if (item.item_type === 'coupon') router.push('/coupons')
else if (item.item_type === 'stop') router.push({ path: '/map', query: { stopId: item.item_id } })
else if (item.item_type === 'shuttle') router.push({ name: 'ShuttleDetalle', params: { id: item.item_id } })
}
const visibleRoutes = computed(() =>
@ -65,12 +75,15 @@ const visibleCoupons = computed(() =>
const visibleStops = computed(() =>
(selectedFilter.value === 'all' || selectedFilter.value === 'stops') ? favoritesStore.stops : []
)
const visibleShuttles = computed(() =>
(selectedFilter.value === 'all' || selectedFilter.value === 'shuttles') ? favoritesStore.shuttles : []
)
const totalFavorites = computed(() => favoritesStore.favorites.length)
const hasVisibleItems = computed(() =>
visibleRoutes.value.length + visibleTaxis.value.length +
visibleBusinesses.value.length + visibleCoupons.value.length +
visibleStops.value.length > 0
visibleStops.value.length + visibleShuttles.value.length > 0
)
</script>
@ -181,6 +194,15 @@ const hasVisibleItems = computed(() =>
<p class="card-name">{{ item.item_name }}</p>
<p class="card-sub">{{ t('favorites.availability') }}</p>
</div>
<a
v-if="getTaxiPhone(item.item_id)"
:href="'tel:' + getTaxiPhone(item.item_id)"
class="call-btn"
@click.stop
title="Llamar ahora"
>
<span class="material-icons">phone_in_talk</span>
</a>
<button class="heart-btn heart-btn--active" @click.stop="removeFavorite($event, item.item_type, item.item_id)" :title="t('favorites.removeTitle')">
<span class="material-icons">favorite</span>
</button>
@ -188,6 +210,33 @@ const hasVisibleItems = computed(() =>
</div>
</section>
<!-- SHUTTLES -->
<section v-if="visibleShuttles.length > 0" class="fav-section">
<div class="section-label">
<span class="material-icons">airport_shuttle</span>
<span>Viajes Turísticos</span>
</div>
<div class="card-list">
<div
v-for="item in visibleShuttles"
:key="item.id"
class="card card--row"
@click="navigateToItem(item)"
>
<div class="card-thumb card-thumb--img">
<img :src="getImageUrl(item.item_image)" :alt="item.item_name" />
</div>
<div class="card-info">
<p class="card-name">{{ item.item_name }}</p>
<p class="card-sub">Ver detalles</p>
</div>
<button class="heart-btn heart-btn--active" @click.stop="removeFavorite($event, item.item_type, item.item_id)">
<span class="material-icons">favorite</span>
</button>
</div>
</div>
</section>
<!-- NEGOCIOS -->
<section v-if="visibleBusinesses.length > 0" class="fav-section">
<div class="section-label">
@ -524,6 +573,32 @@ const hasVisibleItems = computed(() =>
transform: scale(1.1);
}
.call-btn {
background: var(--active-color);
border: none;
width: 38px;
height: 38px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #101820;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
flex-shrink: 0;
margin-right: -4px;
}
.call-btn:hover {
transform: scale(1.1);
box-shadow: 0 4px 15px rgba(254, 231, 21, 0.3);
}
.call-btn .material-icons {
font-size: 20px;
}
.heart-btn--overlay {
position: absolute;
top: 0.5rem;