Cómo mostrar ofertas en su aplicación
Una vez que haya obtenido ofertas de la API con éxito, el siguiente paso es presentarlas de manera efectiva en su aplicación. Este artículo cubre estrategias prácticas para geocodificar, mostrar tarjetas de ofertas, ordenar resultados y mantener las ofertas actualizadas.
Paso 1: Obtener la ubicación del usuario
La API de ofertas requiere coordenadas de latitud y longitud. Hay varias formas de obtenerlos según su plataforma y caso de uso.
API de geolocalización del navegador
El enfoque más directo para aplicaciones web. Esto utiliza el GPS del dispositivo o la ubicación basada en red:
function getUserLocation() {
return new Promise((resolve, reject) => {
if (!navigator.geolocation) {
reject(new Error('Geolocation is not supported'));
return;
}
navigator.geolocation.getCurrentPosition(
(position) => {
resolve({
lat: position.coords.latitude,
long: position.coords.longitude
});
},
(error) => {
// Fall back to IP-based geolocation or a default location
reject(error);
},
{ timeout: 10000, maximumAge: 300000 }
);
});
}
> Importante: La geolocalización requiere permiso del usuario. Tenga siempre una estrategia alternativa para los usuarios que la rechazan o que utilizan navegadores que no la admiten.
Reserva de geolocalización basada en IP
Cuando el GPS no está disponible, los servicios basados en IP proporcionan coordenadas aproximadas:
async function getLocationByIP() {
const response = await fetch('https://ipapi.co/json/');
const data = await response.json();
return {
lat: data.latitude,
long: data.longitude,
city: data.city
};
}
Búsqueda de ciudad o destino
Para aplicaciones donde los usuarios seleccionan un destino, utilice un servicio de codificación geográfica para convertir el nombre de la ubicación en coordenadas:
async function geocodeCity(cityName) {
// Use your preferred geocoding provider (Google Maps, Mapbox, etc.)
const response = await fetch(
https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(cityName)}.json?accesstoken=YOURTOKEN
);
const data = await response.json();
const [lng, lat] = data.features[0].center;
return { lat, long: lng };
}
Paso 2: crear un componente de tarjeta de oferta
Una tarjeta de oferta bien diseñada debería comunicar valor rápidamente. Estos son los elementos clave a incluir:
Elementos esenciales de la tarjeta
- Imagen de propiedad: una imagen principal grande y de alta calidad llama la atención y hace que las ofertas sean visualmente atractivas.
- Nombre del hotel y clasificación de estrellas: muestra de forma destacada para que los usuarios puedan evaluar rápidamente la calidad.
- Ubicación: nombre de la ciudad o vecindario, más la distancia desde las coordenadas buscadas, si están disponibles.
- Precio original — Muestra el precio de referencia tachado para resaltar el descuento.
- Precio de oferta: el precio con descuento, que se muestra más grande y en un color contrastante.
- Insignia de descuento: un porcentaje o insignia de "Ahorra $X" en la esquina de la tarjeta.
- Validez de la oferta: si la respuesta incluye rangos de fechas, muestra cuándo vence la oferta o la ventana de viaje.
Ejemplo de estructura HTML
<div class="deal-card">
<div class="deal-image">
<img src="{deal.imageurl}" alt="{deal.propertyname}" loading="lazy" />
<span class="discount-badge">-{deal.discount_percentage}%</span>
</div>
<div class="deal-content">
<div class="star-rating">{'★'.repeat(deal.star_rating)}</div>
<h3 class="property-name">{deal.property_name}</h3>
<p class="location">{deal.address}</p>
<div class="pricing">
<span class="original-price">${deal.original_price}</span>
<span class="deal-price">${deal.deal_price}</span>
<span class="per-night">per night</span>
</div>
</div>
</div>
Consejos de estilo
- Utilice un diseño de cuadrícula (2 o 3 columnas en el escritorio, una sola columna en el dispositivo móvil) para las tarjetas de ofertas.
- Haz que la insignia de descuento destaque visualmente: una pastilla o una cinta de color funcionan bien.
- Utilice el estilo tachado en el precio original para resaltar los ahorros.
- Asegúrese de que las imágenes tengan una relación de aspecto consistente (16:9 o 3:2) para mantener la cuadrícula limpia.
Paso 3: ordenar y filtrar ofertas
La API devuelve ofertas en su orden predeterminado, pero es posible que desee ordenarlas o filtrarlas en el lado del cliente para que coincidan con las preferencias del usuario.
Opciones de clasificación
function sortDeals(deals, sortBy) {
const sorted = [...deals];
switch (sortBy) {
case 'discount':
// Highest discount first
return sorted.sort((a, b) => b.discountpercentage - a.discountpercentage);
case 'price-low':
// Lowest deal price first
return sorted.sort((a, b) => a.dealprice - b.dealprice);
case 'price-high':
// Highest deal price first
return sorted.sort((a, b) => b.dealprice - a.dealprice);
case 'rating':
// Highest star rating first
return sorted.sort((a, b) => b.starrating - a.starrating);
default:
return sorted;
}
}
Filtrado del lado del cliente
También puede ofrecer filtros para que los usuarios puedan limitar los resultados:
- Calificación de estrellas: filtre por calificación mínima de estrellas (por ejemplo, 3+ estrellas, 4+ estrellas).
- Rango de precios: control deslizante o entradas mínimas y máximas para filtrar por precio de oferta.
- Descuento mínimo: solo muestra ofertas que superen un determinado porcentaje de descuento.
Paso 4: Gestionar la caducidad de la oferta y actualizarla
Las ofertas son urgentes. Las ofertas obsoletas generan una mala experiencia de usuario cuando un usuario hace clic para reservar y descubre que la oferta ya no está disponible.
Actualizar estrategia
- Al cargar la página: siempre busca ofertas nuevas cuando el usuario navega a una página de ofertas.
- Actualización periódica: si el usuario permanece en la página de ofertas, actualice cada 5 a 10 minutos para seleccionar nuevas ofertas y descartar las vencidas.
- En acción del usuario: se actualiza cuando el usuario cambia de ubicación, moneda o preferencias de clasificación.
class DealRefresher {
constructor(fetchFn, intervalMs = 5 60 1000) {
this.fetchFn = fetchFn;
this.intervalMs = intervalMs;
this.timer = null;
}
start() {
this.fetchFn(); // Initial fetch
this.timer = setInterval(() => this.fetchFn(), this.intervalMs);
}
stop() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
}
refresh() {
this.stop();
this.start();
}
}
Manejo de ofertas vencidas
Si las ofertas incluyen una marca de tiempo de vencimiento, puede eliminar o atenuar proactivamente las ofertas vencidas en la interfaz de usuario sin esperar la siguiente llamada a la API:
function isExpired(deal) {
if (!deal.expires_at) return false;
return new Date(deal.expires_at) < new Date();
}
function filterActiveDeals(deals) {
return deals.filter(deal => !isExpired(deal));
}
Paso 5: Estado vacío y carga
Estado de carga
Muestra cartas esqueléticas o una ruleta mientras se cargan las ofertas. Evite mostrar una página vacía que pueda confundirse con "no hay ofertas disponibles".
No hay ofertas disponibles
Es posible que algunas ubicaciones no tengan ofertas actuales. Maneja esto con gracia:
<div class="no-deals">
<h3>No deals available near this location right now</h3>
<p>Deals change frequently. Check back soon or try a different location.</p>
<button onclick="showTopDestinations()">Browse Top Destinations</button>
</div>
Considere recurrir a una consulta top_destination=true cuando una búsqueda basada en proximidad no arroje resultados, para que los usuarios siempre vean algo útil.
Poniéndolo todo junto
Un flujo de integración típico se ve así:
- Detectar o solicitar la ubicación del usuario.
- Llame a la API de ofertas con las coordenadas y la moneda preferida.
- Represente tarjetas de ofertas en un diseño de cuadrícula responsivo.
- Proporcionar controles de clasificación y filtrado.
- Configure una actualización periódica para mantener las ofertas actualizadas.
- Maneje los estados vacíos y los indicadores de carga con elegancia.Para obtener orientación sobre el almacenamiento en caché y el rendimiento, consulte Prácticas recomendadas para la integración.