// Form data object const formData = { userDetails: {} }; // Current step tracking let currentStep = 1; // Countries and states data const countries = [ { code: 'US', name: 'United States' }, { code: 'CA', name: 'Canada' }, { code: 'GB', name: 'United Kingdom' }, { code: 'AU', name: 'Australia' }, { code: 'IN', name: 'India' }, { code: 'DE', name: 'Germany' }, { code: 'FR', name: 'France' }, { code: 'BR', name: 'Brazil' }, { code: 'JP', name: 'Japan' }, { code: 'CN', name: 'China' } ]; const states = { 'US': [ { code: 'CA', name: 'California' }, { code: 'TX', name: 'Texas' }, { code: 'FL', name: 'Florida' }, { code: 'NY', name: 'New York' }, { code: 'IL', name: 'Illinois' }, { code: 'PA', name: 'Pennsylvania' }, { code: 'OH', name: 'Ohio' }, { code: 'GA', name: 'Georgia' }, { code: 'NC', name: 'North Carolina' }, { code: 'MI', name: 'Michigan' } ], 'CA': [ { code: 'ON', name: 'Ontario' }, { code: 'QC', name: 'Quebec' }, { code: 'BC', name: 'British Columbia' }, { code: 'AB', name: 'Alberta' }, { code: 'MB', name: 'Manitoba' }, { code: 'SK', name: 'Saskatchewan' } ], 'GB': [ { code: 'ENG', name: 'England' }, { code: 'SCT', name: 'Scotland' }, { code: 'WLS', name: 'Wales' }, { code: 'NIR', name: 'Northern Ireland' } ], 'AU': [ { code: 'NSW', name: 'New South Wales' }, { code: 'VIC', name: 'Victoria' }, { code: 'QLD', name: 'Queensland' }, { code: 'WA', name: 'Western Australia' }, { code: 'SA', name: 'South Australia' }, { code: 'TAS', name: 'Tasmania' } ], 'IN': [ { code: 'MH', name: 'Maharashtra' }, { code: 'TN', name: 'Tamil Nadu' }, { code: 'UP', name: 'Uttar Pradesh' }, { code: 'KA', name: 'Karnataka' }, { code: 'GJ', name: 'Gujarat' }, { code: 'RJ', name: 'Rajasthan' } ], 'DE': [ { code: 'BW', name: 'Baden-Württemberg' }, { code: 'BY', name: 'Bavaria' }, { code: 'BE', name: 'Berlin' }, { code: 'HB', name: 'Bremen' }, { code: 'HH', name: 'Hamburg' }, { code: 'HE', name: 'Hesse' } ], 'FR': [ { code: 'ARA', name: 'Auvergne-Rhône-Alpes' }, { code: 'BFC', name: 'Bourgogne-Franche-Comté' }, { code: 'BRE', name: 'Brittany' }, { code: 'CVL', name: 'Centre-Val de Loire' }, { code: 'COR', name: 'Corsica' }, { code: 'GES', name: 'Grand Est' } ], 'BR': [ { code: 'SP', name: 'São Paulo' }, { code: 'RJ', name: 'Rio de Janeiro' }, { code: 'MG', name: 'Minas Gerais' }, { code: 'BA', name: 'Bahia' }, { code: 'RS', name: 'Rio Grande do Sul' }, { code: 'PR', name: 'Paraná' } ], 'JP': [ { code: 'TK', name: 'Tokyo' }, { code: 'OS', name: 'Osaka' }, { code: 'KY', name: 'Kyoto' }, { code: 'HK', name: 'Hokkaido' }, { code: 'OK', name: 'Okinawa' }, { code: 'KN', name: 'Kanagawa' } ], 'CN': [ { code: 'BJ', name: 'Beijing' }, { code: 'SH', name: 'Shanghai' }, { code: 'TJ', name: 'Tianjin' }, { code: 'CQ', name: 'Chongqing' }, { code: 'GD', name: 'Guangdong' }, { code: 'JS', name: 'Jiangsu' } ] }; // Initialize the form document.addEventListener('DOMContentLoaded', function() { // Populate country dropdown const countrySelect = document.getElementById('country'); countrySelect.innerHTML = ''; countries.forEach(country => { const option = document.createElement('option'); option.value = country.code; option.textContent = country.name; countrySelect.appendChild(option); }); // Add event listener for country change countrySelect.addEventListener('change', function() { const countryCode = this.value; const stateSelect = document.getElementById('state'); // Show loading document.getElementById('state-loading').style.display = 'block'; // Clear current states stateSelect.innerHTML = ''; // Simulate API delay setTimeout(() => { if (countryCode && states[countryCode]) { states[countryCode].forEach(state => { const option = document.createElement('option'); option.value = state.code; option.textContent = state.name; stateSelect.appendChild(option); }); } // Hide loading document.getElementById('state-loading').style.display = 'none'; }, 500); }); // Add input event listeners to handle label animation document.querySelectorAll('.input-field').forEach(input => { input.addEventListener('input', function() { if (this.value) { this.nextElementSibling.style.top = '4px'; this.nextElementSibling.style.fontSize = '12px'; this.nextElementSibling.style.transform = 'none'; } else { this.nextElementSibling.style.top = '50%'; this.nextElementSibling.style.fontSize = '14px'; this.nextElementSibling.style.transform = 'translateY(-50%)'; } }); input.addEventListener('focus', function() { this.nextElementSibling.style.top = '4px'; this.nextElementSibling.style.fontSize = '12px'; this.nextElementSibling.style.transform = 'none'; }); input.addEventListener('blur', function() { if (!this.value) { this.nextElementSibling.style.top = '50%'; this.nextElementSibling.style.fontSize = '14px'; this.nextElementSibling.style.transform = 'translateY(-50%)'; } }); }); // Handle select field label animation document.querySelectorAll('.select-field').forEach(select => { select.addEventListener('change', function() { if (this.value) { this.nextElementSibling.style.top = '4px'; this.nextElementSibling.style.fontSize = '12px'; this.nextElementSibling.style.transform = 'none'; } else { this.nextElementSibling.style.top = '50%'; this.nextElementSibling.style.fontSize = '14px'; this.nextElementSibling.style.transform = 'translateY(-50%)'; } }); select.addEventListener('focus', function() { this.nextElementSibling.style.top = '4px'; this.nextElementSibling.style.fontSize = '12px'; this.nextElementSibling.style.transform = 'none'; }); select.addEventListener('blur', function() { if (!this.value) { this.nextElementSibling.style.top = '50%'; this.nextElementSibling.style.fontSize = '14px'; this.nextElementSibling.style.transform = 'translateY(-50%)'; } }); }); // Step navigation for desktop document.querySelectorAll('.step').forEach(step => { step.addEventListener('click', function() { const stepNum = parseInt(this.getAttribute('data-step')); if (stepNum <= currentStep || stepNum === getMaxCompletedStep() + 1) { goToStep(stepNum); } }); }); // Step navigation for mobile document.querySelectorAll('.mobile-step').forEach(step => { step.addEventListener('click', function() { const stepNum = parseInt(this.getAttribute('data-step')); if (stepNum <= currentStep || stepNum === getMaxCompletedStep() + 1) { goToStep(stepNum); } }); }); }); // Function to navigate to any step (for tab navigation) function goToStep(step) { // Only allow navigation to completed steps or the next step if (step > currentStep && step > getMaxCompletedStep() + 1) { return; } // Hide current step document.getElementById(`step-${currentStep}`).classList.remove('active'); document.querySelectorAll(`.step[data-step="${currentStep}"]`).forEach(el => { el.classList.remove('active'); }); document.querySelectorAll(`.mobile-step[data-step="${currentStep}"]`).forEach(el => { el.classList.remove('active'); }); // Show target step document.getElementById(`step-${step}`).classList.add('active'); document.querySelectorAll(`.step[data-step="${step}"]`).forEach(el => { el.classList.add('active'); }); document.querySelectorAll(`.mobile-step[data-step="${step}"]`).forEach(el => { el.classList.add('active'); }); currentStep = step; } // Function to get the maximum completed step function getMaxCompletedStep() { const completedSteps = document.querySelectorAll('.step.completed'); let maxStep = 0; completedSteps.forEach(step => { const stepNum = parseInt(step.getAttribute('data-step')); if (stepNum > maxStep) maxStep = stepNum; }); return maxStep; } // Function to navigate to next step function nextStep(step) { // Validate current step before proceeding if (!validateStep(currentStep)) { return; } // Save current step data saveStepData(currentStep); // Mark current step as completed document.querySelectorAll(`.step[data-step="${currentStep}"]`).forEach(el => { el.classList.add('completed'); const stepNumber = el.querySelector('.step-number'); stepNumber.textContent = '✓'; stepNumber.style.backgroundColor = '#000000'; stepNumber.style.borderColor = '#000000'; stepNumber.style.color = 'white'; }); document.querySelectorAll(`.mobile-step[data-step="${currentStep}"]`).forEach(el => { el.classList.add('completed'); const stepNumber = el.querySelector('.step-number'); stepNumber.textContent = '✓'; stepNumber.style.backgroundColor = '#000000'; stepNumber.style.borderColor = '#000000'; stepNumber.style.color = 'white'; }); // Hide current step document.getElementById(`step-${currentStep}`).classList.remove('active'); document.querySelectorAll(`.step[data-step="${currentStep}"]`).forEach(el => { el.classList.remove('active'); }); document.querySelectorAll(`.mobile-step[data-step="${currentStep}"]`).forEach(el => { el.classList.remove('active'); }); // Show next step document.getElementById(`step-${step}`).classList.add('active'); document.querySelectorAll(`.step[data-step="${step}"]`).forEach(el => { el.classList.add('active'); }); document.querySelectorAll(`.mobile-step[data-step="${step}"]`).forEach(el => { el.classList.add('active'); }); currentStep = step; } // Function to navigate to previous step function prevStep(step) { // Hide current step document.getElementById(`step-${currentStep}`).classList.remove('active'); document.querySelectorAll(`.step[data-step="${currentStep}"]`).forEach(el => { el.classList.remove('active'); }); document.querySelectorAll(`.mobile-step[data-step="${currentStep}"]`).forEach(el => { el.classList.remove('active'); }); // Show previous step document.getElementById(`step-${step}`).classList.add('active'); document.querySelectorAll(`.step[data-step="${step}"]`).forEach(el => { el.classList.add('active'); }); document.querySelectorAll(`.mobile-step[data-step="${step}"]`).forEach(el => { el.classList.add('active'); }); currentStep = step; } // Function to validate current step function validateStep(step) { let isValid = true; const form = document.getElementById(getFormId(step)); if (form) { // For account setup step if (step === 1) { const email = document.getElementById('email').value; const password = document.getElementById('password').value; const confirmPassword = document.getElementById('confirmPassword').value; // Email validation if (!validateEmail(email)) { alert('Please enter a valid email address'); isValid = false; } // Password validation if (password.length < 8) { alert('Password must be at least 8 characters long'); isValid = false; } if (password !== confirmPassword) { document.getElementById('password-match-error').style.display = 'block'; isValid = false; } else { document.getElementById('password-match-error').style.display = 'none'; } } // For personal information step if (step === 2) { const firstName = document.getElementById('firstName').value; if (!firstName) { document.getElementById('profile-incomplete').style.display = 'block'; isValid = false; } else { document.getElementById('profile-incomplete').style.display = 'none'; } // Age validation const age = document.getElementById('age').value; if (age && (age < 18 || age > 100)) { alert('You must be 18 years or older to register'); isValid = false; } // Country and state validation const country = document.getElementById('country').value; const state = document.getElementById('state').value; if (!country) { alert('Please select your country'); isValid = false; } if (!state) { alert('Please select your state/region'); isValid = false; } // Validate other required fields const requiredFields = form.querySelectorAll('[required]'); requiredFields.forEach(field => { if (!field.value.trim()) { isValid = false; field.style.border = '1px solid #ef4444'; } else { field.style.border = ''; } }); } // For payment step if (step === 4) { const selectedPayment = document.querySelector('.payment-option.selected'); if (!selectedPayment) { alert('Please select a payment method'); isValid = false; } else { const paymentMethod = selectedPayment.getAttribute('onclick').match(/'([^']+)'/)[1]; if (paymentMethod === 'payoneer') { const payoneerAccount = document.getElementById('payoneerAccount').value; if (!payoneerAccount) { alert('Please enter your Payoneer account number'); isValid = false; } } else if (paymentMethod === 'veem') { const veemAccount = document.getElementById('veemAccount').value; if (!veemAccount) { alert('Please enter your Veem account number'); isValid = false; } } } } // For other steps if (step !== 1 && step !== 2 && step !== 4) { const requiredFields = form.querySelectorAll('[required]'); requiredFields.forEach(field => { if (!field.value.trim()) { isValid = false; field.style.border = '1px solid #ef4444'; } else { field.style.border = ''; } }); } } return isValid; } // Email validation function function validateEmail(email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } // Function to get form ID based on step function getFormId(step) { switch(step) { case 1: return 'account-form'; case 2: return 'personal-form'; case 3: return 'contact-form'; case 4: return 'payment-form'; default: return ''; } } // Function to save step data to formData object function saveStepData(step) { switch(step) { case 1: formData.userDetails.email = document.getElementById('email').value; formData.userDetails.password = document.getElementById('password').value; break; case 2: formData.userDetails.firstName = document.getElementById('firstName').value; formData.userDetails.lastName = document.getElementById('lastName').value; formData.userDetails.age = document.getElementById('age').value; formData.userDetails.dob = document.getElementById('dob').value; formData.userDetails.address = document.getElementById('address').value; formData.userDetails.city = document.getElementById('city').value; formData.userDetails.state = document.getElementById('state').value; formData.userDetails.country = document.getElementById('country').value; break; case 3: formData.userDetails.phone = document.getElementById('phone').value; formData.userDetails.skype = document.getElementById('skype').value; break; case 4: const selectedPayment = document.querySelector('.payment-option.selected'); if (selectedPayment) { const paymentMethod = selectedPayment.getAttribute('onclick').match(/'([^']+)'/)[1]; formData.userDetails.paymentMethod = paymentMethod; if (paymentMethod === 'payoneer') { formData.userDetails.payoneerAccount = document.getElementById('payoneerAccount').value; } else if (paymentMethod === 'veem') { formData.userDetails.veemAccount = document.getElementById('veemAccount').value; } } break; } } // Function to select payment method function selectPaymentMethod(method) { // Remove selected class from all options document.querySelectorAll('.payment-option').forEach(option => { option.classList.remove('selected'); }); // Hide all payment details document.querySelectorAll('.payment-details').forEach(details => { details.style.display = 'none'; }); // Add selected class to clicked option event.currentTarget.classList.add('selected'); // Show appropriate payment details if (method === 'payoneer') { document.getElementById('payoneer-details').style.display = 'block'; } else if (method === 'veem') { document.getElementById('veem-details').style.display = 'block'; } } // Function to generate a strong password function generatePassword() { const length = 12; const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*"; let password = ""; // Ensure at least one of each required character type password += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(Math.random() * 26)]; password += "abcdefghijklmnopqrstuvwxyz"[Math.floor(Math.random() * 26)]; password += "0123456789"[Math.floor(Math.random() * 10)]; password += "!@#$%^&*"[Math.floor(Math.random() * 8)]; // Fill the rest randomly for (let i = password.length; i < length; i++) { password += charset.charAt(Math.floor(Math.random() * charset.length)); } // Shuffle the password password = password.split('').sort(() => 0.5 - Math.random()).join(''); // Set the password field document.getElementById('password').value = password; document.getElementById('confirmPassword').value = password; // Trigger input events to update UI document.getElementById('password').dispatchEvent(new Event('input')); document.getElementById('confirmPassword').dispatchEvent(new Event('input')); } // Function to toggle password visibility function togglePasswordVisibility() { const passwordField = document.getElementById('password'); const confirmField = document.getElementById('confirmPassword'); const toggleButton = document.querySelector('.password-toggle'); if (passwordField.type === 'password') { passwordField.type = 'text'; confirmField.type = 'text'; toggleButton.textContent = 'Hide Password'; } else { passwordField.type = 'password'; confirmField.type = 'password'; toggleButton.textContent = 'Show Password'; } } // Function to submit the form async function submitForm() { // Validate current step if (!validateStep(currentStep)) { return; } // Save current step data saveStepData(currentStep); // Show loading state const submitBtn = document.querySelector('#payment-form .btn-primary'); const originalText = submitBtn.textContent; submitBtn.textContent = 'Processing...'; submitBtn.disabled = true; try { // Send data to server using fetch // console.log('Submitting form data:', formData); const response = await fetch('/api/v1/va/register', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(formData) }); if (response.ok) { // Success - move to success step // Mark current step as completed document.querySelectorAll(`.step[data-step="${currentStep}"]`).forEach(el => { el.classList.add('completed'); const stepNumber = el.querySelector('.step-number'); stepNumber.textContent = '✓'; stepNumber.style.backgroundColor = '#000000'; stepNumber.style.borderColor = '#000000'; stepNumber.style.color = 'white'; }); document.querySelectorAll(`.mobile-step[data-step="${currentStep}"]`).forEach(el => { el.classList.add('completed'); const stepNumber = el.querySelector('.step-number'); stepNumber.textContent = '✓'; stepNumber.style.backgroundColor = '#000000'; stepNumber.style.borderColor = '#000000'; stepNumber.style.color = 'white'; }); nextStep(5); } else { // Handle server errors alert('There was an error submitting your registration. Please try again.'); } } catch (error) { // Handle network errors console.error('Error:', error); alert('There was a network error. Please check your connection and try again.'); } finally { // Restore button state submitBtn.textContent = originalText; submitBtn.disabled = false; } }