Spaces:
Sleeping
Sleeping
| // ======================================== | |
| // CHECKOUT PAGE LOGIC | |
| // ======================================== | |
| let currentStepNum = 1; | |
| let paymentMethod = 'cash'; | |
| document.addEventListener('DOMContentLoaded', () => { | |
| if (getCart().length === 0) { window.location.href = 'cart.html'; return; } | |
| // Auth Check | |
| if (!isLoggedIn()) { | |
| showToast("Majburiy", "To'lovni amalga oshirish yoki buyurtma berish uchun iltimos tizimga kiring", "info"); | |
| setTimeout(() => { | |
| window.location.href = 'index.html'; // In a real app we might open modal directly, but index is safer to initialize auth state | |
| }, 2000); | |
| return; | |
| } | |
| // Pre-fill user data | |
| const user = getUser(); | |
| if (user.name) document.getElementById('userName').value = user.name; | |
| if (user.phone) document.getElementById('userPhone').value = user.phone; | |
| if (user.email) document.getElementById('userEmail').value = user.email; | |
| // Payment method selection | |
| document.querySelectorAll('[data-payment]').forEach(el => { | |
| el.addEventListener('click', () => { | |
| document.querySelectorAll('[data-payment]').forEach(e => e.classList.remove('active')); | |
| el.classList.add('active'); | |
| paymentMethod = el.dataset.payment; | |
| }); | |
| }); | |
| // Load store location info for step 2 | |
| loadStoreLocation(); | |
| }); | |
| function loadStoreLocation() { | |
| const settings = JSON.parse(localStorage.getItem('mtextile_settings')) || {}; | |
| const addressBox = document.getElementById('storeAddressText'); | |
| const mapBox = document.getElementById('storeMapContainer'); | |
| if (settings.address && addressBox) { | |
| addressBox.textContent = settings.address; | |
| } | |
| if (settings.mapIframe && mapBox) { | |
| mapBox.innerHTML = settings.mapIframe; | |
| mapBox.style.display = 'block'; | |
| const iframe = mapBox.querySelector('iframe'); | |
| if (iframe) { | |
| iframe.style.width = '100%'; | |
| iframe.style.height = '100%'; | |
| iframe.style.border = 'none'; | |
| } | |
| } | |
| } | |
| function goToStep(step) { | |
| document.querySelectorAll('.checkout-step').forEach(el => el.classList.remove('active')); | |
| document.getElementById('step' + step).classList.add('active'); | |
| document.querySelectorAll('.progress-step').forEach(el => { | |
| const s = parseInt(el.dataset.step); | |
| el.classList.remove('active', 'done'); | |
| if (s < step) el.classList.add('done'); | |
| if (s === step) el.classList.add('active'); | |
| }); | |
| currentStepNum = step; | |
| window.scrollTo({ top: 0, behavior: 'smooth' }); | |
| } | |
| function nextStep(from) { | |
| if (from === 1 && !validateStep1()) return; | |
| if (from === 2 && !validateStep2()) return; | |
| if (from === 3) buildSummary(); | |
| goToStep(from + 1); | |
| } | |
| function prevStep(from) { goToStep(from - 1); } | |
| function validateStep1() { | |
| let valid = true; | |
| const name = document.getElementById('userName').value.trim(); | |
| const phone = document.getElementById('userPhone').value.trim(); | |
| const email = document.getElementById('userEmail').value.trim(); | |
| clearErrors(); | |
| if (!name || name.length < 2) { | |
| showFieldError('userName', 'nameError', 'Ismingizni kiriting (kamida 2 harf)'); | |
| valid = false; | |
| } | |
| // Strict UZ phone validation | |
| const phoneRegex = /^(?:\+?998)[ \-]?\d{2}[ \-]?\d{3}[ \-]?\d{2}[ \-]?\d{2}$/; | |
| if (!phone || !phoneRegex.test(phone.replace(/\s/g, ''))) { | |
| showFieldError('userPhone', 'phoneError', 'Faqat O\'zbekiston raqami (+998...) kiritilishi shart'); | |
| valid = false; | |
| } | |
| if (email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { | |
| showFieldError('userEmail', 'emailError', 'To\'g\'ri email kiriting'); | |
| valid = false; | |
| } | |
| if (valid) saveUser({ name, phone, email }); | |
| return valid; | |
| } | |
| function validateStep2() { | |
| // Store pickup requires no address input from the user. | |
| return true; | |
| } | |
| function showFieldError(inputId, errorId, msg) { | |
| document.getElementById(inputId).classList.add('error'); | |
| document.getElementById(errorId).textContent = msg; | |
| } | |
| function clearErrors() { | |
| document.querySelectorAll('.form-input.error').forEach(el => el.classList.remove('error')); | |
| document.querySelectorAll('.form-error').forEach(el => el.textContent = ''); | |
| } | |
| function buildSummary() { | |
| const user = getUser(); | |
| const cart = getCart(); | |
| const totals = getCartTotal(); | |
| const payNames = { cash: '💵 Naqd pul', card: '💳 Plastik karta', click: '📱 Click/Payme' }; | |
| let itemsHTML = ''; | |
| cart.forEach(item => { | |
| const p = getProductById(item.productId); | |
| if (!p) return; | |
| itemsHTML += `<div style="display:flex;align-items:center;gap:1rem;padding:0.75rem 0;border-bottom:1px solid var(--clr-border);"> | |
| <img src="${p.images[0]}" style="width:50px;height:60px;object-fit:cover;border-radius:6px;"> | |
| <div style="flex:1"> | |
| <div style="font-weight:600;font-size:0.9rem;">${p.name}</div> | |
| <div style="font-size:0.75rem;color:var(--clr-text-muted)">${item.size} | ${COLORS_MAP[item.color]?.name || item.color} | x${item.quantity}</div> | |
| </div> | |
| <div style="font-weight:600">${formatPrice(p.price * item.quantity)}</div> | |
| </div>`; | |
| }); | |
| document.getElementById('orderSummary').innerHTML = ` | |
| <h3 style="margin-bottom:1rem;font-size:1rem;">📋 Buyurtma tafsilotlari</h3> | |
| <div style="margin-bottom:1rem;"> | |
| <div style="font-size:0.85rem;color:var(--clr-text-muted)">Buyurtmachi</div> | |
| <div>${user.name} | ${user.phone}</div> | |
| </div> | |
| <div style="margin-bottom:1rem;"> | |
| <div style="font-size:0.85rem;color:var(--clr-text-muted)">Olib ketish manzili</div> | |
| <div>Do'kon: ${document.getElementById('storeAddressText').textContent}</div> | |
| </div> | |
| <div style="margin-bottom:1rem;"> | |
| <div style="font-size:0.85rem;color:var(--clr-text-muted)">To'lov usuli</div> | |
| <div>${payNames[paymentMethod]}</div> | |
| </div> | |
| <div style="margin-bottom:0.5rem;font-weight:600;">Mahsulotlar:</div> | |
| ${itemsHTML} | |
| <div style="display:flex;justify-content:space-between;padding-top:1rem;font-size:1.15rem;font-weight:700;"> | |
| <span>Jami summa:</span> | |
| <span>${formatPrice(totals.total)}</span> | |
| </div> | |
| `; | |
| } | |
| async function confirmOrder() { | |
| const btn = document.querySelector('button[onclick="confirmOrder()"]'); | |
| if (btn) { btn.disabled = true; btn.textContent = "Kutilmoqda..."; } | |
| const cartItems = getCart(); // Copy before cart is cleared | |
| const user = getUser(); | |
| const totals = getCartTotal(); | |
| const orderItems = cartItems.map(item => { | |
| const p = getProductById(item.productId); | |
| return { | |
| productId: item.productId, | |
| name: p?.name || 'Mahsulot', | |
| price: p?.price || 0, | |
| size: item.size, | |
| color: item.color, | |
| quantity: item.quantity, | |
| image: p?.images?.[0] || '' | |
| }; | |
| }); | |
| const orderData = { | |
| userId: user.id || null, // Will map to ObjectId or be null | |
| customer: { | |
| name: user.name, | |
| phone: user.phone, | |
| email: user.email || '' | |
| }, | |
| items: orderItems, | |
| totals: { | |
| subtotal: totals.subtotal, | |
| discount: totals.discount, | |
| total: totals.total | |
| }, | |
| paymentMethod: paymentMethod, | |
| status: 'Kutilmoqda' | |
| }; | |
| try { | |
| const order = await API.createOrder(orderData); | |
| if (order && order.orderId) { | |
| // Deduct stock locally | |
| cartItems.forEach(item => deductProductStock(item.productId, item.quantity)); | |
| clearCart(); | |
| // Show success | |
| document.querySelectorAll('.checkout-step').forEach(el => { el.classList.remove('active'); el.style.display = 'none'; }); | |
| document.querySelector('.progress-steps').style.display = 'none'; | |
| const success = document.getElementById('stepSuccess'); | |
| success.style.display = 'block'; | |
| success.classList.add('active'); | |
| document.getElementById('orderId').textContent = `Buyurtma raqami: ${order.orderId}`; | |
| updateCartBadge(); | |
| } else { | |
| throw new Error(order.error || 'Server xatosi'); | |
| } | |
| } catch (err) { | |
| showToast('Xatolik', 'Buyurtma yuborishda xatolik yuz berdi.', 'error'); | |
| if (btn) { btn.disabled = false; btn.textContent = "Tugatish va Buyurtma berish"; } | |
| } | |
| } | |