(function () { function esc(value) { return String(value ?? '') .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"'); } function formatDate(value) { if (!value) return '—'; const d = new Date(value); if (Number.isNaN(d.getTime())) return '—'; return d.toLocaleDateString('en-IN', { year: 'numeric', month: 'short', day: 'numeric' }); } function formatMoney(value) { return '₹' + Number(value || 0).toLocaleString('en-IN', { maximumFractionDigits: 0 }); } function show(message, type = 'info') { const msg = document.getElementById('authMessage'); if (!msg) { alert(message); return; } msg.textContent = message; msg.className = 'toast visible ' + type; setTimeout(() => msg.classList.remove('visible'), 5200); } function profileField(label, value, mono) { return `
${esc(label)}${esc(value)}
`; } function renderProfile(user, orders) { const loading = document.getElementById('accountLoading'); const loggedIn = document.getElementById('accountLoggedIn'); const loggedOut = document.getElementById('accountLoggedOut'); if (loading) loading.style.display = 'none'; if (!user) { if (loggedIn) loggedIn.style.display = 'none'; if (loggedOut) loggedOut.style.display = ''; return; } if (loggedOut) loggedOut.style.display = 'none'; if (loggedIn) loggedIn.style.display = ''; const welcome = document.getElementById('profileWelcome'); if (welcome) welcome.textContent = 'Welcome back, ' + user.name; const verify = document.getElementById('profileVerifyNotice'); if (verify) { verify.className = user.emailVerified ? 'notice success' : 'notice warning'; verify.textContent = user.emailVerified ? 'Your email is verified and checkout is active.' : 'Verify your email with the OTP sent to your inbox, or use Resend verification below.'; } const details = document.getElementById('profileDetails'); if (details) { details.innerHTML = [ profileField('Full name', user.name), profileField('Email address', user.email), profileField('Email verification', user.emailVerified ? 'Verified' : 'Pending OTP'), profileField('Account status', user.status || 'active'), profileField('Member since', formatDate(user.createdAt)), profileField('Last updated', formatDate(user.updatedAt)), profileField('User ID', user.id, true), ].join(''); } const ordersEl = document.getElementById('profileOrders'); if (ordersEl) { const list = Array.isArray(orders) ? orders : []; if (!list.length) { ordersEl.innerHTML = '

No orders yet. Browse the collection and place your first order.

'; } else { ordersEl.innerHTML = list.slice(0, 8).map((order) => { const trackUrl = 'order-statusd5d8.html?order_id=' + encodeURIComponent(order.orderId || '') + '&email=' + encodeURIComponent(order.email || user.email || ''); return `
${esc(order.orderId || 'Order')}
${esc(order.status || 'Placed')} • ${formatMoney(order.total)} • ${esc(order.paymentMethod || '')}
${formatDate(order.createdAt)}
View
`; }).join(''); } } } async function loadAccountProfile(options) { const opts = options || {}; const loading = document.getElementById('accountLoading'); if (loading) loading.style.display = ''; try { if (!window.EcomAPI || !EcomAPI.token()) { renderProfile(null, []); return; } if (!opts.skipSessionSync) { await EcomAPI.syncPhpSession(); } const me = await EcomAPI.me(); if (me._status === 429) { show(me.message || 'Too many requests. Please wait a minute and try again.', 'error'); renderProfile(null, []); return; } if (me.success && me.user) { const ordersRes = await EcomAPI.myOrders().catch(() => ({ success: false, orders: [] })); renderProfile(me.user, ordersRes.success ? ordersRes.orders : []); return; } EcomAPI.setToken(''); renderProfile(null, []); } finally { if (loading) loading.style.display = 'none'; } } window.loadAccountProfile = loadAccountProfile; window.loadAccount = loadAccountProfile; document.addEventListener('DOMContentLoaded', async () => { window.addEventListener('ecom:auth-verified', () => { show('Email verified successfully. You can now checkout.', 'success'); loadAccountProfile(); }); const params = new URLSearchParams(window.location.search); if (params.get('verified') === '1') show('Email verified successfully. You can now checkout.', 'success'); if (params.get('verify') === '1') show('Please verify your email with the OTP before checkout.', 'warning'); await loadAccountProfile(); const resetToken = params.get('reset_token'); const resetForm = document.getElementById('resetPasswordForm'); if (resetForm && resetToken) { resetForm.addEventListener('submit', async (e) => { e.preventDefault(); const fd = new FormData(resetForm); const password = String(fd.get('password') || ''); const confirm = String(fd.get('confirm_password') || ''); if (password.length < 6) return show('Password must be at least 6 characters.', 'error'); if (password !== confirm) return show('Passwords do not match.', 'error'); const data = await EcomAPI.resetPassword(resetToken, password); show(data.message || 'Password updated.', data.success ? 'success' : 'error'); if (data.success) window.location.href = 'account.html'; }); } const forgot = document.getElementById('forgotPasswordForm'); if (forgot) { forgot.addEventListener('submit', async (e) => { e.preventDefault(); const email = new FormData(forgot).get('email'); const data = await EcomAPI.forgotPassword(String(email || '')); show(data.message || 'If that email exists, a reset link has been sent.', 'success'); }); } const signup = document.getElementById('signupForm'); if (signup) { signup.addEventListener('submit', async (e) => { e.preventDefault(); const fd = new FormData(signup); const email = String(fd.get('email') || ''); const btn = signup.querySelector('button'); btn.disabled = true; btn.textContent = 'Creating account...'; const data = await EcomAPI.register({ name: String(fd.get('name') || ''), email, password: String(fd.get('password') || ''), }); if (data.success && data.requiresVerification && data.mailConfigured === false) { show(data.message || 'Email verification is not available for this store.', 'error'); btn.disabled = false; btn.textContent = 'Create account'; return; } if (window.EcomOtpAuth && EcomOtpAuth.handleRegisterResponse(data, email)) { show(data.message || 'Enter the code sent to your email.', 'info'); btn.disabled = false; btn.textContent = 'Create account'; return; } if (data.success && data.token) { EcomAPI.setToken(data.token); await EcomAPI.syncPhpSession(); show(data.message || 'Account created.', 'success'); await loadAccountProfile(); } else { show(data.message || 'Could not create account.', 'error'); } btn.disabled = false; btn.textContent = 'Create account'; }); } const login = document.getElementById('loginForm'); if (login) { login.addEventListener('submit', async (e) => { e.preventDefault(); if (!window.EcomAPI) { show('Account service is unavailable. Please refresh and try again.', 'error'); return; } const fd = new FormData(login); const email = String(fd.get('email') || ''); const btn = login.querySelector('button'); btn.disabled = true; btn.textContent = 'Signing in...'; try { const data = await EcomAPI.login({ email, password: String(fd.get('password') || '') }); if (data._status === 429) { show(data.message || 'Too many sign-in attempts. Please wait a minute and try again.', 'error'); return; } if (window.EcomOtpAuth && EcomOtpAuth.handleLoginResponse(data, email)) { if (data.requiresVerification && !data.emailSent) { const otpData = await EcomAPI.resendOtp(email); show(otpData.message || data.message || 'Verify your email with the OTP sent to your inbox.', otpData.success ? 'warning' : 'error'); } else { show(data.message || 'Verify your email with the OTP sent to your inbox.', 'warning'); } return; } if (data.success) { show('Signed in successfully.', 'success'); await loadAccountProfile(); if (!data.user?.emailVerified) { show('Please verify your email before checkout.', 'warning'); } else if (window.ECOM_AFTER_LOGIN && window.ECOM_AFTER_LOGIN !== 'index-2.html') { window.location.href = window.ECOM_AFTER_LOGIN; } } else { show(data.message || 'Sign in failed.', 'error'); } } catch (_) { show('Sign in failed. Please try again.', 'error'); } finally { btn.disabled = false; btn.textContent = 'Sign in'; } }); } const resend = document.getElementById('resendVerification'); if (resend) { resend.addEventListener('click', async () => { const me = await EcomAPI.me().catch(() => null); const email = me?.user?.email || String(document.querySelector('#loginForm input[name="email"]')?.value || '') || String(document.querySelector('#signupForm input[name="email"]')?.value || ''); if (!email) { show('Sign in or enter your email first.', 'error'); return; } const data = EcomAPI.token() ? await EcomAPI.resendVerification().catch(() => EcomAPI.resendOtp(email)) : await EcomAPI.resendOtp(email); if (window.EcomOtpAuth) { EcomOtpAuth.show(email, data.message || 'Enter the verification code from your email.'); } show(data.message || 'Verification code sent.', data.success ? 'success' : 'error'); await loadAccountProfile(); }); } const signOut = document.getElementById('signOutLink'); if (signOut) { signOut.addEventListener('click', (e) => { e.preventDefault(); EcomAPI.logout(); }); } const changeForm = document.getElementById('changePasswordForm'); if (changeForm) { changeForm.addEventListener('submit', async (e) => { e.preventDefault(); const fd = new FormData(changeForm); const data = await EcomAPI.changePassword(String(fd.get('current_password') || ''), String(fd.get('new_password') || '')); show(data.message || 'Password updated.', data.success ? 'success' : 'error'); }); } }); })();