/* ========================================================================== M GALA — Public site shared behavior (header/footer, voting, sharing, etc.) ========================================================================== */ (function () { "use strict"; var Store = window.MGala.Store; /* ---------- initials-avatar fallback for broken photo URLs ---------- */ function initialsAvatar(name) { var initials = (name || "?").split(" ").filter(Boolean).slice(0, 2).map(function (s) { return s[0]; }).join("").toUpperCase(); var svg = '' + '' + '' + '' + '' + initials + '' + ''; return "data:image/svg+xml;base64," + btoa(svg); } window.MGala.attachImgFallback = function (img, name) { img.addEventListener("error", function onErr() { img.removeEventListener("error", onErr); img.src = initialsAvatar(name); }); }; /* ---------------------------- toast ---------------------------- */ var toastTimer; window.MGala.toast = function (msg, icon) { var el = document.getElementById("mg-toast"); if (!el) { el = document.createElement("div"); el.id = "mg-toast"; el.className = "toast"; document.body.appendChild(el); } el.innerHTML = '' + msg + ""; el.classList.add("show"); clearTimeout(toastTimer); toastTimer = setTimeout(function () { el.classList.remove("show"); }, 3200); }; /* ---------------------------- header / footer ---------------------------- */ var CATS_CACHE = null; function cats() { return CATS_CACHE || (CATS_CACHE = Store.getCategories()); } window.MGala.renderHeader = function (root, active) { var host = document.getElementById(root || "site-header"); if (!host) return; host.innerHTML = '' + '
' + '' + '' + 'Nominate a Woman' + 'Get Tickets' + '
'; var burger = document.getElementById("mg-hamburger"); var menu = document.getElementById("mg-mobile-menu"); var close = document.getElementById("mg-menu-close"); if (burger) burger.addEventListener("click", function () { menu.classList.add("open"); }); if (close) close.addEventListener("click", function () { menu.classList.remove("open"); }); menu.querySelectorAll("a").forEach(function (a) { a.addEventListener("click", function () { menu.classList.remove("open"); }); }); }; function navLink(href, label, active) { var isActive = (label === "Home" && active === "home") || (label === "Categories" && active === "categories") || (label === "Nominees" && active === "nominees"); return '" + label + ""; } window.MGala.renderFooter = function (root) { var host = document.getElementById(root || "site-footer"); if (!host) return; host.innerHTML = '
' + '
' + '

Know a remarkable woman?

' + '

Nominate her today and help her get the recognition she deserves.

' + 'Nominate a Woman ' + '
' + '' + '
'; }; /* ---------------------------- voting ---------------------------- */ window.MGala.wireVoteButtons = function (container) { (container || document).querySelectorAll("[data-vote-id]").forEach(function (btn) { var id = btn.getAttribute("data-vote-id"); refreshVoteBtn(btn, id); btn.addEventListener("click", function (e) { e.preventDefault(); if (Store.hasVoted(id)) { window.MGala.toast("You already voted for her today — come back tomorrow for another vote!", "fa-heart"); return; } if (btn.disabled) return; btn.disabled = true; Store.vote(id).then(function (ok) { btn.disabled = false; if (ok) { window.MGala.toast("Thanks for your vote!", "fa-heart"); refreshVoteBtn(btn, id); document.querySelectorAll('[data-votes-for="' + id + '"]').forEach(function (el) { el.textContent = Store.fmt(Store.getNominee(id).votes); }); } else { window.MGala.toast("You already voted for her today — come back tomorrow for another vote!", "fa-heart"); } }); }); }); }; function refreshVoteBtn(btn, id) { if (Store.hasVoted(id)) { btn.innerHTML = ' Voted'; btn.classList.add("voted"); } else { btn.innerHTML = btn.getAttribute("data-label") || ' Vote'; } } /* ---------------------------- sharing ---------------------------- */ function absoluteNomineeUrl(id) { var dir = window.location.pathname.replace(/[^/]*$/, ""); return window.location.origin + dir + "nominee.html?id=" + encodeURIComponent(id); } function legacyCopy(text) { try { var ta = document.createElement("textarea"); ta.value = text; ta.setAttribute("readonly", ""); ta.style.position = "fixed"; ta.style.top = "-1000px"; ta.style.opacity = "0"; document.body.appendChild(ta); ta.focus(); ta.select(); var ok = document.execCommand("copy"); document.body.removeChild(ta); return ok; } catch (e) { return false; } } function copyText(text, onDone) { if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(function () { onDone(true); }).catch(function () { onDone(legacyCopy(text)); }); } else { onDone(legacyCopy(text)); } } /* ---------------------------- share modal ---------------------------- */ function ensureShareModal() { var el = document.getElementById("mg-share-backdrop"); if (el) return el; el = document.createElement("div"); el.id = "mg-share-backdrop"; el.className = "share-backdrop"; el.innerHTML = '
' + '' + '
Share This Page
' + '

' + '' + '
' + '
'; document.body.appendChild(el); el.addEventListener("click", function (e) { if (e.target === el) closeShareModal(); }); document.getElementById("mg-share-close").addEventListener("click", closeShareModal); document.getElementById("mg-share-copy").addEventListener("click", function () { var input = document.getElementById("mg-share-url"); input.select(); copyText(input.value, function (ok) { window.MGala.toast(ok ? "Link copied!" : "Couldn't auto-copy — the link above is selected, just copy it manually.", ok ? "fa-check" : "fa-triangle-exclamation"); }); }); return el; } function closeShareModal() { var el = document.getElementById("mg-share-backdrop"); if (el) el.classList.remove("open"); } window.MGala.share = function (name, id) { var url = absoluteNomineeUrl(id); var text = "Vote for " + name + " at M Gala!"; var modal = ensureShareModal(); document.getElementById("mg-share-name").textContent = name; document.getElementById("mg-share-url").value = url; var platforms = [ { key: "whatsapp", label: "WhatsApp", icon: "fa-brands fa-whatsapp", href: "https://wa.me/?text=" + encodeURIComponent(text + " " + url) }, { key: "sms", label: "Text Message", icon: "fa-solid fa-comment-sms", href: "sms:?&body=" + encodeURIComponent(text + " " + url) }, { key: "facebook", label: "Facebook", icon: "fa-brands fa-facebook-f", href: "https://www.facebook.com/sharer/sharer.php?u=" + encodeURIComponent(url) }, { key: "twitter", label: "X / Twitter", icon: "fa-brands fa-x-twitter", href: "https://twitter.com/intent/tweet?text=" + encodeURIComponent(text) + "&url=" + encodeURIComponent(url) }, { key: "email", label: "Email", icon: "fa-regular fa-envelope", href: "mailto:?subject=" + encodeURIComponent("Vote for " + name + " at M Gala") + "&body=" + encodeURIComponent(text + " " + url) } ]; document.getElementById("mg-share-platforms").innerHTML = platforms.map(function (p) { return ' ' + p.label + ''; }).join(""); modal.classList.add("open"); if (navigator.share) { navigator.share({ title: text, text: text, url: url }).then(function () { closeShareModal(); }).catch(function () { /* user cancelled or unsupported — modal stays open as the reliable fallback */ }); } }; /* ---------------------------- scroll reveal ---------------------------- */ window.MGala.initReveal = function () { var els = document.querySelectorAll(".reveal"); if (!("IntersectionObserver" in window)) { els.forEach(function (e) { e.classList.add("in"); }); return; } var io = new IntersectionObserver(function (entries) { entries.forEach(function (en) { if (en.isIntersecting) { en.target.classList.add("in"); io.unobserve(en.target); } }); }, { threshold: 0.12 }); els.forEach(function (e) { io.observe(e); }); }; /* ---------------------------- card builder ---------------------------- */ window.MGala.nomineeCardHTML = function (n, opts) { opts = opts || {}; var cat = Store.getCategory(n.category); return ( '
' + (opts.rank ? '
#' + opts.rank + "
" : "") + '' + n.name + '' + '
' + '
' + n.name + "
" + '
' + (cat ? cat.name : "") + "
" + '
' + '
' + Store.fmt(n.votes) + "
" + '' + "
" + "
" + "
" ); }; document.addEventListener("DOMContentLoaded", function () { document.querySelectorAll("img[data-name]").forEach(function (img) { window.MGala.attachImgFallback(img, img.getAttribute("data-name")); }); }); })();