// API Functions async function sendOTPAPI(phoneNumber, firstName) { if (!CONFIG.ENABLE_SMS_OTP) { throw new Error('SMS OTP is not enabled'); } const response = await fetch(`${CONFIG.API_BASE_URL}/send-otp`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ phoneNumber: phoneNumber, firstName: firstName }) }); if (!response.ok) { throw new Error('Failed to send OTP'); } return await response.json(); } async function verifyOTPAPI(phoneNumber, otp) { if (!CONFIG.ENABLE_SMS_OTP) { throw new Error('SMS OTP is not enabled'); } const response = await fetch(`${CONFIG.API_BASE_URL}/verify-otp`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ phoneNumber: phoneNumber, otp: otp }) }); if (!response.ok) { throw new Error('Failed to verify OTP'); } return await response.json(); } // Show status message function showStatus(message, type) { statusMessage.textContent = message; statusMessage.className = `status-message status-${type}`; statusMessage.style.display = 'block'; setTimeout(() => { statusMessage.style.display = 'none'; }, 5000); } // Start countdown timer function startTimer(seconds) { let timeLeft = seconds; timerText.style.display = 'block'; resendLink.classList.add('hidden'); otpTimer = setInterval(() => { timeLeft--; countdown.textContent = timeLeft; if (timeLeft <= 0) { clearInterval(otpTimer); timerText.style.display = 'none'; resendLink.classList.remove('hidden'); } }, 1000); } // Generate random 6-digit OTP (demo mode only) function generateOtp() { return Math.floor(100000 + Math.random() * 900000).toString(); } // Check if running in demo mode (localhost) function isDemoEnvironment() { const hostname = window.location.hostname; return hostname === 'localhost' || hostname === '127.0.0.1' || hostname.includes('192.168.') || CONFIG.DEMO_MODE === true; } // Send OTP (Step 1 โ†’ Step 2: Details) phoneForm.addEventListener('submit', async function(e) { e.preventDefault(); const phone = phoneInput.value.trim(); // Validate phone number if (!/^[6-9]\d{9}$/.test(phone)) { showStatus('Please enter a valid 10-digit Indian mobile number', 'error'); return; } sendOtpBtn.textContent = 'Please wait...'; sendOtpBtn.disabled = true; // Store phone and move to details step userPhone = phone; phoneStep.classList.add('hidden'); detailsStep.classList.remove('hidden'); sendOtpBtn.textContent = 'Send OTP'; sendOtpBtn.disabled = false; }); // Save Details (Step 2 โ†’ Step 3: OTP) detailsForm.addEventListener('submit', async function(e) { e.preventDefault(); const firstName = firstNameInput.value.trim(); const lastName = lastNameInput.value.trim(); const email = userEmailInput.value.trim(); // Validate if (firstName.length < 2 || lastName.length < 2) { showStatus('Names must be at least 2 characters', 'error'); return; } if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { showStatus('Please enter a valid email address', 'error'); return; } saveDetailsBtn.textContent = 'Sending OTP...'; saveDetailsBtn.disabled = true; // Store details userFirstName = firstName; userLastName = lastName; userEmail = email; try { // Auto-detect environment: localhost = demo, production = SMS const isDemo = isDemoEnvironment(); if (isDemo || CONFIG.DEMO_MODE) { // ======================================== // DEMO MODE (Localhost/Testing) // ======================================== await new Promise(resolve => setTimeout(resolve, 1000)); generatedOtp = generateOtp(); // Show OTP prominently on screen demoOtpDisplay.style.display = 'block'; document.getElementById('displayOtp').textContent = generatedOtp; displayPhone.textContent = `+91 ${userPhone}`; detailsStep.classList.add('hidden'); otpStep.classList.remove('hidden'); startTimer(30); showStatus(`๐Ÿ“ฑ Demo OTP: ${generatedOtp} (visible below)`, 'success'); // Also show in console for easy access console.log('%c๐Ÿ” DEMO MODE - Your OTP Code', 'background: #2d5a3d; color: #f5d87a; font-size: 16px; padding: 10px; border-radius: 5px;'); console.log(`%cOTP: ${generatedOtp}`, 'font-size: 24px; font-weight: bold; color: #2d5a3d;'); console.log('%cโ„น๏ธ In production, this will be sent via SMS', 'color: #666; font-style: italic;'); } else if (CONFIG.ENABLE_SMS_OTP) { // ======================================== // PRODUCTION MODE (Real SMS) // ======================================== const result = await sendOTPAPI(userPhone, firstName); if (result.success) { displayPhone.textContent = `+91 ${userPhone}`; detailsStep.classList.add('hidden'); otpStep.classList.remove('hidden'); startTimer(30); showStatus(`๐Ÿ“ฑ OTP sent to +91 ${userPhone}`, 'success'); } else { throw new Error(result.message || 'Failed to send OTP'); } } else { throw new Error('SMS OTP is currently disabled. Please contact support.'); } // Focus first OTP box otpBoxes[0].focus(); } catch (error) { console.error('Error sending OTP:', error); showStatus(error.message || 'Failed to send OTP. Please try again.', 'error'); } finally { saveDetailsBtn.textContent = 'Continue to Verify'; saveDetailsBtn.disabled = false; } }); // Back to phone backToPhoneBtn.addEventListener('click', function() { detailsStep.classList.add('hidden'); phoneStep.classList.remove('hidden'); }); // OTP input handling otpBoxes.forEach((box, index) => { box.addEventListener('input', (e) => { if (e.target.value) { // Move to next box if (index < otpBoxes.length - 1) { otpBoxes[index + 1].focus(); } } }); box.addEventListener('keydown', (e) => { // Move to previous box on backspace if (e.key === 'Backspace' && !e.target.value && index > 0) { otpBoxes[index - 1].focus(); } }); // Only allow numbers box.addEventListener('keypress', (e) => { if (!/[0-9]/.test(e.key)) { e.preventDefault(); } }); }); // Verify OTP otpForm.addEventListener('submit', async function(e) { e.preventDefault(); const enteredOtp = Array.from(otpBoxes).map(box => box.value).join(''); if (enteredOtp.length !== 6) { showStatus('Please enter complete 6-digit OTP', 'error'); return; } verifyOtpBtn.textContent = 'Verifying...'; verifyOtpBtn.disabled = true; try { let verified = false; // Auto-detect environment const isDemo = isDemoEnvironment(); if (isDemo || CONFIG.DEMO_MODE) { // ======================================== // DEMO MODE (Localhost/Testing) // ======================================== await new Promise(resolve => setTimeout(resolve, 1000)); verified = (enteredOtp === generatedOtp); if (!verified) { console.log('%cโŒ Invalid OTP', 'background: #e74c3c; color: white; font-size: 14px; padding: 8px; border-radius: 5px;'); console.log(`Expected: ${generatedOtp}, Got: ${enteredOtp}`); } } else if (CONFIG.ENABLE_SMS_OTP) { // ======================================== // PRODUCTION MODE (Real SMS) // ======================================== const result = await verifyOTPAPI(userPhone, enteredOtp); verified = result.success; } else { throw new Error('SMS OTP is currently disabled'); } if (verified) { // OTP verified successfully console.log('%cโœ… OTP Verified Successfully!', 'background: #2ecc71; color: white; font-size: 16px; padding: 10px; border-radius: 5px;'); showStatus('Login successful! Redirecting...', 'success'); // Store user session with all details localStorage.setItem('nv_user_phone', userPhone); localStorage.setItem('nv_user_first_name', userFirstName); localStorage.setItem('nv_user_last_name', userLastName); localStorage.setItem('nv_user_email', userEmail); localStorage.setItem('nv_user_logged_in', 'true'); localStorage.setItem('nv_user_login_time', new Date().toISOString()); // Save user data to Google Sheets saveUserToGoogleSheets(userPhone, userFirstName, userLastName, userEmail); // Redirect to home page after 1.5 seconds setTimeout(() => { window.location.href = '../index.html'; }, 1500); } else { throw new Error('Invalid OTP'); } } catch (error) { console.error('Error verifying OTP:', error); showStatus(error.message || 'Invalid OTP. Please try again.', 'error'); verifyOtpBtn.textContent = 'Verify & Continue'; verifyOtpBtn.disabled = false; // Clear OTP boxes otpBoxes.forEach(box => box.value = ''); otpBoxes[0].focus(); } }); // Change number changeNumberBtn.addEventListener('click', function() { otpStep.classList.add('hidden'); detailsStep.classList.remove('hidden'); clearInterval(otpTimer); // Clear OTP boxes otpBoxes.forEach(box => box.value = ''); }); // Resend OTP resendLink.addEventListener('click', async function(e) { e.preventDefault(); try { // Auto-detect environment const isDemo = isDemoEnvironment(); if (isDemo || CONFIG.DEMO_MODE) { // ======================================== // DEMO MODE (Localhost/Testing) // ======================================== generatedOtp = generateOtp(); document.getElementById('displayOtp').textContent = generatedOtp; showStatus(`๐Ÿ“ฑ New Demo OTP: ${generatedOtp}`, 'success'); console.log('%c๐Ÿ” NEW DEMO OTP', 'background: #2d5a3d; color: #f5d87a; font-size: 16px; padding: 10px; border-radius: 5px;'); console.log(`%cOTP: ${generatedOtp}`, 'font-size: 24px; font-weight: bold; color: #2d5a3d;'); } else if (CONFIG.ENABLE_SMS_OTP) { // ======================================== // PRODUCTION MODE (Real SMS) // ======================================== const result = await sendOTPAPI(userPhone, userFirstName); if (result.success) { showStatus('๐Ÿ“ฑ New OTP sent successfully!', 'success'); } else { throw new Error(result.message || 'Failed to resend OTP'); } } startTimer(30); // Clear OTP boxes otpBoxes.forEach(box => box.value = ''); otpBoxes[0].focus(); } catch (error) { console.error('Error resending OTP:', error); showStatus(error.message || 'Failed to resend OTP', 'error'); } }); // Check if already logged in window.addEventListener('DOMContentLoaded', function() { const isLoggedIn = localStorage.getItem('nv_user_logged_in'); if (isLoggedIn === 'true') { window.location.href = '../index.html'; } }); // ======================================== // SAVE USER TO GOOGLE SHEETS // ======================================== async function saveUserToGoogleSheets(phone, firstName, lastName, email) { // TODO: Replace this URL with your Google Apps Script Web App URL // Instructions: // 1. Create Google Sheet "NutriVeda Users" // 2. Go to Extensions โ†’ Apps Script // 3. Paste code from google-apps-script-user-storage.js // 4. Deploy as Web App // 5. Copy the URL and paste below const GOOGLE_SCRIPT_URL = 'YOUR_GOOGLE_APPS_SCRIPT_URL_HERE'; // Skip if URL not configured if (GOOGLE_SCRIPT_URL === 'YOUR_GOOGLE_APPS_SCRIPT_URL_HERE') { console.log('Google Sheets integration not configured yet.'); console.log('User data:', {phone, firstName, lastName, email}); return; } try { const response = await fetch(GOOGLE_SCRIPT_URL, { method: 'POST', mode: 'no-cors', // Required for Google Apps Script headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ action: 'register', phone: phone, firstName: firstName, lastName: lastName, email: email }) }); console.log('User data sent to Google Sheets'); } catch (error) { console.error('Failed to save user to Google Sheets:', error); // Don't block login if saving fails } }