feat(map): clean stop markers and route dimming
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, computed, watch, nextTick } from 'vue'
|
||||
import { onMounted, ref, computed } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useTaxiStore } from '@/stores/taxi'
|
||||
import { useShuttleStore } from '@/stores/shuttle'
|
||||
@ -23,25 +24,13 @@ const shifts = ['all', 'dia', 'tarde', 'noche']
|
||||
// Shuttle Filters
|
||||
const shuttleRouteFilter = ref('all')
|
||||
const shuttleTypeFilter = ref('all')
|
||||
const expandedShuttleId = ref<string | null>(null)
|
||||
const router = useRouter()
|
||||
const shuttleRefs = ref<Record<string, any>>({})
|
||||
|
||||
const setShuttleRef = (el: any, id: string) => {
|
||||
if (el) shuttleRefs.value[id] = el
|
||||
}
|
||||
|
||||
watch(expandedShuttleId, async (newVal) => {
|
||||
if (newVal) {
|
||||
await nextTick()
|
||||
const el = shuttleRefs.value[newVal]
|
||||
if (el) {
|
||||
// Small timeout to wait for the CSS height transition if any
|
||||
setTimeout(() => {
|
||||
el.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const shuttleRoutes = computed(() => {
|
||||
const routes = shuttleStore.shuttles.map(s => `${s.origin} - ${s.destination}`)
|
||||
@ -88,23 +77,6 @@ const handleCall = (taxi: Taxi) => {
|
||||
window.location.href = `tel:${taxi.phone_number}`
|
||||
}
|
||||
|
||||
const handleReserve = (shuttle: Shuttle) => {
|
||||
analyticsService.logEvent({
|
||||
event_name: 'shuttle_contact',
|
||||
item_id: shuttle.id,
|
||||
properties: { action: 'whatsapp', route: shuttle.route_name }
|
||||
})
|
||||
const message = encodeURIComponent(`Hola SIBU, me gustaría reservar un cupo para la ruta: ${shuttle.route_name}.`)
|
||||
window.open(`https://wa.me/${shuttle.contact_whatsapp.replace(/\+/g, '')}?text=${message}`, '_blank')
|
||||
}
|
||||
|
||||
const handleCallShuttle = (shuttle: Shuttle) => {
|
||||
analyticsService.logEvent({
|
||||
event_name: 'shuttle_contact',
|
||||
item_id: shuttle.id,
|
||||
properties: { action: 'call', route: shuttle.route_name }
|
||||
})
|
||||
}
|
||||
|
||||
function getShiftLabel(shift: string) {
|
||||
if (shift === 'dia') return t('taxi.dayShift')
|
||||
@ -275,26 +247,15 @@ function getShiftLabel(shift: string) {
|
||||
|
||||
<div v-else class="shuttles-grid">
|
||||
<!-- OVERLAY BACKDROP when a card is expanded -->
|
||||
<Teleport to="body">
|
||||
<div
|
||||
v-if="expandedShuttleId !== null"
|
||||
class="shuttle-modal-backdrop"
|
||||
@click="expandedShuttleId = null"
|
||||
></div>
|
||||
</Teleport>
|
||||
|
||||
<div
|
||||
v-for="shuttle in filteredShuttles"
|
||||
:key="shuttle.id"
|
||||
v-memo="[shuttle.id]"
|
||||
:ref="el => setShuttleRef(el, shuttle.id)"
|
||||
class="shuttle-card"
|
||||
:class="{ expanded: expandedShuttleId === shuttle.id }"
|
||||
@click="() => {
|
||||
expandedShuttleId = expandedShuttleId === shuttle.id ? null : shuttle.id;
|
||||
if (expandedShuttleId === shuttle.id) {
|
||||
analyticsService.logEvent({ event_name: 'shuttle_view', item_id: shuttle.id });
|
||||
}
|
||||
analyticsService.logEvent({ event_name: 'shuttle_view_detailed', item_id: shuttle.id });
|
||||
router.push(`/shuttle/${shuttle.id}`);
|
||||
}"
|
||||
>
|
||||
<img
|
||||
@ -325,72 +286,10 @@ function getShiftLabel(shift: string) {
|
||||
{{ shuttle.vehicle_type }}
|
||||
</div>
|
||||
<div class="expand-indicator">
|
||||
<span class="material-icons">{{ expandedShuttleId === shuttle.id ? 'expand_less' : 'expand_more' }}</span>
|
||||
<span class="material-icons">chevron_right</span>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- Close shuttle-main-info -->
|
||||
|
||||
<!-- EXPANDED CONTENT -->
|
||||
<div class="shuttle-details" v-if="expandedShuttleId === shuttle.id" @click.stop>
|
||||
<div class="shuttle-separator"></div>
|
||||
|
||||
<div class="shuttle-body">
|
||||
<div class="info-row">
|
||||
<span class="material-icons">schedule</span>
|
||||
<div>
|
||||
<p class="label">{{ t('shuttle.duration') }}</p>
|
||||
<p class="value">{{ shuttle.estimated_duration }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="material-icons">event</span>
|
||||
<div>
|
||||
<p class="label">{{ t('shuttle.departure') }}</p>
|
||||
<p class="value">{{ shuttle.departure_times }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row" v-if="shuttle.english_speaking">
|
||||
<span class="material-icons">g_translate</span>
|
||||
<div>
|
||||
<p class="label">IDIOMA</p>
|
||||
<p class="value">Español · English</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Precios prominentes -->
|
||||
<div class="price-block">
|
||||
<div class="price-row-main">
|
||||
<span class="price-amount-big">${{ shuttle.price_per_person }}</span>
|
||||
<span class="price-label-big">{{ t('shuttle.perPerson') }}</span>
|
||||
</div>
|
||||
<div class="price-row-secondary" v-if="shuttle.price_private_trip">
|
||||
<span class="material-icons price-icon-secondary">directions_car</span>
|
||||
<span class="price-amount-secondary">${{ shuttle.price_private_trip }}</span>
|
||||
<span class="price-label-secondary">viaje privado</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Botones de contacto (full width) -->
|
||||
<div class="contact-buttons">
|
||||
<a
|
||||
v-if="shuttle.phone_number"
|
||||
:href="'tel:' + shuttle.phone_number"
|
||||
class="contact-btn btn-call"
|
||||
@click.stop="handleCallShuttle(shuttle)"
|
||||
>
|
||||
<span class="material-icons">phone_in_talk</span>
|
||||
<span>Llamar</span>
|
||||
</a>
|
||||
<button
|
||||
class="contact-btn btn-whatsapp"
|
||||
@click.stop="handleReserve(shuttle)"
|
||||
>
|
||||
<span class="material-icons">chat</span>
|
||||
<span>WhatsApp</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="filteredShuttles.length === 0" class="empty-state">
|
||||
|
||||
Reference in New Issue
Block a user