Spaces:
Running
Running
Create a single-page, futuristic crypto-themed web app called “QuantumPay”. It should simulate a crypto payment flow (no real payments).
08bb856
verified
| document.addEventListener('DOMContentLoaded', function() { | |
| // DOM Elements | |
| const amountButtons = document.querySelectorAll('.amount-btn'); | |
| const currencyButtons = document.querySelectorAll('.currency-btn'); | |
| const walletInput = document.getElementById('walletAddress'); | |
| const addressError = document.getElementById('addressError'); | |
| const proceedBtn = document.getElementById('proceedBtn'); | |
| const paymentForm = document.getElementById('paymentForm'); | |
| const simulatedReturnBox = document.getElementById('simulatedReturnBox'); | |
| const returnAmountEl = document.getElementById('returnAmount'); | |
| const returnRateEl = document.getElementById('returnRate'); | |
| // Summary elements | |
| const summaryAmount = document.getElementById('summaryAmount'); | |
| const summaryCurrency = document.getElementById('summaryCurrency'); | |
| // Selected values | |
| let selectedAmount = null; | |
| let selectedCurrency = null; | |
| // Amount selection | |
| amountButtons.forEach(button => { | |
| button.addEventListener('click', function() { | |
| // Remove selected class from all buttons | |
| amountButtons.forEach(btn => btn.classList.remove('selected')); | |
| // Add selected class to clicked button | |
| this.classList.add('selected'); | |
| // Update selected amount | |
| selectedAmount = parseInt(this.dataset.value); | |
| document.getElementById('selectedAmount').value = selectedAmount; | |
| // Update summary | |
| summaryAmount.textContent = `$${selectedAmount}`; | |
| // Handle $50 special rule | |
| if (selectedAmount === 50) { | |
| const rate = (Math.random() * 20 + 20).toFixed(2); // 20-40% | |
| const returnAmount = (selectedAmount * rate / 100).toFixed(2); | |
| returnRateEl.textContent = `${rate}%`; | |
| returnAmountEl.textContent = `+$${returnAmount}`; | |
| simulatedReturnBox.classList.remove('hidden'); | |
| } else { | |
| simulatedReturnBox.classList.add('hidden'); | |
| } | |
| validateForm(); | |
| }); | |
| }); | |
| // Currency selection | |
| currencyButtons.forEach(button => { | |
| button.addEventListener('click', function() { | |
| // Remove selected class from all buttons | |
| currencyButtons.forEach(btn => btn.classList.remove('selected')); | |
| // Add selected class to clicked button | |
| this.classList.add('selected'); | |
| // Update selected currency | |
| selectedCurrency = this.dataset.value; | |
| document.getElementById('selectedCurrency').value = selectedCurrency; | |
| // Update summary | |
| summaryCurrency.textContent = selectedCurrency; | |
| // Clear previous validation | |
| addressError.classList.add('hidden'); | |
| walletInput.classList.remove('border-red-500'); | |
| validateForm(); | |
| }); | |
| }); | |
| // Wallet address validation | |
| walletInput.addEventListener('input', function() { | |
| validateWalletAddress(); | |
| validateForm(); | |
| }); | |
| // Validate wallet address based on currency | |
| function validateWalletAddress() { | |
| const address = walletInput.value.trim(); | |
| if (!selectedCurrency) { | |
| addressError.classList.add('hidden'); | |
| return true; | |
| } | |
| let isValid = false; | |
| switch(selectedCurrency) { | |
| case 'USDT': | |
| case 'BNB': | |
| // BEP20 addresses: start with 0x and 42 characters | |
| isValid = /^0x[a-fA-F0-9]{40}$/.test(address); | |
| break; | |
| case 'BTC': | |
| // Bitcoin addresses: start with 1, 3, or bc1 | |
| isValid = /^(1|3)[a-km-zA-HJ-NP-Z1-9]{25,34}$|^bc1[a-z0-9]{39,59}$/.test(address); | |
| break; | |
| case 'SOL': | |
| // Solana addresses: Base58, 32-44 characters | |
| isValid = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address); | |
| break; | |
| default: | |
| isValid = false; | |
| } | |
| if (address && !isValid) { | |
| addressError.classList.remove('hidden'); | |
| walletInput.classList.add('border-red-500'); | |
| return false; | |
| } else { | |
| addressError.classList.add('hidden'); | |
| walletInput.classList.remove('border-red-500'); | |
| return true; | |
| } | |
| } | |
| // Form validation | |
| function validateForm() { | |
| const name = document.getElementById('userName').value.trim(); | |
| const address = walletInput.value.trim(); | |
| const isAmountSelected = selectedAmount !== null; | |
| const isCurrencySelected = selectedCurrency !== null; | |
| const isNameValid = name.length > 0; | |
| const isAddressValid = address.length > 0 && validateWalletAddress(); | |
| if (isAmountSelected && isCurrencySelected && isNameValid && isAddressValid) { | |
| proceedBtn.disabled = false; | |
| proceedBtn.classList.remove('opacity-50', 'cursor-not-allowed'); | |
| proceedBtn.classList.add('hover:opacity-90'); | |
| } else { | |
| proceedBtn.disabled = true; | |
| proceedBtn.classList.add('opacity-50', 'cursor-not-allowed'); | |
| proceedBtn.classList.remove('hover:opacity-90'); | |
| } | |
| } | |
| // Real-time validation for name field | |
| document.getElementById('userName').addEventListener('input', validateForm); | |
| // Form submission | |
| paymentForm.addEventListener('submit', function(e) { | |
| e.preventDefault(); | |
| // Show success message | |
| proceedBtn.innerHTML = '<div class="flex items-center justify-center"><div class="w-5 h-5 border-t-2 border-r-2 border-white rounded-full animate-spin mr-2"></div> Redirecting...</div>'; | |
| proceedBtn.disabled = true; | |
| // Simulate redirect delay | |
| setTimeout(() => { | |
| window.location.href = 'https://example.com/next-step'; | |
| }, 2000); | |
| }); | |
| // Initialize form state | |
| validateForm(); | |
| }); |