Temporizador solo - Bsale-IO/template-docs GitHub Wiki
Este componente está integrado en todos los templates base y permite añadir un temporizador visual interactivo en la página. El temporizador puede configurarse para hacer una cuenta regresiva hasta una fecha específica, y puede incluir un mensaje personalizado junto con un botón de llamada a la acción. Una vez llegue a cero, el temporizador desaparecerá automáticamente.
Codigo componente Temporizador solo
<!-- Configuración del temporizador -->
{% assign exclusive_timer_year = "2026" %} <!-- Año de finalización de la oferta -->
{% assign exclusive_timer_month = "3" %} <!-- Mes de finalización (marzo) -->
{% assign exclusive_timer_day = "21" %} <!-- Día de finalización -->
{% assign exclusive_timer_hour = "16" %} <!-- Hora de finalización (24h) -->
{% assign exclusive_timer_minute = "04" %} <!-- Minuto de finalización -->
{% assign exclusive_timer_second = "59" %} <!-- Segundo de finalización -->
<!-- Configuración del texto del temporizador -->
{% assign exclusive_timer_heading = "OFERTA EXCLUSIVA" %} <!-- Encabezado del temporizador -->
{% assign exclusive_timer_message = "¡OFERTA FLASH! TERMINA EN POCAS HORAS" %} <!-- Mensaje mostrado junto al temporizador -->
{% assign exclusive_timer_text_button = "Ver Oferta Ahora" %} <!-- Texto del botón -->
{% assign collection_link = "/collection/celulares" %} <!-- Enlace de la colección -->
<div class="exclusive-timer-container mt-4">
<div class="header-container">
<h2 class="exclusive-timer-heading">{{ exclusive_timer_heading }}</h2>
<div class="exclusive-timer-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"></circle>
<polyline points="12 6 12 12 16 14"></polyline>
</svg>
</div>
</div>
<div class="exclusive-timer-content">
<div class="exclusive-timer-box">
<span class="exclusive-timer-days">00</span>
<div class="exclusive-timer-label">Días</div>
</div>
<div class="exclusive-timer-box">
<span class="exclusive-timer-hours">00</span>
<div class="exclusive-timer-label">Horas</div>
</div>
<div class="exclusive-timer-box">
<span class="exclusive-timer-minutes">00</span>
<div class="exclusive-timer-label">Minutos</div>
</div>
<div class="exclusive-timer-box">
<span class="exclusive-timer-seconds">00</span>
<div class="exclusive-timer-label">Segundos</div>
</div>
</div>
<div class="exclusive-timer-message">
<div class="flame-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="#FF4B2B" stroke="#FF4B2B" stroke-width="1">
<path d="M12 2c0 4-6 8-6 13 0 3.5 2.5 6 6 6s6-2.5 6-6c0-5-6-9-6-13z"></path>
<path d="M12 9c0 2-1.5 4-1.5 6 0 1.5 1 2.5 1.5 2.5s1.5-1 1.5-2.5c0-2-1.5-4-1.5-6z" fill="#FFDE59"></path>
</svg>
</div>
{{ exclusive_timer_message }}
<div class="flame-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="#FF4B2B" stroke="#FF4B2B" stroke-width="1">
<path d="M12 2c0 4-6 8-6 13 0 3.5 2.5 6 6 6s6-2.5 6-6c0-5-6-9-6-13z"></path>
<path d="M12 9c0 2-1.5 4-1.5 6 0 1.5 1 2.5 1.5 2.5s1.5-1 1.5-2.5c0-2-1.5-4-1.5-6z" fill="#FFDE59"></path>
</svg>
</div>
</div>
<a href="{{ collection_link }}" class="exclusive-timer-button">{{ exclusive_timer_text-button }}</a>
</div>
<script>
function startExclusiveCountdown(targetDate, serverTime) {
const countdownContainers = document.querySelectorAll('.exclusive-timer-container');
let currentServerTime = serverTime;
countdownContainers.forEach(container => {
const daysElement = container.querySelector('.exclusive-timer-days');
const hoursElement = container.querySelector('.exclusive-timer-hours');
const minutesElement = container.querySelector('.exclusive-timer-minutes');
const secondsElement = container.querySelector('.exclusive-timer-seconds');
function updateCountdown() {
currentServerTime += 1000; // Aumentamos en 1 segundo de forma independiente del usuario
const timeLeft = targetDate - currentServerTime;
if (timeLeft <= 0) {
container.classList.add("exclusive-timer-expired");
return;
}
const days = Math.floor(timeLeft / (1000 * 60 * 60 * 24));
const hours = Math.floor((timeLeft % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((timeLeft % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((timeLeft % (1000 * 60)) / 1000);
daysElement.textContent = days.toString().padStart(2, "0");
hoursElement.textContent = hours.toString().padStart(2, "0");
minutesElement.textContent = minutes.toString().padStart(2, "0");
secondsElement.textContent = seconds.toString().padStart(2, "0");
}
updateCountdown();
setInterval(updateCountdown, 1000);
});
}
// Obtener la fecha del final de la oferta en UTC desde el servidor
const exclusiveOfferEndDate = Date.UTC(
parseInt("{{ exclusive_timer_year }}"),
parseInt("{{ exclusive_timer_month }}") - 1,
parseInt("{{ exclusive_timer_day }}"),
parseInt("{{ exclusive_timer_hour }}"),
parseInt("{{ exclusive_timer_minute }}"),
parseInt("{{ exclusive_timer_second }}")
);
const exclusiveServerCurrentTime = {{serverTimeMs}}; // Este ya viene en UTC del servidor
startExclusiveCountdown(exclusiveOfferEndDate, exclusiveServerCurrentTime);
</script>
Codigo CSS del componente Temporizador solo
.exclusive-timer-title a {
color: var(--exclusive-timer-text-color);
text-decoration: none;
font-weight: bold;
transition: color 0.3s ease;
}
.exclusive-timer-title a:hover {
color: rgba(255, 255, 255, 0.8);
}
.exclusive-timer-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: var(--exclusive-timer-bg);
padding: 20px;
border-radius: 12px;
font-size: 20px;
font-weight: bold;
text-align: center;
margin-bottom: 20px;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.3);
position: relative;
}
.exclusive-timer-container::before {
content: '';
position: absolute;
top: -6px;
left: -6px;
right: -6px;
bottom: -6px;
background: var(--exclusive-timer-bg);
border-radius: 14px;
opacity: 0;
z-index: -1;
animation: pulse-border-exclusive 2s infinite ease-in-out;
filter: blur(3px);
}
@keyframes pulse-border-exclusive {
0% {
transform: scale(1);
opacity: 0;
}
20% {
transform: scale(1.01);
opacity: 0.4;
}
70% {
transform: scale(1.02);
opacity: 0;
}
100% {
transform: scale(1);
opacity: 0;
}
}
.header-container {
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
margin-bottom: 15px;
}
.exclusive-timer-heading {
font-size: 28px;
color: white;
text-transform: uppercase;
letter-spacing: 2px;
margin: 0;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.exclusive-timer-icon {
animation: swing 2s infinite;
color: white;
display: flex;
align-items: center;
}
@keyframes swing {
20% { transform: rotate(8deg); }
40% { transform: rotate(-8deg); }
60% { transform: rotate(4deg); }
80% { transform: rotate(-4deg); }
100% { transform: rotate(0deg); }
}
.exclusive-timer-content {
display: flex;
gap: 15px;
font-size: 22px;
}
.exclusive-timer-box {
display: flex;
flex-direction: column;
align-items: center;
background: var(--exclusive-timer-box-bg);
color: var(--exclusive-timer-box-text-color);
padding: 15px 20px;
border-radius: 12px;
min-width: 80px;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
transform: skew(-5deg);
transition: all 0.3s ease;
}
.exclusive-timer-box:hover {
transform: skew(-5deg) scale(1.05);
}
.exclusive-timer-box span {
font-size: 32px;
font-weight: bold;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
transition: opacity 0.3s ease;
}
.exclusive-timer-label {
font-size: 16px;
text-transform: uppercase;
margin-top: 5px;
}
.exclusive-timer-message {
font-size: 18px;
margin: 15px 0;
background: var(--exclusive-timer-message-bg);
color: var(--exclusive-timer-message-text);
padding: 10px 20px;
border-radius: 50px;
font-weight: bold;
letter-spacing: 0.5px;
animation: scaleAnimation 1.5s infinite;
display: flex;
align-items: center;
justify-content: center;
}
.flame-icon {
animation: flameFlicker 1s infinite;
margin: 0 5px;
}
@keyframes scaleAnimation {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.03); }
}
@keyframes flameFlicker {
0%, 100% { opacity: 1; }
50% { opacity: 0.8; }
}
.exclusive-timer-button {
margin-top: 20px;
padding: 12px 30px;
background: var(--exclusive-timer-button-bg);
color: var(--exclusive-timer-button-text);
font-size: 18px;
font-weight: bold;
text-transform: uppercase;
text-decoration: none;
border-radius: 50px;
border: none;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease;
animation: buttonPulse 2s infinite;
letter-spacing: 1px;
}
.exclusive-timer-button:hover {
background: var(--exclusive-timer-button-hover-bg);
transform: translateY(-3px);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
color: var(--exclusive-timer-button-hover-text);
}
@keyframes buttonPulse {
0% { transform: scale(1); box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); }
50% { transform: scale(1.03); }
100% { transform: scale(1); box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); }
}
.exclusive-timer-expired {
display: none !important;
}
@media (max-width: 480px) {
.header-container {
flex-direction: column;
gap: 10px;
}
.exclusive-timer-heading {
font-size: 24px;
}
.exclusive-timer-content {
display: flex;
flex-wrap: nowrap;
justify-content: center;
padding: 11px;
gap: 5px;
overflow: hidden;
}
.exclusive-timer-box {
min-width: 60px;
padding: 10px 12px;
}
.exclusive-timer-box span {
font-size: 24px;
}
.exclusive-timer-label {
font-size: 10px;
}
.exclusive-timer-message {
font-size: 16px;
padding: 8px 15px;
}
.exclusive-timer-button {
padding: 10px 20px;
font-size: 16px;
}
}
Codigo CSS de las variables en el root
/********************************************************************
Temporizador Solo con botón
*********************************************************************/
--exclusive-timer-bg: linear-gradient(135deg, #FF416C, #FF4B2B);
--exclusive-timer-box-bg: rgba(255, 255, 255, 0.2);
--exclusive-timer-box-text-color: #fff;
--exclusive-timer-message-bg: #FFDE59;
--exclusive-timer-message-text: #333;
--exclusive-timer-button-bg: linear-gradient(135deg, #4CAF50, #3e8e41);
--exclusive-timer-button-hover-bg: linear-gradient(135deg, #45a049, #36802e);
--exclusive-timer-button-text: white;
--exclusive-timer-button-hover-text: #eeeeee;
El componente "Temporizador solo"para poder activarlo, se deberá llamar en el componente 🟢 INICIO
{{ 'Temporizador solo' | get_component }}
EL principio del componente tiene sus variables de configuración la cual son las siguientes:
<!-- Configuración del temporizador -->
{% assign exclusive_timer_year = "2026" %} <!-- Año de finalización de la oferta -->
{% assign exclusive_timer_month = "3" %} <!-- Mes de finalización (marzo) -->
{% assign exclusive_timer_day = "21" %} <!-- Día de finalización -->
{% assign exclusive_timer_hour = "16" %} <!-- Hora de finalización (24h) -->
{% assign exclusive_timer_minute = "04" %} <!-- Minuto de finalización -->
{% assign exclusive_timer_second = "59" %} <!-- Segundo de finalización -->
<!-- Configuración del texto del temporizador -->
{% assign exclusive_timer_heading = "OFERTA EXCLUSIVA" %} <!-- Encabezado del temporizador -->
{% assign exclusive_timer_message = "¡OFERTA FLASH! TERMINA EN POCAS HORAS" %} <!-- Mensaje mostrado junto al temporizador -->
{% assign exclusive_timer_text-button = "Ver Oferta Ahora" %} <!-- Texto del botón -->
{% assign collection_link = "/collection/celulares" %} <!-- Enlace de la colección -->
Este archivo contiene la configuración del temporizador para la oferta exclusiva.
Important
El temporizador funcionará exactamente hasta la fecha y hora configuradas en las variables de tiempo y desaparecerá cuando llegue a cero
-
exclusive_timer_year
: Año de finalización de la oferta (Ejemplo:"2026"
). -
exclusive_timer_month
: Mes de finalización (Ejemplo:"3"
para marzo). -
exclusive_timer_day
: Día de finalización de la oferta (Ejemplo:"21"
). -
exclusive_timer_hour
: Hora de finalización en formato 24h (Ejemplo:"16"
para las 16:00 hrs). -
exclusive_timer_minute
: Minuto exacto en que finaliza la oferta (Ejemplo:"04"
). -
exclusive_timer_second
: Segundo exacto en que finaliza la oferta (Ejemplo:"59"
).
-
exclusive_timer_heading
: Encabezado del temporizador (Ejemplo:"OFERTA EXCLUSIVA"
). -
exclusive_timer_message
: Mensaje mostrado junto al temporizador (Ejemplo:"¡OFERTA FLASH! TERMINA EN POCAS HORAS"
). -
exclusive_timer_text_button
: Texto del botón de acción (Ejemplo:"Ver Oferta Ahora"
). -
collection_link
: Enlace a la colección relevante (Ejemplo:"/collection/celulares"
).
Important
La variable {{serverTimeMs}}
obtiene la hora directamente desde el servidor, incluyendo la zona horaria. Por lo tanto, no puede ser manipulada de forma local en el equipo del usuario.