/**
* Padrão de design: Module Pattern
* – encapsula estado e funções
* – expõe apenas um método init()
*
* Organização estilo “Controller”:
* – cacheDOM() pega elementos
* – bindEvents() registra eventos
* – handlers/controladores orquestram ações
* – services (aqui: storage/format/time) são utilitários puros
*/
const LandingPage = (() => {
// ====== Estado privado ======
const state = {
// Ajuste se quiser timezone específico no servidor.
// Aqui: data local do navegador (04/04 às 08:00).
eventDate: new Date(new Date().getFullYear(), 3, 4, 8, 0, 0), // mês 3 = abril
countdownTimer: null
};
// ====== Cache de DOM ======
const dom = {};
function cacheDOM() {
dom.menuBtn = document.querySelector(“[data-menu-btn]”);
dom.mobileMenu = document.querySelector(“[data-mobile-menu]”);
dom.openModalBtns = document.querySelectorAll(“[data-open-modal]”);
dom.modal = document.querySelector(“[data-modal]”);
dom.closeModalBtns = document.querySelectorAll(“[data-close-modal]”);
dom.form = document.querySelector(“[data-form]”);
dom.formStatus = document.querySelector(“[data-form-status]”);
dom.cdDays = document.querySelector(“[data-cd-days]”);
dom.cdHours = document.querySelector(“[data-cd-hours]”);
dom.cdMinutes = document.querySelector(“[data-cd-minutes]”);
dom.cdSeconds = document.querySelector(“[data-cd-seconds]”);
dom.year = document.querySelector(“[data-year]”);
}
// ====== Serviços/Utilitários (funções puras) ======
const pad2 = (n) => String(n).padStart(2, “0”);
function diffParts(targetDate) {
const now = new Date().getTime();
const target = targetDate.getTime();
const diff = Math.max(0, target – now);
const totalSeconds = Math.floor(diff / 1000);
const days = Math.floor(totalSeconds / 86400);
const hours = Math.floor((totalSeconds % 86400) / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
return { diff, days, hours, minutes, seconds };
}
const storage = {
key: “pp_lead”,
save(data) {
localStorage.setItem(this.key, JSON.stringify(data));
},
load() {
try { return JSON.parse(localStorage.getItem(this.key)); }
catch { return null; }
}
};
// ====== UI helpers ======
function setCountdownUI({ days, hours, minutes, seconds }) {
if (!dom.cdDays) return;
dom.cdDays.textContent = pad2(days);
dom.cdHours.textContent = pad2(hours);
dom.cdMinutes.textContent = pad2(minutes);
dom.cdSeconds.textContent = pad2(seconds);
}
function openModal() {
dom.modal.classList.add(“is-open”);
dom.modal.setAttribute(“aria-hidden”, “false”);
document.body.style.overflow = “hidden”;
// foco inicial (acessibilidade)
const firstInput = dom.modal.querySelector(“input”);
if (firstInput) firstInput.focus();
}
function closeModal() {
dom.modal.classList.remove(“is-open”);
dom.modal.setAttribute(“aria-hidden”, “true”);
document.body.style.overflow = “”;
}
function toggleMobileMenu() {
dom.mobileMenu.classList.toggle(“is-open”);
}
// ====== Controllers (event handlers) ======
function handleKeyDown(e) {
if (e.key === “Escape” && dom.modal.classList.contains(“is-open”)) {
closeModal();
}
}
function handleFormSubmit(e) {
e.preventDefault();
dom.formStatus.textContent = “”;
const formData = new FormData(dom.form);
const name = String(formData.get(“name”) || “”).trim();
const email = String(formData.get(“email”) || “”).trim();
const whatsapp = String(formData.get(“whatsapp”) || “”).trim();
if (name.length < 2) {
dom.formStatus.textContent = "Por favor, informe seu nome.";
return;
}
if (!email.includes("@") || email.length < 6) {
dom.formStatus.textContent = "Por favor, informe um email válido.";
return;
}
// Simula envio (troque por fetch() para sua API/CRM)
const payload = { name, email, whatsapp, createdAt: new Date().toISOString() };
storage.save(payload);
dom.formStatus.textContent = "Inscrição confirmada! ✅ Você receberá o link da aula.";
dom.form.reset();
// Fecha modal depois de um tempinho
setTimeout(closeModal, 1200);
}
function startCountdown() {
// Render imediato
setCountdownUI(diffParts(state.eventDate));
// Atualiza a cada 1s
state.countdownTimer = setInterval(() => {
const parts = diffParts(state.eventDate);
setCountdownUI(parts);
// Se chegou no evento, para o timer
if (parts.diff <= 0) clearInterval(state.countdownTimer);
}, 1000);
}
function hydrateFormIfLeadExists() {
const lead = storage.load();
if (!lead || !dom.form) return;
const nameInput = dom.form.querySelector('input[name="name"]');
const emailInput = dom.form.querySelector('input[name="email"]');
const whatsappInput = dom.form.querySelector('input[name="whatsapp"]');
if (nameInput && lead.name) nameInput.value = lead.name;
if (emailInput && lead.email) emailInput.value = lead.email;
if (whatsappInput && lead.whatsapp) whatsappInput.value = lead.whatsapp;
}
function bindEvents() {
dom.menuBtn?.addEventListener("click", toggleMobileMenu);
dom.openModalBtns.forEach(btn => btn.addEventListener(“click”, openModal));
dom.closeModalBtns.forEach(btn => btn.addEventListener(“click”, closeModal));
dom.modal?.addEventListener(“click”, (e) => {
// clique fora do conteúdo fecha (overlay)
if (e.target.matches(“[data-close-modal]”)) closeModal();
});
document.addEventListener(“keydown”, handleKeyDown);
dom.form?.addEventListener(“submit”, handleFormSubmit);
}
function init() {
cacheDOM();
bindEvents();
dom.year.textContent = String(new Date().getFullYear());
hydrateFormIfLeadExists();
startCountdown();
}
return { init };
})();
document.addEventListener(“DOMContentLoaded”, LandingPage.init);