Spaces:
Sleeping
Sleeping
| // ======================================== | |
| // ADMIN PANEL LOGIC | |
| // ======================================== | |
| const ADMIN_PASSWORD = 'admin'; // Basic auth explicitly requested for simplicity | |
| document.addEventListener('DOMContentLoaded', () => { | |
| if (sessionStorage.getItem('adminAuth') === 'true') { | |
| initAdmin(); | |
| } | |
| }); | |
| function checkAdmin() { | |
| const p = document.getElementById('adminPass').value; | |
| if (p === ADMIN_PASSWORD) { | |
| sessionStorage.setItem('adminAuth', 'true'); | |
| initAdmin(); | |
| } else { | |
| alert("Noto'g'ri parol!"); | |
| } | |
| } | |
| function initAdmin() { | |
| document.getElementById('adminLogin').style.display = 'none'; | |
| document.getElementById('adminDashboard').style.display = 'flex'; | |
| document.body.style.overflow = 'auto'; // Re-enable scrolling if disabled | |
| updateStats(); | |
| renderAdminProducts(); | |
| renderAdminOrders(); | |
| loadAdminSettings(); | |
| } | |
| function showSection(id, el) { | |
| document.querySelectorAll('.admin-section').forEach(s => s.style.display = 'none'); | |
| document.querySelectorAll('.admin-nav a').forEach(a => a.classList.remove('active')); | |
| document.getElementById('section-' + id).style.display = 'block'; | |
| if (el) el.classList.add('active'); | |
| } | |
| function updateStats() { | |
| document.getElementById('statProducts').textContent = PRODUCTS.length; | |
| // Fetch orders if they exist | |
| const orders = JSON.parse(localStorage.getItem('mtextile_orders') || '[]'); | |
| document.getElementById('statOrders').textContent = orders.length; | |
| const revenue = orders.reduce((total, o) => total + (o.totals?.total || 0), 0); | |
| document.getElementById('statRevenue').textContent = formatPrice(revenue); | |
| } | |
| // --- Settings Logic --- | |
| function loadAdminSettings() { | |
| try { | |
| const settings = JSON.parse(localStorage.getItem('mtextile_settings')) || { | |
| address: '', | |
| mapIframe: '' | |
| }; | |
| const addrInput = document.getElementById('settingAddress'); | |
| const mapInput = document.getElementById('settingMap'); | |
| const preview = document.getElementById('settingsMapPreview'); | |
| if (addrInput) addrInput.value = settings.address || ''; | |
| if (mapInput) mapInput.value = settings.mapIframe || ''; | |
| if (settings.mapIframe && preview) { | |
| preview.innerHTML = settings.mapIframe; | |
| preview.style.display = 'block'; | |
| // ensure iframe fills container | |
| const iframe = preview.querySelector('iframe'); | |
| if (iframe) { | |
| iframe.style.width = '100%'; | |
| iframe.style.height = '100%'; | |
| iframe.style.border = 'none'; | |
| } | |
| } | |
| } catch (e) { | |
| console.error("Sozlamalarni yuklashda xatolik:", e); | |
| } | |
| } | |
| function saveAdminSettings() { | |
| const address = document.getElementById('settingAddress').value.trim(); | |
| const mapIframe = document.getElementById('settingMap').value.trim(); | |
| const settings = { address, mapIframe }; | |
| localStorage.setItem('mtextile_settings', JSON.stringify(settings)); | |
| alert("Sozlamalar muvaffaqiyatli saqlandi!"); | |
| loadAdminSettings(); // Refresh preview | |
| } | |
| function renderAdminProducts() { | |
| const tbody = document.getElementById('adminProductsTable'); | |
| tbody.innerHTML = ''; | |
| PRODUCTS.slice().reverse().forEach(p => { | |
| const tr = document.createElement('tr'); | |
| tr.innerHTML = ` | |
| <td><img src="${p.images[0]}" alt="${p.name}"></td> | |
| <td><strong>${p.name}</strong></td> | |
| <td>${p.category}</td> | |
| <td>${formatPrice(p.price)}</td> | |
| <td><span class="badge ${p.inStock ? 'badge-new' : ''}">${p.inStock ? 'Mavjud' : "Tugagan"}</span></td> | |
| <td> | |
| <button class="action-btn" onclick="editProduct(${p.id})">✏️</button> | |
| <button class="action-btn delete" onclick="deleteProduct(${p.id})">🗑️</button> | |
| </td> | |
| `; | |
| tbody.appendChild(tr); | |
| }); | |
| } | |
| function renderAdminOrders() { | |
| const tbody = document.getElementById('ordersTableBody'); | |
| const orders = JSON.parse(localStorage.getItem('mtextile_orders') || '[]'); | |
| tbody.innerHTML = ''; | |
| if (orders.length === 0) { | |
| tbody.innerHTML = `<tr><td colspan="5" style="text-align:center;padding:2rem;">Hozircha buyurtmalar yo'q</td></tr>`; | |
| return; | |
| } | |
| const sortedOrders = [...orders].reverse(); | |
| sortedOrders.forEach((o, i) => { | |
| const customerName = o.customer?.name || o.name || '—'; | |
| const customerPhone = o.customer?.phone || o.phone || '—'; | |
| const orderDate = o.createdAt || o.date; | |
| const orderTotal = o.totals?.total || o.total || 0; | |
| const tr = document.createElement('tr'); | |
| tr.innerHTML = ` | |
| <td>#${o.id}</td> | |
| <td><strong>${customerName}</strong></td> | |
| <td>${customerPhone}</td> | |
| <td>${formatPrice(orderTotal)}</td> | |
| <td>${orderDate ? new Date(orderDate).toLocaleDateString() : '—'}</td> | |
| <td> | |
| <select onchange="updateOrderStatus('${o.id}', this.value)" style="padding:4px;border-radius:4px;border:1px solid var(--clr-border);background:var(--clr-surface);color:var(--clr-text-primary);cursor:pointer;"> | |
| <option value="Kutilmoqda" ${o.status === 'Kutilmoqda' || !o.status ? 'selected' : ''}>Kutilmoqda</option> | |
| <option value="Olib ketildi" ${o.status === 'Olib ketildi' ? 'selected' : ''}>Olib ketildi</option> | |
| <option value="Bekor qilindi" ${o.status === 'Bekor qilindi' ? 'selected' : ''}>Bekor qilindi</option> | |
| </select> | |
| </td> | |
| `; | |
| tbody.appendChild(tr); | |
| }); | |
| } | |
| function updateOrderStatus(orderId, newStatus) { | |
| const orders = JSON.parse(localStorage.getItem('mtextile_orders') || '[]'); | |
| const index = orders.findIndex(o => o.id === orderId); | |
| if (index > -1) { | |
| orders[index].status = newStatus; | |
| localStorage.setItem('mtextile_orders', JSON.stringify(orders)); | |
| } | |
| } | |
| function filterAdminProducts(query) { | |
| const q = query.toLowerCase().trim(); | |
| const rows = document.querySelectorAll('#adminProductsTable tr'); | |
| rows.forEach(row => { | |
| const nameColumn = row.children[1]; | |
| if (!nameColumn) return; | |
| const name = nameColumn.textContent.toLowerCase(); | |
| row.style.display = name.includes(q) ? '' : 'none'; | |
| }); | |
| } | |
| // ======================================== | |
| // CRUD OPERATIONS | |
| // ======================================== | |
| const modal = document.getElementById('productModal'); | |
| const form = document.getElementById('productForm'); | |
| function openProductModal() { | |
| form.reset(); | |
| document.getElementById('pId').value = ''; | |
| document.getElementById('modalTitle').textContent = "Mahsulot qo'shish"; | |
| modal.style.display = 'flex'; | |
| } | |
| function closeProductModal() { | |
| modal.style.display = 'none'; | |
| } | |
| function editProduct(id) { | |
| const p = getProductById(id); | |
| if (!p) return; | |
| document.getElementById('pId').value = p.id; | |
| document.getElementById('pName').value = p.name; | |
| document.getElementById('pCat').value = p.category; | |
| document.getElementById('pSubCat').value = p.subcategory; | |
| document.getElementById('pPrice').value = p.price; | |
| document.getElementById('pOldPrice').value = p.oldPrice || ''; | |
| document.getElementById('pImg').value = p.images[0]; | |
| document.getElementById('pDesc').value = p.description; | |
| document.getElementById('pNew').checked = p.isNew; | |
| document.getElementById('pFeat').checked = p.isFeatured; | |
| document.getElementById('modalTitle').textContent = "Mahsulotni tahrirlash"; | |
| modal.style.display = 'flex'; | |
| } | |
| function deleteProduct(id) { | |
| if (confirm('Rostdan ham bu mahsulotni o\'chirmoqchimisiz?')) { | |
| PRODUCTS = PRODUCTS.filter(p => p.id !== id); | |
| saveProducts(); | |
| } | |
| } | |
| form.addEventListener('submit', (e) => { | |
| e.preventDefault(); | |
| const id = document.getElementById('pId').value; | |
| const price = parseInt(document.getElementById('pPrice').value); | |
| const oldPrice = parseInt(document.getElementById('pOldPrice').value) || null; | |
| let discount = 0; | |
| if (oldPrice && oldPrice > price) { | |
| discount = Math.round(((oldPrice - price) / oldPrice) * 100); | |
| } | |
| const pData = { | |
| name: document.getElementById('pName').value, | |
| category: document.getElementById('pCat').value, | |
| subcategory: document.getElementById('pSubCat').value, | |
| price: price, | |
| oldPrice: oldPrice, | |
| discount: discount, | |
| images: [document.getElementById('pImg').value], | |
| description: document.getElementById('pDesc').value, | |
| isNew: document.getElementById('pNew').checked, | |
| isFeatured: document.getElementById('pFeat').checked, | |
| // Default properties for new products | |
| sizes: ["S", "M", "L", "XL"], | |
| colors: ["qora", "oq"], | |
| rating: 5.0, | |
| reviewCount: 0, | |
| inStock: true | |
| }; | |
| if (id) { | |
| // Edit existing | |
| const index = PRODUCTS.findIndex(p => p.id === parseInt(id)); | |
| if (index > -1) { | |
| PRODUCTS[index] = { ...PRODUCTS[index], ...pData }; | |
| } | |
| } else { | |
| // Add new | |
| pData.id = Date.now(); // Generate unique ID | |
| PRODUCTS.push(pData); | |
| } | |
| saveProducts(); | |
| closeProductModal(); | |
| }); | |
| function saveProducts() { | |
| localStorage.setItem('mtextile_products', JSON.stringify(PRODUCTS)); | |
| updateStats(); | |
| renderAdminProducts(); | |
| } | |