mtextylelastedweb / js /checkout.js
ibrohm's picture
Initial deploy via assistant API
eb4179c verified
// ========================================
// 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"; }
}
}