1(function() { 2 var API_URL = 'https://airshop.work/api/leads/shopboard-signup'; 3 var modal = document.getElementById('shopboard-signup-modal'); 4 var form = document.getElementById('shopboard-signup-form'); 5 var messageEl = document.getElementById('shopboard-signup-message'); 6 var emailInput = document.getElementById('shopboard-signup-email'); 7 var closeButtons = document.querySelectorAll('[data-shopboard-signup-close]'); 8 var triggerButtons = document.querySelectorAll('[data-shopboard-signup-open]'); 9 var lastActiveElement = null; 10 var formLoadTime = Date.now(); 11 12 if (!modal || !form || !messageEl || !emailInput || !triggerButtons.length) return; 13 14 function openModal() { 15 lastActiveElement = document.activeElement; 16 modal.hidden = false; 17 document.body.classList.add('shopboard-signup-open'); 18 messageEl.textContent = ''; 19 messageEl.className = 'shopboard-signup-message'; 20 window.setTimeout(function() { 21 emailInput.focus(); 22 }, 0); 23 } 24 25 function closeModal() { 26 modal.hidden = true; 27 document.body.classList.remove('shopboard-signup-open'); 28 29 if (lastActiveElement && typeof lastActiveElement.focus === 'function') { 30 lastActiveElement.focus(); 31 } 32 } 33 34 triggerButtons.forEach(function(button) { 35 button.addEventListener('click', openModal); 36 }); 37 38 closeButtons.forEach(function(button) { 39 button.addEventListener('click', closeModal); 40 }); 41 42 modal.addEventListener('click', function(event) { 43 if (event.target === modal) { 44 closeModal(); 45 } 46 }); 47 48 document.addEventListener('keydown', function(event) { 49 if (modal.hidden) { 50 return; 51 } 52 53 if (event.key === 'Escape') { 54 closeModal(); 55 } 56 57 if (event.key !== 'Tab') { 58 return; 59 } 60 61 var focusable = modal.querySelectorAll('button, input, [href], select, textarea, [tabindex]:not([tabindex="-1"])'); 62 if (!focusable.length) { 63 return; 64 } 65 66 var first = focusable[0]; 67 var last = focusable[focusable.length - 1]; 68 69 if (event.shiftKey && document.activeElement === first) { 70 event.preventDefault(); 71 last.focus(); 72 } else if (!event.shiftKey && document.activeElement === last) { 73 event.preventDefault(); 74 first.focus(); 75 } 76 }); 77 78 form.addEventListener('submit', async function(event) { 79 event.preventDefault(); 80 81 var submitBtn = form.querySelector('button[type="submit"]'); 82 var honeypot = form.querySelector('input[name="website"]'); 83 var email = emailInput.value.trim(); 84 85 if (honeypot && honeypot.value.trim()) { 86 return; 87 } 88 89 if (!email) { 90 messageEl.textContent = 'Please enter your email.'; 91 messageEl.className = 'shopboard-signup-message error'; 92 return; 93 } 94 95 submitBtn.disabled = true; 96 messageEl.textContent = ''; 97 messageEl.className = 'shopboard-signup-message'; 98 99 try { 100 var response = await fetch(API_URL, { 101 method: 'POST', 102 headers: { 'Content-Type': 'application/json' }, 103 body: JSON.stringify({ 104 email: email, 105 website: honeypot ? honeypot.value : '', 106 form_load_time: formLoadTime, 107 leadType: 'shopboard_signup', 108 topic: 'Shopboard' 109 }) 110 }); 111 112 var data = await response.json().catch(function() { 113 return {}; 114 }); 115 116 if (!response.ok) { 117 throw new Error(data.error || 'Something went wrong'); 118 } 119 120 messageEl.textContent = 'You are on the Shopboard update list.'; 121 messageEl.className = 'shopboard-signup-message success'; 122 form.reset(); 123 } catch (err) { 124 messageEl.textContent = err.message || 'Failed to sign up. Please try again.'; 125 messageEl.className = 'shopboard-signup-message error'; 126 } finally { 127 submitBtn.disabled = false;
128 } 129 }); 130})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.