How to Add Countdown Timer in Shopify Store without App ⏰​ Free - eCommerce Thesis

How to Add Countdown Timer in Shopify Store without App ⏰​ Free

{% comment %}
Liquid Variables
{% endcomment %}

{% liquid
assign timer_section_title = section.settings.timer_section_title
assign timer_section_subtitle = section.settings.timer_section_subtitle

assign date_picker_time = section.settings.date_picker

assign cta_bg_color = section.settings.cta_bg_color
assign cta_text_color = section.settings.cta_text_color

assign title_text_color = section.settings.title_text_color
assign subtitle_text_color = section.settings.subtitle_text_color
assign subtitle_font_weight = section.settings.subtitle_font_weight

assign section_bg_color = section.settings.bg_color
assign timer_color = section.settings.timer_color
%}



{% comment %}
Custom CSS Styles
{% endcomment %}
{% style %}
    .timer-flex-container{
        background: {{ section_bg_color }};
        align-items: center;
        justify-content: center;
        column-gap: 20px;
        padding: 10px;
        display: flex;
        opacity: 1;
        transition: 0.5s all linear;
    }

    .hide-element{
        padding: 0 !important;
        opacity: 0;
    }

    .timer-flex-container .timer {
        display: flex;
        justify-content: space-around;
    }

    .timer-flex-container .timer-subtitle{
        text-align:center; margin: 5px 0;
    }

    .timer-flex-container .timer-subtitle{
        color: {{ subtitle_text_color }};
        font-weight: {{ subtitle_font_weight }};
        font-family: inherit;
        font-size: 18px;
    }

    .timer-flex-container .timer--expired {
        display: none;
    }

    .timer-flex-container .timer__title {
        text-align: center;
        font-weight: bold;
    }

    .timer-flex-container .timer-display {
        display: -webkit-box;
        display: -ms-flexbox;
        display: flex;
        -webkit-box-pack: justify;
        -ms-flex-pack: justify;
        justify-content: center;
        margin-top: 5px;
    }

    .timer-flex-container .timer{
        margin-right: 1rem;
    }

    .timer-flex-container .timer-block {
        position: relative;
        padding: 0 10px;
    }

    .timer-flex-container .timer-block__num,
    .timer-flex-container .timer-block__unit {
        display: block;
        text-align: center;
        color: {{ timer_color }};
        font-family: inherit;
    }

    .timer-flex-container .timer-block__num{
        font-size: 16px;
    }

    .timer-flex-container .timer-block__unit{
        font-size: 13px;
        margin-top: -7px;
    }

    .timer-flex-container .colon {
        font-size: 16px;
        color: {{ timer_color }};
    }

    .timer-flex-container .timer-button{
        max-height: 45px;
        background-color: {{ section.settings.cta_bg_color }} !important;
        color: {{ section.settings.cta_text_color }} !important;
        border-radius: 4px;
    }

    .timer-flex-container .timer-button::after{
        content: none;
    }

    .timer-display-flex{
        display: flex;
        align-items: center;
    }

    .gradient-bg-animation{background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
	background-size: 400% 400%;
	animation: gradient 15s ease infinite;}




@keyframes gradient {
	0% {
		background-position: 0% 50%;
	}
	50% {
		background-position: 100% 50%;
	}
	100% {
		background-position: 0% 50%;
	}
}

    @media screen and (max-width: 768px){
        .timer-flex-container{
            flex-direction: column;
        }
    }

    @media screen and (max-width: 391px){
        .timer-display-flex{
            width: 100%;
            justify-content: space-evenly;
            flex-wrap: wrap;
        }
    }

{% endstyle %}

{% unless date_picker_time == blank %}
<div class="timer-flex-container hide-element gradient-bg-animation">
    {% unless timer_section_title == blank %}
        <div class="timer-subtitle">{{ timer_section_title }}</div>
    {% endunless %}


    <div class = "timer-display-flex">
        <countdown-timer-bar schema-time="{{ date_picker_time }}">
            <div class="timer" style="visibility: hidden;">
                <div class="timer-display">
                    <div class="timer-block">
                        <span class="timer-block__num js-timer-days">00</span>
                        <span class="timer-block__unit">Days</span>
                    </div>

                    <div class="colon">:</div>

                    <div class="timer-block">
                        <span class="timer-block__num js-timer-hours">00</span>
                        <span class="timer-block__unit">Hrs</span>
                    </div>

                    <div class="colon">:</div>

                    <div class="timer-block">
                        <span class="timer-block__num js-timer-minutes">00</span>
                        <span class="timer-block__unit">Mins</span>
                    </div>

                    <div class="colon">:</div>

                    <div class="timer-block">
                        <span class="timer-block__num js-timer-seconds">00</span>
                        <span class="timer-block__unit">Secs</span>
                    </div>
                </div>
            </div>
        </countdown-timer-bar>

        {% unless section.settings.timer_section_btn_link == blank and timer_section_btn_text == blank %}
        <a class="timer-button button" href="{{ section.settings.timer_section_btn_link }}">
            <span>{{
                section.settings.timer_section_btn_text }}
            </span>
        </a>
        {% endunless %}
    </div>

    
