From 2eca01d7edbcfe029ab95392aa1bba2dc5bcf362 Mon Sep 17 00:00:00 2001 From: Hanzo_dev <2002samudiojohan@gmail.com> Date: Sat, 28 Feb 2026 21:27:18 -0500 Subject: [PATCH] feat: redesign promotions carrusel and fix closest stop marker issue --- frontend/src/composables/useFlujoPrincipal.ts | 6 +- frontend/src/views/MapView.vue | 201 ++++++++---------- 2 files changed, 95 insertions(+), 112 deletions(-) diff --git a/frontend/src/composables/useFlujoPrincipal.ts b/frontend/src/composables/useFlujoPrincipal.ts index 0d9435c..b75b1c5 100644 --- a/frontend/src/composables/useFlujoPrincipal.ts +++ b/frontend/src/composables/useFlujoPrincipal.ts @@ -6,7 +6,7 @@ import type { BusStop } from '@/types' import { useRouteStore } from '@/stores/route' export const useFlujoPrincipal = () => { - const { limpiarMapa, registrarMarker } = useMapState() + const { limpiarMapa } = useMapState() const paradaCercanaInst = useParadaCercana() const { encontrarParadaCercana, paradaCercana } = paradaCercanaInst const { trazarRuta } = useDirectionsRoute() @@ -97,7 +97,8 @@ export const useFlujoPrincipal = () => { } } - // ── PASO 6: Marcador de parada cercana ──────────────── + // ── PASO 6: Marcador de parada cercana (ELIMINADO por petición del usuario para mantener mapa limpio) ──────────────── + /* registrarMarker( new google.maps.Marker({ position: { lat: paradaCercanaFound.latitude, lng: paradaCercanaFound.longitude }, @@ -114,6 +115,7 @@ export const useFlujoPrincipal = () => { zIndex: 10 }) ) + */ // ── PASO 7: Pulso animado en ubicación del usuario ──── dibujarPulsoUsuario(ubicacion, map) diff --git a/frontend/src/views/MapView.vue b/frontend/src/views/MapView.vue index 8f9c1e9..68b0547 100644 --- a/frontend/src/views/MapView.vue +++ b/frontend/src/views/MapView.vue @@ -45,9 +45,7 @@ const isUpdatingMarkers = ref(false); const unitMarkers = ref>(new Map()); const unitFetchInterval = ref(null); const userCoords = ref<{ lat: number; lng: number } | null>(null); -const polyline = ref(null); const walkingPolyline = ref(null); -const walkingPolylineBorder = ref(null); const optimalStopPulse = ref(null); const showRouteDropdown = ref(false); const routeCardRef = ref(null); @@ -704,32 +702,26 @@ async function highlightOptimalStopForRoute() { - +
- -
- - +
- local_offer - Ofertas Disponibles - ({{ couponStore.coupons.length }}) + stars + Ofertas SIBU
-
- - -
-
- - -{{ currentPromo.discount_percentage }}% - + -{{ currentPromo.discount_percentage }}%
-
-

{{ currentPromo.business?.name || 'SIBU' }}

+ {{ currentPromo.business?.name || 'Local' }}

{{ currentPromo.title }}

-

{{ currentPromo.description }}

