diff --git a/assets/images/webp/digital-gift-card-expb.webp b/assets/images/webp/digital-gift-card-expb.webp new file mode 100644 index 0000000..f92d3a4 Binary files /dev/null and b/assets/images/webp/digital-gift-card-expb.webp differ diff --git a/assets/js/webapp/wallet.js b/assets/js/webapp/wallet.js index 9434b1f..bed8fec 100644 --- a/assets/js/webapp/wallet.js +++ b/assets/js/webapp/wallet.js @@ -398,11 +398,29 @@ function sellToken() { alert("Sell to Token / Exchange Loop Coming Soon..."); } +// ====================== QR / SCAN HELPER ====================== +function scanQRCode() { + const helper = document.getElementById('scan-helper'); + + if (helper) { + helper.classList.toggle('hidden'); + + // Auto-hide after 4 seconds + setTimeout(() => { + if (helper) helper.classList.add('hidden'); + }, 4000); + } + + // Optional: future real QR scan would go here + console.log("📷 Scan & Send feature — coming soon"); +} + // ====================== MODAL & REDEEM FUNCTIONS ====================== function openModal(modalId) { if (modalId === 'redeem') { document.getElementById('redeem-modal').style.display = 'flex'; resetRedeemForm(); + populateRedeemAddress(); // Auto-populate + lock } } @@ -416,7 +434,7 @@ function closeModal(modalId) { function resetRedeemForm() { const input = document.getElementById('redeem-input'); const msg = document.getElementById('redeem-message'); - const btn = document.getElementById('redeem-submit-btn'); // ← Fixed: targets correct button + const btn = document.getElementById('redeem-submit-btn'); if (input) input.value = ''; if (msg) { @@ -430,6 +448,65 @@ function resetRedeemForm() { } } +// ====================== SMART ADDRESS MODE (Locked by default) ====================== +function populateRedeemAddress() { + const input = document.getElementById('wallet-address'); + if (!input) return; + + const connectedAddr = window.connectedWallet || localStorage.getItem('wallet_address'); + + if (connectedAddr) { + input.value = connectedAddr; + lockAddressField(input); + console.log("✅ Auto-populated and LOCKED:", connectedAddr); + } else { + unlockAddressField(input); + } +} + +function lockAddressField(input) { + input.readOnly = true; + input.classList.add('locked-address'); + updateAddressModeUI(true); +} + +function unlockAddressField(input) { + input.readOnly = false; + input.value = ''; // Clear for safety + input.classList.remove('locked-address'); + updateAddressModeUI(false); +} + +function updateAddressModeUI(isLocked) { + const link = document.getElementById('manual-address-link'); + if (!link) return; + + if (isLocked) { + link.innerHTML = `✏️ Use different address`; + } else { + link.innerHTML = `➕ Use connected wallet`; + } +} + +window.toggleAddressMode = function() { + const input = document.getElementById('wallet-address'); + if (!input) return; + + if (input.classList.contains('locked-address')) { + // Locked → unlock for manual + unlockAddressField(input); + } else { + // Unlocked → restore connected wallet + const connectedAddr = window.connectedWallet || localStorage.getItem('wallet_address'); + if (connectedAddr) { + input.value = connectedAddr; + lockAddressField(input); + } else { + alert("No wallet is currently connected."); + } + } +}; + // ====================== CENTRALIZED WALLET STATE + CLEAR LOGIC ====================== function clearBalancesOnDisconnect() { const allTokens = ['SOL', 'USDC', 'EXPB', 'GIDDY', 'ONE', 'KIN', 'DOBBY', 'MYLO', 'DUNO', 'CPT', 'SINU']; @@ -1364,7 +1441,7 @@ document.addEventListener('DOMContentLoaded', () => { messageDiv.textContent = 'Invalid code: Must be exactly 13 digits.'; messageDiv.style.color = '#e74c3c'; if (mainBtn) mainBtn.classList.add('failure'); - if (mainBtn) mainBtn.textContent = 'INVALID'; + if (mainBtn) mainBtn.textContent = 'TRY AGAIN'; return; } @@ -1374,6 +1451,14 @@ document.addEventListener('DOMContentLoaded', () => { return; } + // ====================== SOLANA ADDRESS VALIDATION ====================== + if (!isValidSolanaAddress(destinationWallet)) { + messageDiv.textContent = '❌ Invalid Solana address. Please check the format and try again.'; + messageDiv.style.color = '#e74c3c'; + if (mainBtn) mainBtn.classList.add('failure'); + return; + } + // Show Checking... on main REDEEM button const originalText = mainBtn ? mainBtn.textContent : 'REDEEM'; if (mainBtn) { @@ -1410,7 +1495,6 @@ document.addEventListener('DOMContentLoaded', () => { } if (!data) { - // Error handling (same style as redeem.html) messageDiv.style.color = '#e74c3c'; messageDiv.textContent = "Network error: " + (lastError?.message || "All backends failed"); if (mainBtn) { @@ -1421,16 +1505,14 @@ document.addEventListener('DOMContentLoaded', () => { } if (data.success) { - // Success → show the nice modal (same as redeem.html) showRedeemSuccessModal(data); if (mainBtn) { mainBtn.textContent = originalText; mainBtn.disabled = false; } } else { - // Error from backend messageDiv.style.color = '#e74c3c'; - messageDiv.textContent = data.message || "Redemption failed"; + messageDiv.textContent = data.message || "Invaild, expired or used code. Check or try another."; if (mainBtn) { mainBtn.textContent = originalText; mainBtn.disabled = false; @@ -1439,6 +1521,27 @@ document.addEventListener('DOMContentLoaded', () => { }); } + // ====================== SOLANA ADDRESS VALIDATION HELPER ====================== + function isValidSolanaAddress(address) { + if (!address || typeof address !== 'string') return false; + if (address.length < 32 || address.length > 44) return false; + + // Basic base58 alphabet check + const base58Regex = /^[1-9A-HJ-NP-Za-km-z]+$/; + if (!base58Regex.test(address)) return false; + + try { + // Use web3.js if available (most accurate) + if (typeof solanaWeb3 !== 'undefined' && solanaWeb3.PublicKey) { + new solanaWeb3.PublicKey(address); + return true; + } + return true; // fallback validation passed + } catch (e) { + return false; + } + } + // ====================== REDEEM IN KINNECTED BUTTON (Original Simple Flow) ====================== const kinnectedBtn = document.querySelector('button[onclick="redeemInKinnected()"]'); @@ -1466,7 +1569,7 @@ document.addEventListener('DOMContentLoaded', () => { messageDiv.textContent = 'Invalid code: Must be exactly 13 digits.'; messageDiv.style.color = '#e74c3c'; button.classList.add('failure'); - button.textContent = 'INVALID'; + button.textContent = 'TRY AGAIN'; return; } @@ -1482,6 +1585,44 @@ document.addEventListener('DOMContentLoaded', () => { }); } +// ====================== REFRESH REDEEM MODAL (Full Reset for Both Buttons) ====================== +window.refreshRedeemModal = function() { + console.log("🔄 Full Refresh - Resetting all buttons..."); + + // Close modal + const modal = document.getElementById('redeem-modal'); + if (modal) closeModal('redeem'); + + setTimeout(() => { + // Reset Main Redeem Button + const mainBtn = document.getElementById('redeem-submit-btn'); + if (mainBtn) { + mainBtn.textContent = 'REDEEM'; + mainBtn.disabled = false; + mainBtn.classList.remove('success', 'failure'); + } + + // Reset Kinnected Button + const kinnectedBtn = document.querySelector('button[onclick="redeemInKinnected()"]'); + if (kinnectedBtn) { + kinnectedBtn.textContent = 'Redeem in Kinnected'; + kinnectedBtn.disabled = false; + kinnectedBtn.classList.remove('success', 'failure'); + } + + // Clear messages + const messageDiv = document.getElementById('redeem-message'); + if (messageDiv) { + messageDiv.textContent = ''; + messageDiv.style.color = ''; + } + + // Re-open modal + openModal('redeem'); + console.log("✅ Both buttons and modal fully reset"); + }, 250); +}; + // Wrapper for onclick in HTML window.redeemInKinnected = function () { const btn = document.querySelector('button[onclick="redeemInKinnected()"]'); @@ -1615,12 +1756,13 @@ window.dismissClaimBubble = dismissClaimBubble; window.toggleCommunityTokens = toggleCommunityTokens; window.toggleWorldwideCurrencies = toggleWorldwideCurrencies; -// Create / Sign In Modal (Updated) +// Create / Sign In Modal window.openCreateSignInModal = openCreateSignInModal; window.closeCreateSignInModal = closeCreateSignInModal; window.handleCreateWalletFromModal = handleCreateWalletFromModal; window.handleAppleSignInFromModal = handleAppleSignInFromModal; +// Modals window.openValueLockModal = openValueLockModal; window.closeValueLockModal = closeValueLockModal; window.openGiddySwapModal = openGiddySwapModal; @@ -1632,9 +1774,8 @@ window.selectSwapPercent = selectSwapPercent; window.changeCurrency = changeCurrency; window.showTxSuccess = showTxSuccess; window.closeTxSuccessModal = closeTxSuccessModal; +window.closeRedeemSuccessModal = closeRedeemSuccessModal; +window.scanQRCode = scanQRCode; window.getPhantomSDK = getPhantomSDK; -window.isMobileDevice = isMobileDevice; - -// Kinnected Redeem -window.closeRedeemSuccessModal = closeRedeemSuccessModal; \ No newline at end of file +window.isMobileDevice = isMobileDevice; \ No newline at end of file diff --git a/wallet.html b/wallet.html index eb19026..a1e6c60 100644 --- a/wallet.html +++ b/wallet.html @@ -1050,51 +1050,48 @@ - - + + #connectedStatus #connectedAddress { + color: var(--text-color, #166534) !important; + } + + /* Dark Mode Override */ + .dark-mode #connectedStatus { + background: rgba(16, 185, 129, 0.12); + border-color: rgba(16, 185, 129, 0.5); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); + } +
@@ -2081,30 +2078,18 @@