</div>
{% endunless %}


{% comment %}
Native Web Component Definition
{% endcomment %}
{% javascript %}
class CountdownTimerBar extends HTMLElement {
    constructor() {
        super();
    }

    init() {
        this.schemaTime = this.getAttribute('schema-time');

        this.timer = this.querySelector(".timer")
        this.countdown = new Date(this.schemaTime).getTime();
        this.second = 1000;
        this.minute = this.second * 60;
        this.hour = this.minute * 60;
        this.day = this.hour * 24;

        this.timerInterval = null;
        this.startTimer();

        setTimeout(() => this.timer.style.visibility = "visible", 1000)
    }

    padWithLeadingZero = (number) => {
        if (number < 10) {
            return '0' + number;
        } else {
            return number;
        }
    };

    isDateInPast(date) {
        const now = new Date();
        return date < now;
    }


    startTimer() {
        //Have quick check to see if Date input in the countdown class variable is in the past
        //Helper function

        const timerElem = this.timer
        this.timerInterval = setInterval(() => {
            const now = new Date().getTime();
            const distance = this.countdown - now;

            const dayCalc = Math.floor(distance / this.day);
            const hourCalc = Math.floor((distance % this.day) / this.hour);
            const minuteCalc = Math.floor((distance % this.hour) / this.minute);
            const secondCalc = Math.floor((distance % this.minute) / this.second);

            timerElem.querySelector('.js-timer-days').textContent = this.padWithLeadingZero(dayCalc);
            timerElem.querySelector('.js-timer-hours').textContent = this.padWithLeadingZero(hourCalc);
            timerElem.querySelector('.js-timer-minutes').textContent = this.padWithLeadingZero(minuteCalc);
            timerElem.querySelector('.js-timer-seconds').textContent = this.padWithLeadingZero(secondCalc);
        }, this.second);
    }

    disconnectedCallback() {
        clearInterval(this.timerInterval);
    }

    connectedCallback(){
        this.init();
        console.log("countdown timer was added to the page")
        
        const timerFlexContainer = window.document.querySelector(".timer-flex-container")
        const timerElem = this.timer

        const pastDate = this.isDateInPast(this.countdown)
        if(pastDate){
            timerFlexContainer.remove()
            this.remove()
        }
        window.setTimeout(() => {
            timerFlexContainer.classList.remove("hide-element")
        }, 2000);
    }

    disconnectedCallback(){
        console.log("The Timer date has passed so the timer was removed")
    }
}

customElements.define('countdown-timer-bar', CountdownTimerBar);
{% endjavascript %}


    {% comment %}
    Section Customization Options
    {% endcomment %}
    {% schema %}
    {
        "name": "Countdown Top Bar",
        "tag": "section",
        "enabled_on": {
            "groups": ["header"]
        },
        "settings": [
            {
                "type": "header",
                "content": "General Section Settings"
            },
            {
                "type": "color",
                "id": "bg_color",
                "default": "#fff",
                "label": "Section Background Color"
            },
            {
                "type": "header",
                "content": "Title Settings"
            },
            {
                "type": "text",
                "id": "timer_section_title",
                "label": "Section Title",
                "default": "Hurry up! Sale ends in:"
            },
            {
                "type": "color",
                "id": "subtitle_text_color",
                "default": "#fff",
                "label": "Section Title Text Color"
            },
            {
                "type": "select",
                "id": "subtitle_font_weight",
                "default": "500",
                "label": "Normal or Bolded Text",
                "options": [
                    {
                        "label": "Normal",
                        "value": "500"
                    },
                    {
                        "label": "Bold",
                        "value": "700"
                    }
                ]
            },
            {
                "type": "header",
                "content": "Timer Settings"
            },
            {
                "type": "text",
                "id": "date_picker",
                "label": "Choose a date",
                "info": "Input date in this format: 07/21/2023. When date is in past section will disappear"
            },
            {
                "type": "color",
                "id": "timer_color",
                "default": "#fff",
                "label": "Timer Color"
            },
            {
                "type": "header",
                "content": "Button Settings"
            },
            {
                "type": "url",
                "id": "timer_section_btn_link",
                "label": "Call to Action Button Link"
            },
            {
                "type": "text",
                "id": "timer_section_btn_text",
                "label": "Call to Action Button Text",
                "default": "Shop Now!"
            },
            {
                "type": "color",
                "id": "cta_bg_color",
                "default": "#4770db",
                "label": "Call to Action Background Color"
            },
            {
                "type": "color",
                "id": "cta_text_color",
                "default": "#fff",
                "label": "Call to Action Text Color"
            }
        ],
        "presets": [
            {
                "name": "Countdown Top Bar"
            }
        ]
    }
    {% endschema %}