'use strict'; /* admin → shop section: items + purchases */ (function () { 'use strict'; let inited = false; let _shopItems = []; async function load() { try { const [stats, items] = await Promise.all([ LS.adminShopStats(), LS.adminShopGetItems() ]); const topName = stats.topItems?.[0]?.name || '—'; document.getElementById('shop-stats-grid').innerHTML = `
${stats.activeItems}/${stats.totalItems}
Товаров
${stats.totalPurchases}
Покупок
${stats.totalCoinsInCirculation}
Монет в обороте
${esc(topName)}
Топ товар
`; _shopItems = items; renderShopItems(); if (window.lucide) lucide.createIcons(); } catch(e) { document.getElementById('shop-stats-grid').innerHTML = `
Ошибка: ${esc(e.message)}
`; } } function renderShopItems() { const body = document.getElementById('shop-items-body'); if (!_shopItems.length) { body.innerHTML = 'Нет товаров'; return; } const typeLabels = { frame:'Рамка', title:'Титул', theme:'Тема', effect:'Эффект', background:'Фон' }; body.innerHTML = _shopItems.map(it => ` ${it.id} ${esc(it.name)} ${typeLabels[it.type] || esc(it.type)} ${it.price} ${it.sold_count || 0} `).join(''); if (window.lucide) lucide.createIcons(); } const TYPE_OPTIONS = [ { v: 'frame', l: 'Рамка' }, { v: 'title', l: 'Титул' }, { v: 'background', l: 'Фон' }, { v: 'effect', l: 'Эффект' }, ]; /* Open the add/edit item modal. item = null → create, object → edit. */ function openItemModal(item) { const isEdit = !!item; const dataStr = item && item.data ? (typeof item.data === 'string' ? item.data : JSON.stringify(item.data)) : ''; const body = document.createElement('div'); body.innerHTML = `
`; const $ = sel => body.querySelector(sel); $('#shop-f-name').value = item?.name || ''; $('#shop-f-type').value = item?.type || 'frame'; $('#shop-f-price').value = item?.price ?? 100; $('#shop-f-desc').value = item?.description || ''; $('#shop-f-icon').value = item?.icon || ''; $('#shop-f-data').value = dataStr; $('#shop-f-active').checked = item ? !!item.is_active : true; let saving = false; const m = LS.modal({ title: isEdit ? ('Редактировать товар #' + item.id) : 'Добавить товар', content: body, size: 'md', actions: [ { label: 'Отмена', onClick: () => m.close() }, { label: 'Сохранить', primary: true, id: 'shop-save-btn', onClick: async () => { if (saving) return; const payload = { name: $('#shop-f-name').value.trim(), type: $('#shop-f-type').value, price: parseInt($('#shop-f-price').value, 10) || 0, description: $('#shop-f-desc').value.trim(), icon: $('#shop-f-icon').value.trim(), data: $('#shop-f-data').value.trim() || null, is_active: $('#shop-f-active').checked ? 1 : 0, }; if (!payload.name) { m.setError('Введите название'); return; } if (payload.data) { try { JSON.parse(payload.data); } catch { m.setError('Поле «Данные» — некорректный JSON'); return; } } saving = true; const btn = document.getElementById('shop-save-btn'); if (btn) { btn.disabled = true; btn.textContent = 'Сохранение…'; } try { if (isEdit) { await LS.adminShopUpdateItem(item.id, payload); LS.toast('Товар обновлён', 'success'); } else { await LS.adminShopCreateItem(payload); LS.toast('Товар создан', 'success'); } m.close(); inited = false; await load(); inited = true; } catch(e) { m.setError('Ошибка: ' + e.message); saving = false; if (btn) { btn.disabled = false; btn.textContent = 'Сохранить'; } } } }, ], }); setTimeout(() => $('#shop-f-name')?.focus(), 80); } function shopAdminCreateItem() { openItemModal(null); } function shopAdminEditItem(id) { const it = _shopItems.find(i => i.id === id); if (it) openItemModal(it); } async function shopAdminDeleteItem(id) { if (!await LS.confirm('Все покупки этого товара будут удалены.', { title: 'Удалить товар?', confirmText: 'Удалить', danger: true })) return; try { await LS.adminShopDeleteItem(id); LS.toast('Товар удалён', 'success'); inited = false; await load(); inited = true; } catch(e) { LS.toast('Ошибка: ' + e.message, 'error'); } } async function shopAdminToggleActive(id, active) { try { await LS.adminShopUpdateItem(id, { is_active: active ? 1 : 0 }); LS.toast(active ? 'Товар активирован' : 'Товар деактивирован', 'success'); } catch(e) { LS.toast('Ошибка: ' + e.message, 'error'); } } // Expose onclick handlers window.shopAdminCreateItem = shopAdminCreateItem; window.shopAdminEditItem = shopAdminEditItem; window.shopAdminDeleteItem = shopAdminDeleteItem; window.shopAdminToggleActive = shopAdminToggleActive; window.AdminSections = window.AdminSections || {}; window.AdminSections.shop = { init: async () => { if (inited) return; inited = true; await load(); }, reload: load, }; })();