// Mobile menu function toggleMobileMenu() { const overlay = document.getElementById('mobile-menu-overlay'); const panel = document.getElementById('mobile-menu-panel'); if (!overlay || !panel) return; const isOpen = panel.style.display === 'block'; if (isOpen) { overlay.style.display = 'none'; panel.style.display = 'none'; } else { overlay.style.display = 'block'; panel.style.display = 'block'; document.querySelectorAll('.mm-item').forEach(function(el) { el.classList.toggle('active', el.dataset.page === window._currentPage); }); const mmUsers = document.getElementById('mm-users'); if (mmUsers && window._currentUser) { mmUsers.style.display = window._currentUser.role === 'admin' ? '' : 'none'; } } } function closeMobileMenu() { const overlay = document.getElementById('mobile-menu-overlay'); const panel = document.getElementById('mobile-menu-panel'); if (overlay) overlay.style.display = 'none'; if (panel) panel.style.display = 'none'; } // Handle mm-item clicks document.addEventListener('click', function(e) { const item = e.target.closest('.mm-item'); if (item && item.dataset.page) { closeMobileMenu(); setPage(item.dataset.page); } }); // Sidebar toggle for mobile function toggleSidebar() { const sidebar = document.querySelector('.sidebar'); if (!sidebar) return; const isOpen = sidebar.style.transform === 'translateX(0px)' || sidebar.classList.contains('open'); if (isOpen) { sidebar.style.transform = ''; sidebar.classList.remove('open'); document.getElementById('sidebar-overlay') && document.getElementById('sidebar-overlay').remove(); } else { sidebar.style.transform = 'translateX(0)'; sidebar.classList.add('open'); const ov = document.createElement('div'); ov.id = 'sidebar-overlay'; ov.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.4);z-index:49'; ov.onclick = function(){ toggleSidebar(); }; document.body.appendChild(ov); } }
Маркетинг
Яндекс Метрика · трафик и конверсии
АМ
Заказов
--
загрузка...
Выручка
--
загрузка...
Себестоимость
--
затраты
Прибыль
--
маржа
Средний чек
--
за заказ
Воронка продаж
Конверсия сегодня
Загрузка...
Деньги по каналам
Яндекс Метрика
Загрузка...
Топ товаров за неделю
По прибыли · с остатками
Загрузка...
Курьеры
Доставки сегодня
Загрузка...
По часам
vs вчера
Загрузка...
'; document.body.appendChild(modal); const roleEl=document.getElementById('um-role'); if(roleEl) roleEl.addEventListener('change',function(){const ps=document.getElementById('um-pages-section');if(ps)ps.style.display=this.value==='admin'?'none':'';}); if(user&&user.role==='admin'){const ps=document.getElementById('um-pages-section');if(ps)ps.style.display='none';} } async function saveUser(id){ const name=document.getElementById('um-name').value.trim(); const username=document.getElementById('um-username').value.trim(); const password=document.getElementById('um-password').value; const role=document.getElementById('um-role').value; const activeEl=document.getElementById('um-active'); const active=activeEl?activeEl.checked:true; const pages=Array.from(document.querySelectorAll('#um-pages-section input[type=checkbox]:checked')).map(function(c){return c.value;}); const err=document.getElementById('um-err'); if(!name){err.textContent='Введите имя';err.style.display='block';return;} if(!id&&!password){err.textContent='Введите пароль';err.style.display='block';return;} err.style.display='none'; try{ const token=localStorage.getItem('auth_token'); const body={name:name,role:role,active:active,pages:pages}; if(password) body.password=password; if(!id) body.username=username; const r=await fetch(id?'/api/auth/users/'+id:'/api/auth/users',{method:id?'PUT':'POST',headers:{'Content-Type':'application/json','x-auth-token':token},body:JSON.stringify(body)}); const data=await r.json(); if(!r.ok){err.textContent=data.error;err.style.display='block';return;} const m=document.getElementById('user-modal');if(m)m.remove(); showToast('Пользователь сохранён','success'); loadUsersList(); }catch(e){err.textContent='Ошибка';err.style.display='block';} } async function deleteUser(id){ if(!confirm('Удалить пользователя?')) return; const r=await fetch('/api/auth/users/'+id,{method:'DELETE',headers:{'x-auth-token':localStorage.getItem('auth_token')}}); if(r.ok){const m=document.getElementById('user-modal');if(m)m.remove();showToast('Пользователь удалён','info');loadUsersList();} }