- + +
- -
-
- + >
@@ -944,54 +927,38 @@ async function highlightOptimalStopForRoute() { OFFERS BOTTOM SHEET ═══════════════════════════════════════ */ .offers-sheet { - position: fixed; - /* Base 72px (altura menú) + 60px espacio visual + safe area */ - bottom: calc(72px + 60px + env(safe-area-inset-bottom, 0px)); - left: 10px; - right: 10px; - background: #fff; - border: 2px solid #000; - border-radius: 12px; + position: absolute; + bottom: 80px; /* Separado del borde inferior/menú */ + left: 50%; + transform: translateX(-50%); + width: 92%; + max-width: 400px; + background: rgba(255, 255, 255, 0.85); + backdrop-filter: blur(20px) saturate(180%); + -webkit-backdrop-filter: blur(20px) saturate(180%); + border: 1px solid rgba(255, 255, 255, 0.3); + border-radius: 24px; z-index: 2000; - padding-bottom: 10px; - box-shadow: 0 -4px 15px rgba(0,0,0,0.2); + padding: 12px; + box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15); color: #000; - /* Limitar altura máxima para no ocupar toda la pantalla */ - max-height: calc(100vh - 200px); - overflow-y: auto; + overflow: hidden; } @media (prefers-color-scheme: dark) { .offers-sheet { - background: #111; + background: rgba(20, 20, 20, 0.8); + border-color: rgba(255, 255, 255, 0.1); color: #fff; - border-color: #333; } } -@media (max-width: 900px) { - .offers-sheet { - /* En móvil más espacio aún por el menú nativo */ - bottom: calc(135px + env(safe-area-inset-bottom, 0px)); - left: 8px; - right: 8px; - } -} - -.sheet-handle { - width: 40px; - height: 4px; - border-radius: 99px; - background: var(--border-color); - margin: 10px auto 8px; -} - .sheet-header { display: flex; align-items: center; justify-content: space-between; - padding: 0.5rem 1rem 0.75rem; - border-bottom: 1px solid var(--border-color); + padding: 0.25rem 0.5rem 0.5rem; + margin-bottom: 4px; } .sheet-header-left { @@ -1033,32 +1000,41 @@ async function highlightOptimalStopForRoute() { .sheet-close:hover { color: var(--text-primary); } .sheet-close .material-icons { font-size: 1.125rem; } -/* Card area */ .sheet-card-area { display: flex; align-items: center; - gap: 0.25rem; - padding: 0.75rem 0.5rem 0.375rem; - min-height: 110px; + gap: 0.5rem; + padding: 0.25rem; + min-height: 100px; } .sheet-nav { flex-shrink: 0; - width: 32px; - height: 32px; + width: 28px; + height: 28px; border-radius: 50%; - border: 1px solid var(--border-color); - background: var(--bg-primary); + border: none; + background: rgba(0, 0, 0, 0.05); color: var(--text-secondary); display: flex; align-items: center; justify-content: center; cursor: pointer; - transition: all 0.18s; + transition: all 0.2s; +} +.sheet-nav:disabled { opacity: 0.1; cursor: default; } +.sheet-nav:not(:disabled):hover { + background: var(--active-color); + color: #101820; + transform: scale(1.1); +} +.sheet-nav .material-icons { font-size: 1.125rem; } + +@media (prefers-color-scheme: dark) { + .sheet-nav { + background: rgba(255, 255, 255, 0.1); + } } -.sheet-nav:disabled { opacity: 0.3; cursor: default; } -.sheet-nav:not(:disabled):hover { background: var(--active-color); color: #101820; border-color: var(--active-color); } -.sheet-nav .material-icons { font-size: 1.25rem; } .sheet-card { flex: 1; @@ -1071,11 +1047,11 @@ async function highlightOptimalStopForRoute() { .sheet-img-wrap { position: relative; flex-shrink: 0; - width: 88px; - height: 88px; - border-radius: 12px; + width: 80px; + height: 80px; + border-radius: 16px; overflow: hidden; - background: var(--bg-primary); + box-shadow: 0 4px 12px rgba(0,0,0,0.1); } .sheet-img { @@ -1086,15 +1062,15 @@ async function highlightOptimalStopForRoute() { .sheet-discount { position: absolute; - top: 6px; - left: 6px; - background: #ef4444; + top: 0; + left: 0; + background: #f43f5e; color: #ffffff; - font-size: 0.6875rem; - font-weight: 800; - padding: 0.15rem 0.4rem; - border-radius: 6px; - line-height: 1.2; + font-size: 0.65rem; + font-weight: 900; + padding: 0.2rem 0.5rem; + border-bottom-right-radius: 12px; + line-height: 1; } .sheet-info { @@ -1102,27 +1078,25 @@ async function highlightOptimalStopForRoute() { min-width: 0; display: flex; flex-direction: column; - gap: 0.2rem; + gap: 0.15rem; } .sheet-biz-name { margin: 0; - font-size: 0.6875rem; - font-weight: 700; - color: var(--active-color); + font-size: 0.65rem; + font-weight: 800; + color: var(--text-secondary); text-transform: uppercase; - letter-spacing: 0.04em; + letter-spacing: 0.05em; + opacity: 0.8; } .sheet-promo-title { margin: 0; - font-size: 0.9375rem; - font-weight: 800; + font-size: 0.9rem; + font-weight: 900; color: var(--text-primary); - line-height: 1.2; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + line-height: 1.1; } .sheet-promo-desc { @@ -1137,23 +1111,30 @@ async function highlightOptimalStopForRoute() { } .sheet-cta { + align-self: flex-start; display: inline-flex; align-items: center; gap: 0.25rem; - margin-top: 0.375rem; - padding: 0.4rem 0.875rem; - background: var(--active-color); - color: #101820; + margin-top: 0.4rem; + padding: 0.35rem 0.75rem; + background: #101820; + color: #fee715; border: none; - border-radius: 99px; - font-size: 0.8125rem; + border-radius: 12px; + font-size: 0.75rem; font-weight: 800; - font-family: inherit; cursor: pointer; - transition: transform 0.15s; - align-self: flex-start; + transition: transform 0.2s; +} + +.sheet-cta:active { transform: scale(0.95); } + +@media (prefers-color-scheme: dark) { + .sheet-cta { + background: #fee715; + color: #101820; + } } -.sheet-cta:active { transform: scale(0.97); } /* Dots */ .sheet-dots {