class VidaDrop {
constructor(container) {
this.container = container;
this.sectionId = container.dataset.sectionId;
this.initCountdown();
this.initPreorder();
this.initStickyCtaHandler();
}
initCountdown() {
const ribbonCountdown = document.getElementById(`countdown-ribbon-${this.sectionId}`);
const inlineCountdown = document.getElementById(`countdown-inline-${this.sectionId}`);
if (ribbonCountdown) {
this.startCountdown(ribbonCountdown);
}
if (inlineCountdown) {
this.startCountdown(inlineCountdown);
}
}
startCountdown(element) {
const endDatetime = element.dataset.end;
if (!endDatetime) return;
const endDate = new Date(endDatetime);
const timerElement = element.querySelector('.vida-drop__countdown-timer');
const updateTimer = () => {
const now = new Date();
const distance = endDate - now;
if (distance < 0) {
timerElement.textContent = 'Ended';
return;
}
const days = Math.floor(distance / (1000 * 60 * 60 * 24));
const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
let timeString = '';
if (days > 0) {
timeString = `${days}d ${hours}h ${minutes}m ${seconds}s`;
} else if (hours > 0) {
timeString = `${hours}h ${minutes}m ${seconds}s`;
} else {
timeString = `${minutes}m ${seconds}s`;
if (element.classList.contains('vida-drop__countdown-ribbon')) {
element.classList.add('is-urgent');
}
}
timerElement.textContent = timeString;
};
updateTimer();
setInterval(updateTimer, 1000);
}
initPreorder() {
const preorderSection = this.container.querySelector('.vida-drop__preorder');
if (!preorderSection) return;
const startDatetime = preorderSection.dataset.preorderStart;
const endDatetime = preorderSection.dataset.preorderEnd;
const cap = parseInt(preorderSection.dataset.preorderCap);
const sold = parseInt(preorderSection.dataset.preorderSold);
const stateContainer = preorderSection.querySelector('.vida-drop__preorder-state');
const beforeState = preorderSection.querySelector('.vida-drop__preorder-before');
const activeState = preorderSection.querySelector('.vida-drop__preorder-active');
const waitlistState = preorderSection.querySelector('.vida-drop__preorder-waitlist');
const afterState = preorderSection.querySelector('.vida-drop__preorder-after');
const now = new Date();
const startDate = startDatetime ? new Date(startDatetime) : null;
const endDate = endDatetime ? new Date(endDatetime) : null;
// Hide all states
const hideAllStates = () => {
beforeState.style.display = 'none';
activeState.style.display = 'none';
waitlistState.style.display = 'none';
afterState.style.display = 'none';
};
hideAllStates();
// Determine which state to show
if (sold >= cap) {
stateContainer.dataset.state = 'waitlist';
waitlistState.style.display = 'block';
} else if (startDate && now < startDate) {
stateContainer.dataset.state = 'before';
beforeState.style.display = 'block';
const startDateSpan = beforeState.querySelector('.preorder-start-date');
if (startDateSpan) {
startDateSpan.textContent = startDate.toLocaleDateString('en-US', {
month: 'long',
day: 'numeric',
year: 'numeric',
hour: 'numeric',
minute: '2-digit'
});
}
} else if (endDate && now > endDate) {
stateContainer.dataset.state = 'after';
afterState.style.display = 'block';
} else {
stateContainer.dataset.state = 'active';
activeState.style.display = 'block';
}
// Handle pre-order button click
const preorderBtn = preorderSection.querySelector('.vida-drop__preorder-cta');
if (preorderBtn) {
preorderBtn.addEventListener('click', (e) => {
e.preventDefault();
const productId = preorderBtn.dataset.productId;
if (productId) {
this.addToCart(productId);
}
});
}
}
async addToCart(productId) {
try {
const response = await fetch('/cart/add.js', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
id: productId,
quantity: 1
})
});
if (response.ok) {
// Trigger cart drawer or redirect
if (typeof window.dispatchEvent === 'function') {
window.dispatchEvent(new CustomEvent('cart:item-added'));
}
// Fallback: redirect to cart
window.location.href = '/cart';
} else {
console.error('Failed to add to cart');
}
} catch (error) {
console.error('Error adding to cart:', error);
}
}
initStickyCtaHandler() {
const stickyCta = document.getElementById(`sticky-cta-${this.sectionId}`);
const stickyBtn = stickyCta?.querySelector('.vida-drop__sticky-cta-btn');
if (!stickyCta || !stickyBtn) return;
// Show/hide sticky CTA based on scroll position
const heroSection = this.container.querySelector('.vida-drop__hero');
const preorderSection = this.container.querySelector('.vida-drop__preorder');
const handleScroll = () => {
if (!heroSection) return;
const heroBottom = heroSection.getBoundingClientRect().bottom;
const preorderTop = preorderSection?.getBoundingClientRect().top;
// Show if scrolled past hero but before preorder section
if (heroBottom < 0 && (!preorderSection || preorderTop > window.innerHeight)) {
stickyCta.classList.add('is-visible');
} else {
stickyCta.classList.remove('is-visible');
}
};
window.addEventListener('scroll', handleScroll);
handleScroll(); // Check on load
// Handle sticky CTA click
stickyBtn.addEventListener('click', () => {
const preorderSection = this.container.querySelector('.vida-drop__preorder');
if (preorderSection) {
preorderSection.scrollIntoView({ behavior: 'smooth' });
} else {
const productSection = this.container.querySelector('#product');
if (productSection) {
productSection.scrollIntoView({ behavior: 'smooth' });
}
}
});
}
}
// Initialize on DOMContentLoaded
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initVidaDrop);
} else {
initVidaDrop();
}
function initVidaDrop() {
const containers = document.querySelectorAll('.vida-drop');
containers.forEach(container => {
new VidaDrop(container);
});
}
// Reinitialize on Shopify section events
if (typeof Shopify !== 'undefined' && Shopify.designMode) {
document.addEventListener('shopify:section:load', (event) => {
const container = event.target.querySelector('.vida-drop');
if (container) {
new VidaDrop(container);
}
});
}
{
"name": "VIDA Drop",
"tag": "section",
"class": "section",
"settings": [
{
"type": "header",
"content": "Countdown Timer"
},
{
"type": "checkbox",
"id": "countdown_enable",
"label": "Enable countdown timer",
"default": false
},
{
"type": "select",
"id": "countdown_style",
"label": "Countdown style",
"options": [
{
"value": "ribbon",
"label": "Ribbon (sticky top)"
},
{
"value": "inline",
"label": "Inline (in hero)"
}
],
"default": "ribbon"
},
{
"type": "text",
"id": "countdown_label",
"label": "Countdown label",
"default": "Drop Ends In:"
},
{
"type": "text",
"id": "countdown_end_datetime",
"label": "End date & time",
"info": "Format: YYYY-MM-DD HH:MM:SS (24-hour format)"
},
{
"type": "header",
"content": "Hero Section"
},
{
"type": "image_picker",
"id": "hero_image",
"label": "Hero background image"
},
{
"type": "select",
"id": "hero_image_focal_point",
"label": "Image focal point",
"options": [
{
"value": "center center",
"label": "Center"
},
{
"value": "top center",
"label": "Top"
},
{
"value": "bottom center",
"label": "Bottom"
},
{
"value": "center left",
"label": "Left"
},
{
"value": "center right",
"label": "Right"
}
],
"default": "center center"
},
{
"type": "select",
"id": "hero_height",
"label": "Hero height",
"options": [
{
"value": "60vh",
"label": "Small (60% viewport)"
},
{
"value": "75vh",
"label": "Medium (75% viewport)"
},
{
"value": "100vh",
"label": "Large (Full viewport)"
}
],
"default": "75vh"
},
{
"type": "select",
"id": "overlay_bg_style",
"label": "Overlay background style",
"options": [
{
"value": "none",
"label": "None"
},
{
"value": "gradient",
"label": "Gradient overlay"
},
{
"value": "panel",
"label": "Panel background"
}
],
"default": "gradient"
},
{
"type": "select",
"id": "text_color_mode",
"label": "Text color",
"options": [
{
"value": "dark",
"label": "Dark (white text)"
},
{
"value": "light",
"label": "Light (dark text)"
}
],
"default": "dark"
},
{
"type": "select",
"id": "overlay_position",
"label": "Content position",
"options": [
{
"value": "center",
"label": "Center"
},
{
"value": "left",
"label": "Left"
},
{
"value": "right",
"label": "Right"
}
],
"default": "center"
},
{
"type": "text",
"id": "kicker",
"label": "Kicker text",
"default": "Limited Edition"
},
{
"type": "text",
"id": "hero_heading",
"label": "Heading",
"default": "New Drop: Product Name"
},
{
"type": "richtext",
"id": "hero_subheading",
"label": "Subheading"
},
{
"type": "text",
"id": "hero_cta_label",
"label": "Button label",
"default": "Shop This Drop"
},
{
"type": "url",
"id": "hero_cta_link",
"label": "Button link",
"info": "Leave blank to link to product section"
},
{
"type": "header",
"content": "Story & Pillars"
},
{
"type": "richtext",
"id": "story_richtext",
"label": "Story text"
},
{
"type": "text",
"id": "pillars_cta_label",
"label": "Pillars CTA label"
},
{
"type": "url",
"id": "pillars_cta_link",
"label": "Pillars CTA link"
},
{
"type": "header",
"content": "Product Features"
},
{
"type": "text",
"id": "features_heading",
"label": "Features section heading",
"default": "What Makes This Special"
},
{
"type": "color_scheme",
"id": "features_color_scheme",
"label": "Features color scheme",
"default": "scheme-1"
},
{
"type": "text",
"id": "buy_cta_label",
"label": "Buy button label",
"default": "Pre-Order Now"
},
{
"type": "url",
"id": "buy_cta_link",
"label": "Buy button link"
},
{
"type": "header",
"content": "Pre-Order Panel"
},
{
"type": "checkbox",
"id": "preorder_enable",
"label": "Enable pre-order panel",
"default": true
},
{
"type": "product",
"id": "preorder_product",
"label": "Pre-order product"
},
{
"type": "text",
"id": "preorder_badge_text",
"label": "Badge text",
"default": "Pre-Order"
},
{
"type": "text",
"id": "preorder_start_datetime",
"label": "Pre-order start date & time",
"info": "Format: YYYY-MM-DD HH:MM:SS"
},
{
"type": "text",
"id": "preorder_end_datetime",
"label": "Pre-order end date & time",
"info": "Format: YYYY-MM-DD HH:MM:SS"
},
{
"type": "number",
"id": "preorder_quantity_cap",
"label": "Quantity cap",
"info": "Maximum number of pre-orders available",
"default": 100
},
{
"type": "select",
"id": "preorder_price_mode",
"label": "Pricing mode",
"options": [
{
"value": "standard",
"label": "Standard product price"
},
{
"value": "fixed",
"label": "Fixed pre-order price"
},
{
"value": "percent_off",
"label": "Percentage discount"
},
{
"value": "amount_off",
"label": "Amount off"
}
],
"default": "standard"
},
{
"type": "number",
"id": "preorder_price",
"label": "Fixed pre-order price (in cents)",
"info": "Only applies when 'Fixed pre-order price' is selected"
},
{
"type": "number",
"id": "preorder_discount_percent",
"label": "Discount percentage",
"info": "Only applies when 'Percentage discount' is selected"
},
{
"type": "number",
"id": "preorder_discount_amount",
"label": "Discount amount (in cents)",
"info": "Only applies when 'Amount off' is selected"
},
{
"type": "checkbox",
"id": "preorder_compare_at_show",
"label": "Show compare at price",
"default": true
},
{
"type": "text",
"id": "preorder_ship_eta",
"label": "Shipping ETA",
"default": "Ships in 4-6 weeks"
},
{
"type": "text",
"id": "preorder_note",
"label": "Pre-order note"
},
{
"type": "text",
"id": "preorder_cta_label",
"label": "Pre-order button label",
"default": "Pre-Order Now"
},
{
"type": "header",
"content": "Reviews Section"
},
{
"type": "text",
"id": "reviews_heading",
"label": "Reviews heading"
},
{
"type": "color_scheme",
"id": "reviews_color_scheme",
"label": "Reviews color scheme",
"default": "scheme-2"
},
{
"type": "header",
"content": "Other Drops"
},
{
"type": "text",
"id": "other_drops_heading",
"label": "Other drops heading",
"default": "More Drops"
},
{
"type": "color_scheme",
"id": "other_drops_color_scheme",
"label": "Other drops color scheme",
"default": "scheme-1"
},
{
"type": "header",
"content": "About VIDA Drop"
},
{
"type": "text",
"id": "about_heading",
"label": "About heading",
"default": "About VIDA Drop"
},
{
"type": "richtext",
"id": "about_richtext",
"label": "About text"
},
{
"type": "color_scheme",
"id": "about_color_scheme",
"label": "About color scheme",
"default": "scheme-1"
},
{
"type": "checkbox",
"id": "show_email_capture",
"label": "Show email signup",
"default": true
},
{
"type": "header",
"content": "Section Settings"
},
{
"type": "color_scheme",
"id": "color_scheme",
"label": "Color scheme",
"default": "scheme-1"
}
],
"blocks": [
{
"type": "pillar",
"name": "Pillar",
"limit": 3,
"settings": [
{
"type": "image_picker",
"id": "pillar_icon",
"label": "Icon"
},
{
"type": "text",
"id": "pillar_title",
"label": "Title",
"default": "Pillar Title"
},
{
"type": "textarea",
"id": "pillar_text",
"label": "Text",
"default": "Describe this pillar value or feature."
}
]
},
{
"type": "gallery_image",
"name": "Gallery Image",
"settings": [
{
"type": "image_picker",
"id": "gallery_image",
"label": "Image"
},
{
"type": "text",
"id": "gallery_alt",
"label": "Image alt text"
}
]
},
{
"type": "feature",
"name": "Product Feature",
"settings": [
{
"type": "image_picker",
"id": "feature_icon",
"label": "Icon"
},
{
"type": "text",
"id": "feature_title",
"label": "Title",
"default": "Feature Title"
},
{
"type": "textarea",
"id": "feature_text",
"label": "Description",
"default": "Describe this product feature."
}
]
},
{
"type": "review",
"name": "Customer Review",
"settings": [
{
"type": "range",
"id": "review_stars",
"label": "Star rating",
"min": 1,
"max": 5,
"step": 1,
"default": 5
},
{
"type": "textarea",
"id": "review_text",
"label": "Review text"
},
{
"type": "text",
"id": "review_author",
"label": "Author name"
},
{
"type": "text",
"id": "review_location",
"label": "Location"
}
]
},
{
"type": "other_drop",
"name": "Other Drop Card",
"settings": [
{
"type": "image_picker",
"id": "drop_image",
"label": "Drop image"
},
{
"type": "text",
"id": "drop_title",
"label": "Drop title",
"default": "Drop Name"
},
{
"type": "url",
"id": "drop_link",
"label": "Drop link"
},
{
"type": "checkbox",
"id": "drop_sold_out",
"label": "Mark as sold out",
"default": false
}
]
}
],
"presets": [
{
"name": "VIDA Drop",
"blocks": [
{
"type": "pillar"
},
{
"type": "pillar"
},
{
"type": "pillar"
},
{
"type": "feature"
},
{
"type": "feature"
},
{
"type": "feature"
}
]
}
]
}