👋

Create your account

Already have an account? Sign In

OR
const phoneInput = document.getElementById('phone'); const countryCodeInput = document.getElementById('country_code'); const homeCountryInput = document.getElementById('home_country'); let phoneIntl = null; let syncPhoneMeta = () => {}; let phoneCountryTouched = false; const normalizePhone = () => { if (!phoneInput) return; phoneInput.value = phoneInput.value.replace(/^\s*0+/, ''); }; if (phoneInput && window.intlTelInput) { const initialIso = phoneInput.dataset.iso || 'us'; phoneIntl = window.intlTelInput(phoneInput, { initialCountry: initialIso, separateDialCode: true, preferredCountries: ['au', 'nz', 'gb', 'us'], dropdownContainer: phoneInput.closest('.field'), utilsScript: 'https://cdn.jsdelivr.net/npm/intl-tel-input@19.5.5/build/js/utils.js' }); syncPhoneMeta = () => { if (!phoneIntl) return; const data = phoneIntl.getSelectedCountryData(); countryCodeInput.value = data.dialCode ? `+${data.dialCode}` : ''; homeCountryInput.value = data.iso2 ? String(data.iso2).toUpperCase() : ''; }; phoneInput.addEventListener('countrychange', () => { phoneCountryTouched = true; syncPhoneMeta(); }); phoneInput.addEventListener('blur', normalizePhone); phoneInput.addEventListener('input', () => { if (phoneInput.value.trim() !== '') { phoneCountryTouched = true; } }); syncPhoneMeta(); ensureIpCountryFallback(); const form = phoneInput.closest('form'); if (form) { form.addEventListener('submit', syncPhoneMeta); } } const registerForm = document.querySelector('.login-form'); const confirmModal = document.getElementById('countryConfirmModal'); const selectModal = document.getElementById('countrySelectModal'); const creatingModal = document.getElementById('creatingAccountModal'); const detectedCountryName = document.getElementById('detectedCountryName'); const countrySelect = document.getElementById('home_country_select'); const confirmYesBtn = document.getElementById('confirmCountryYes'); const confirmNoBtn = document.getElementById('confirmCountryNo'); const confirmSelectBtn = document.getElementById('confirmCountrySelect'); const clientErrors = document.getElementById('clientErrors'); const loginBaseUrl = 'login.php'; let countryConfirmed = false; const openModal = (modal) => { if (!modal) return; modal.classList.add('active'); document.body.classList.add('modal-open'); }; const closeModal = (modal) => { if (!modal) return; modal.classList.remove('active'); if (!document.querySelector('.country-modal.active')) { document.body.classList.remove('modal-open'); } }; const showCreatingModal = () => { closeModal(confirmModal); closeModal(selectModal); if (creatingModal) { openModal(creatingModal); } }; const getDetectedCountry = () => { if (phoneIntl) { return phoneIntl.getSelectedCountryData(); } return { name: homeCountryInput.value || 'United States', iso2: 'us', dialCode: '' }; }; let emailExists = false; let emailCheckedValue = ''; let emailCheckInFlight = false; const proCodeInput = document.getElementById('ref_code'); const proCodeStatus = document.getElementById('proCodeStatus'); let proCodeValid = true; let proCodeCheckedValue = ''; let proCodeCheckInFlight = false; const updateEmailStatus = (email, exists) => { if (!emailStatus) return; emailStatus.textContent = ''; emailStatus.innerHTML = ''; emailStatus.style.color = ''; if (!exists) return; const sep = loginBaseUrl.includes('?') ? '&' : '?'; const loginLink = `${loginBaseUrl}${sep}email=${encodeURIComponent(email)}`; emailStatus.innerHTML = `An account with this email already exists. Sign In`; emailStatus.style.color = 'rgb(255 94 123)'; }; const updateProCodeStatus = (code, valid, name) => { if (!proCodeStatus) return; proCodeStatus.textContent = ''; proCodeStatus.style.color = ''; if (!code) { proCodeValid = true; return; } if (!valid) { proCodeStatus.textContent = 'Premium code is invalid.'; proCodeStatus.style.color = 'rgb(255 94 123)'; return; } const cleanName = (name || '').trim(); if (cleanName) { const suffix = /s$/i.test(cleanName) ? "'" : "'s"; proCodeStatus.textContent = `${cleanName}${suffix} Premium code is valid.`; } else { proCodeStatus.textContent = 'Premium code is valid.'; } proCodeStatus.style.color = 'rgb(86 221 121)'; }; const showClientErrors = (items) => { if (!clientErrors) return; clientErrors.innerHTML = ''; if (!items || !items.length) { clientErrors.style.display = 'none'; return; } items.forEach((msg) => { const line = document.createElement('div'); line.textContent = msg; clientErrors.appendChild(line); }); clientErrors.style.display = 'block'; }; const submitWithRecaptcha = async () => { if (!registerForm || window.isRegisterRecaptchaSubmitting && window.isRegisterRecaptchaSubmitting()) return; if (window.setRegisterRecaptchaSubmitting) window.setRegisterRecaptchaSubmitting(true); try { if (window.runRegisterRecaptcha) { await window.runRegisterRecaptcha(); } registerForm.submit(); } catch (err) { if (window.setRegisterRecaptchaSubmitting) window.setRegisterRecaptchaSubmitting(false); showClientErrors(['reCAPTCHA failed to load. Please try again.']); if (creatingModal) closeModal(creatingModal); } }; const validateRegisterForm = () => { const items = []; const firstName = document.getElementById('first_name'); const email = document.getElementById('email'); const gender = document.getElementById('gender'); const dob = document.getElementById('dob'); const pass = document.getElementById('password'); const confirm = document.getElementById('confirm'); const terms = document.getElementById('agree_terms'); if (!firstName || !firstName.value.trim()) items.push('First name is required.'); if (!email || !email.value.trim()) { items.push('Email is required.'); } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.value.trim())) { items.push('Email is not valid.'); } else if (emailExists && emailCheckedValue === email.value.trim().toLowerCase()) { items.push('An account with this email already exists.'); } if (proCodeInput) { const code = proCodeInput.value.trim().toUpperCase(); if (code && !proCodeValid && proCodeCheckedValue === code) { items.push('Premium code is invalid.'); } } if (!pass || !pass.value) { items.push('Password is required.'); } else if (pass.value.length < 8) { items.push('Password must be at least 8 characters.'); } if (pass && confirm && pass.value !== confirm.value) { items.push('Passwords do not match.'); } if (!gender || !gender.value) items.push('Gender is required.'); if (!dob || !dob.value) { items.push('Date of birth is required.'); } else { const dobDate = new Date(`${dob.value}T00:00:00`); if (!Number.isNaN(dobDate.getTime())) { const today = new Date(); let age = today.getFullYear() - dobDate.getFullYear(); const hasHadBirthday = (today.getMonth() > dobDate.getMonth()) || (today.getMonth() === dobDate.getMonth() && today.getDate() >= dobDate.getDate()); if (!hasHadBirthday) age -= 1; if (age < 13) { items.push('You must be 13 or older to create an account.'); } } } if (terms && !terms.checked) { items.push('Please accept the Terms of Service, Privacy Policy, and Cookie Policy.'); } return items; }; function ensureIpCountryFallback(){ if (!phoneIntl || phoneCountryTouched) return; if (phoneInput && phoneInput.value.trim() !== '') return; fetch('https://ipwho.is/?fields=success,country_code') .then((res) => res.json()) .then((data) => { const iso = (data && data.success && data.country_code) ? String(data.country_code).toLowerCase() : ''; if (!/^[a-z]{2}$/.test(iso)) return; const current = phoneIntl.getSelectedCountryData(); if (!current || current.iso2 !== iso) { phoneIntl.setCountry(iso); syncPhoneMeta(); } }) .catch(() => {}); } const checkEmailExists = async (email) => { if (emailCheckInFlight) return; emailCheckInFlight = true; try { const res = await fetch('php_includes/check_email.php?email=' + encodeURIComponent(email)); const data = await res.json(); emailExists = !!(data && data.exists); emailCheckedValue = email; updateEmailStatus(email, emailExists); } catch (e) { emailExists = false; emailCheckedValue = ''; updateEmailStatus('', false); } finally { emailCheckInFlight = false; } }; const checkProCode = async (code) => { if (proCodeCheckInFlight) return; proCodeCheckInFlight = true; try { const res = await fetch('php_includes/check_pro_code.php?code=' + encodeURIComponent(code)); const data = await res.json(); proCodeValid = !!(data && data.valid); proCodeCheckedValue = code; updateProCodeStatus(code, proCodeValid, data && data.name ? data.name : ''); } catch (e) { proCodeValid = false; proCodeCheckedValue = code; updateProCodeStatus(code, false, ''); } finally { proCodeCheckInFlight = false; } }; const buildCountrySelect = () => { if (!countrySelect) return; const data = (window.intlTelInputGlobals && window.intlTelInputGlobals.getCountryData) ? window.intlTelInputGlobals.getCountryData() : []; const preferred = ['au', 'nz', 'gb', 'us']; const preferredSet = new Set(preferred); const byName = data .filter((c) => !preferredSet.has(c.iso2)) .sort((a, b) => a.name.localeCompare(b.name)); const ordered = preferred.map((iso) => data.find((c) => c.iso2 === iso)).filter(Boolean).concat(byName); countrySelect.innerHTML = ''; ordered.forEach((c, idx) => { const opt = document.createElement('option'); opt.value = c.iso2; opt.textContent = c.name; if (idx === 0) opt.selected = false; countrySelect.appendChild(opt); }); }; const syncDetectedLabel = () => { const detected = getDetectedCountry(); if (detectedCountryName) { detectedCountryName.textContent = detected.name || 'your country'; } if (countrySelect) { const target = detected.iso2 || 'us'; countrySelect.value = target; } }; if (registerForm) { registerForm.addEventListener('input', () => showClientErrors([])); registerForm.addEventListener('submit', async (e) => { e.preventDefault(); normalizePhone(); syncPhoneMeta(); const emailValue = emailInput ? emailInput.value.trim().toLowerCase() : ''; if (emailValue && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(emailValue) && emailCheckedValue !== emailValue) { await checkEmailExists(emailValue); } const proCodeValue = proCodeInput ? proCodeInput.value.trim().toUpperCase() : ''; if (proCodeValue && proCodeCheckedValue !== proCodeValue) { await checkProCode(proCodeValue); } const errors = validateRegisterForm(); if (errors.length) { showClientErrors(errors); return; } showClientErrors([]); if (countryConfirmed) { showCreatingModal(); await submitWithRecaptcha(); return; } await ensureIpCountryFallback(); buildCountrySelect(); syncDetectedLabel(); openModal(confirmModal); }); } if (confirmYesBtn) { confirmYesBtn.addEventListener('click', () => { countryConfirmed = true; normalizePhone(); syncPhoneMeta(); showCreatingModal(); submitWithRecaptcha(); }); } if (confirmNoBtn) { confirmNoBtn.addEventListener('click', () => { closeModal(confirmModal); buildCountrySelect(); syncDetectedLabel(); openModal(selectModal); }); } if (confirmSelectBtn) { confirmSelectBtn.addEventListener('click', () => { const iso = countrySelect ? countrySelect.value : ''; if (!iso) return; if (phoneIntl) { phoneIntl.setCountry(iso); } syncPhoneMeta(); countryConfirmed = true; normalizePhone(); showCreatingModal(); submitWithRecaptcha(); }); } if (confirmModal) { confirmModal.addEventListener('click', (e) => { if (e.target === confirmModal) { closeModal(confirmModal); } }); } if (selectModal) { selectModal.addEventListener('click', (e) => { if (e.target === selectModal) { closeModal(selectModal); } }); } const emailInput = document.getElementById('email'); const emailStatus = document.getElementById('emailStatus'); emailInput.addEventListener('input', () => { emailExists = false; emailCheckedValue = ''; updateEmailStatus('', false); }); emailInput.addEventListener('blur', async ()=>{ const email = emailInput.value.trim().toLowerCase(); if (!email) return; await checkEmailExists(email); }); if (proCodeInput) { proCodeInput.addEventListener('input', () => { proCodeValid = true; proCodeCheckedValue = ''; updateProCodeStatus('', true, ''); }); proCodeInput.addEventListener('blur', async () => { const code = proCodeInput.value.trim().toUpperCase(); if (!code) { updateProCodeStatus('', true, ''); return; } await checkProCode(code); }); } const passInput = document.getElementById('password'); const confirmInput = document.getElementById('confirm'); const passStatus = document.getElementById('passStatus'); const confirmStatus = document.getElementById('confirmStatus'); function hasSpecial(str){ return /[^A-Za-z0-9]/.test(str); } passInput.addEventListener('blur', ()=>{ const v = passInput.value; if (!v) { passStatus.textContent = ''; return; } if (v.length < 8 || !hasSpecial(v)){ passStatus.textContent = 'Password must be more than 8 characters and contain one special character.'; passStatus.style.color = 'rgb(255 94 123)'; } else { passStatus.textContent = ''; passStatus.style.color = ''; } }); confirmInput.addEventListener('keyup', ()=>{ const p = passInput.value; const c = confirmInput.value; if (!p) { confirmStatus.textContent=''; return; } if (c.length >= p.length){ if (p === c){ confirmStatus.textContent = ''; confirmStatus.style.color = ''; } else { confirmStatus.textContent = 'Passwords do not match.'; confirmStatus.style.color = 'rgb(255 94 123)'; } } else { confirmStatus.textContent=''; confirmStatus.style.color = ''; } });