fix: decouple map search from global selection and fix offers anchoring/masking

This commit is contained in:
2026-02-28 22:01:16 -05:00
parent 147ea98cda
commit 69fbe3dcbc

View File

@ -50,6 +50,7 @@ const optimalStopPulse = ref<any>(null);
const showRouteDropdown = ref(false); const showRouteDropdown = ref(false);
const routeCardRef = ref<HTMLElement | null>(null); const routeCardRef = ref<HTMLElement | null>(null);
const mappingSequenceId = ref(0); const mappingSequenceId = ref(0);
const wasSelectedFromMap = ref(false);
const alturaNavbar = ref(64); const alturaNavbar = ref(64);
// Search state // Search state
@ -276,6 +277,7 @@ watch(
} else { } else {
// Clear markers when no route is selected // Clear markers when no route is selected
lastProcessedRouteId.value = null; lastProcessedRouteId.value = null;
wasSelectedFromMap.value = false; // Reset selection origin
clearMapMarkers(); clearMapMarkers();
} }
}, },
@ -393,6 +395,7 @@ async function updatePromoMarkers() {
async function selectRouteAndClose(routeId: string, routeName: string) { async function selectRouteAndClose(routeId: string, routeName: string) {
console.log(`🤖 JARVIS: Iniciando viaje hacia ${routeName}`); console.log(`🤖 JARVIS: Iniciando viaje hacia ${routeName}`);
wasSelectedFromMap.value = true;
await routeStore.selectRoute(routeId, routeName); await routeStore.selectRoute(routeId, routeName);
showRouteDropdown.value = false; showRouteDropdown.value = false;
showUberSearch.value = false; // Close the expanded search panel showUberSearch.value = false; // Close the expanded search panel
@ -607,9 +610,9 @@ async function highlightOptimalStopForRoute() {
<div class="uber-search-container" :class="{ 'compact-mode': routeStore.selectedRouteId && !showUberSearch }"> <div class="uber-search-container" :class="{ 'compact-mode': routeStore.selectedRouteId && !showUberSearch }">
<!-- Floating Triggers --> <!-- Floating Triggers -->
<div v-if="!showUberSearch" class="triggers-row"> <div v-if="!showUberSearch" class="triggers-row">
<!-- Shrunk Trigger (Icon only) --> <!-- Shrunk Trigger (Icon only) - Only if selected from MAP -->
<div <div
v-if="routeStore.selectedRouteId" v-if="routeStore.selectedRouteId && wasSelectedFromMap"
class="uber-search-trigger circular" class="uber-search-trigger circular"
@click="openUberSearch" @click="openUberSearch"
title="Buscar" title="Buscar"
@ -685,7 +688,7 @@ async function highlightOptimalStopForRoute() {
v-for="route in routeStore.allRoutes" v-for="route in routeStore.allRoutes"
:key="route.id" :key="route.id"
class="uber-result-item" class="uber-result-item"
:class="{ 'selected-route': route.id === routeStore.selectedRouteId }" :class="{ 'selected-route': route.id === routeStore.selectedRouteId && wasSelectedFromMap }"
@click="selectRouteAndClose(route.id, route.name)" @click="selectRouteAndClose(route.id, route.name)"
> >
<div class="result-icon"> <div class="result-icon">
@ -702,74 +705,73 @@ async function highlightOptimalStopForRoute() {
</div> <!-- Fin uber-results --> </div> <!-- Fin uber-results -->
</div> <!-- Fin uber-search-panel --> </div> <!-- Fin uber-search-panel -->
</Transition> </Transition>
</div> <!-- Fin uber-search-container --> </div> <!-- Ends uber-search-container -->
</div> <!-- Ends map-view -->
</div> <!-- Ends map-side -->
<!-- Offers Floating Card (Uber Eats style) --> <!-- Offers Floating Card (Uber Eats style) - OUTSIDE map-side to avoid anchoring -->
<Transition name="sheet-slide"> <Transition name="sheet-slide">
<div v-if="showPromos && couponStore.coupons.length > 0" class="offers-sheet"> <div v-if="showPromos && couponStore.coupons.length > 0" class="offers-sheet">
<!-- Header --> <!-- Header -->
<div class="sheet-header"> <div class="sheet-header">
<div class="sheet-title-group"> <div class="sheet-title-group">
<span class="material-icons sheet-star">stars</span> <span class="material-icons sheet-star">stars</span>
<span class="sheet-title">Ofertas SIBU</span> <span class="sheet-title">Ofertas SIBU</span>
</div>
<button class="sheet-close" @click="showPromos = false">
<span class="material-icons">close</span>
</button>
</div>
<!-- Card area with nav arrows -->
<div class="sheet-card-area">
<button class="sheet-nav" @click="prevPromo" :disabled="couponStore.coupons.length < 2">
<span class="material-icons">chevron_left</span>
</button>
<Transition name="carousel-slide" mode="out-in">
<div
v-if="currentPromo"
:key="currentPromo.id"
class="sheet-card"
@mouseenter="stopCarousel"
@touchstart="stopCarousel"
@mouseleave="startCarousel"
>
<div class="sheet-img-wrap">
<img
:src="getImageUrl(currentPromo.image_url, 'coupon')"
class="sheet-img"
@error="(e) => (e.target as HTMLImageElement).src = getImageUrl(null, 'coupon')"
/>
<span v-if="currentPromo.discount_percentage" class="sheet-discount">-{{ currentPromo.discount_percentage }}%</span>
</div>
<div class="sheet-info">
<span class="sheet-biz-name">{{ currentPromo.business?.name || 'Local' }}</span>
<h3 class="sheet-promo-title">{{ currentPromo.title }}</h3>
<button class="sheet-cta" @click="handlePromoClick(currentPromo)">Ver detalles</button>
<!-- CTA to business removed for simplification -->
</div>
</div>
</Transition>
<button class="sheet-nav" @click="nextPromo" :disabled="couponStore.coupons.length < 2">
<span class="material-icons">chevron_right</span>
</button>
</div>
<!-- Dots -->
<div class="sheet-dots" v-if="couponStore.coupons.length > 1">
<div
v-for="(_, i) in couponStore.coupons"
:key="i"
class="sheet-dot"
:class="{ 'sheet-dot--active': i === currentCarouselIndex }"
@click="currentCarouselIndex = i; startCarousel()"
></div>
</div> </div>
<button class="sheet-close" @click="showPromos = false">
<span class="material-icons">close</span>
</button>
</div>
<!-- Card area with nav arrows -->
<div class="sheet-card-area">
<button class="sheet-nav" @click="prevPromo" :disabled="couponStore.coupons.length < 2">
<span class="material-icons">chevron_left</span>
</button>
<Transition name="carousel-slide" mode="out-in">
<div
v-if="currentPromo"
:key="currentPromo.id"
class="sheet-card"
@mouseenter="stopCarousel"
@touchstart="stopCarousel"
@mouseleave="startCarousel"
>
<div class="sheet-img-wrap">
<img
:src="getImageUrl(currentPromo.image_url, 'coupon')"
class="sheet-img"
@error="(e) => (e.target as HTMLImageElement).src = getImageUrl(null, 'coupon')"
/>
<span v-if="currentPromo.discount_percentage" class="sheet-discount">-{{ currentPromo.discount_percentage }}%</span>
</div>
<div class="sheet-info">
<span class="sheet-biz-name">{{ currentPromo.business?.name || 'Local' }}</span>
<h3 class="sheet-promo-title">{{ currentPromo.title }}</h3>
<button class="sheet-cta" @click="handlePromoClick(currentPromo)">Ver detalles</button>
</div>
</div>
</Transition>
<button class="sheet-nav" @click="nextPromo" :disabled="couponStore.coupons.length < 2">
<span class="material-icons">chevron_right</span>
</button>
</div>
<!-- Dots -->
<div class="sheet-dots" v-if="couponStore.coupons.length > 1">
<div
v-for="(_, i) in couponStore.coupons"
:key="i"
class="sheet-dot"
:class="{ 'sheet-dot--active': i === currentCarouselIndex }"
@click="currentCarouselIndex = i; startCarousel()"
></div>
</div> </div>
</Transition>
</div> </div>
</div> </Transition>
<!-- Modal for details removed as per request to eliminate extra markings --> <!-- Modal for details removed as per request to eliminate extra markings -->
@ -929,7 +931,7 @@ async function highlightOptimalStopForRoute() {
OFFERS BOTTOM SHEET OFFERS BOTTOM SHEET
═══════════════════════════════════════ */ ═══════════════════════════════════════ */
.offers-sheet { .offers-sheet {
position: absolute; position: fixed;
bottom: 80px; /* Separado del borde inferior/menú */ bottom: 80px; /* Separado del borde inferior/menú */
left: 50%; left: 50%;
transform: translateX(-50%) translateY(0); transform: translateX(-50%) translateY(0);
@ -940,7 +942,7 @@ async function highlightOptimalStopForRoute() {
-webkit-backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.3); border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 24px; border-radius: 24px;
z-index: 2000; z-index: 3000; /* Aumentado para estar sobre todo */
padding: 12px; padding: 12px;
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15); box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
color: #000; color: #000;