Temporizador solo - Bsale-IO/template-docs GitHub Wiki

Componente por defecto en los templates

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.

Grabación de pantalla 2025-03-25 a la(s) 16 55 38

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;

Instrucciones de Instalación

El componente "Temporizador solo"para poder activarlo, se deberá llamar en el componente 🟢 INICIO

image

{{ 'Temporizador solo' | get_component }}

Instrucciones de su configuración

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 -->

Configuración del Temporizador

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

Variables de Configuración

Temporización

  • 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").

Contenido del Temporizador

  • 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.

⚠️ **GitHub.com Fallback** ⚠️