(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');
});
}
});
})();