function openModal() { document.getElementById('userModal').classList.add('active'); } function closeModal() { document.getElementById('userModal').classList.remove('active'); } function toast(msg, ok) { var t = document.createElement('div'); t.textContent = msg; Object.assign(t.style, { position:'fixed', bottom:'24px', left:'50%', transform:'translateX(-50%)', padding:'12px 24px', borderRadius:'12px', fontSize:'13px', fontWeight:'600', background: ok ? 'rgba(16,185,129,0.15)' : 'rgba(244,63,94,0.15)', border: ok ? '1px solid rgba(16,185,129,0.3)' : '1px solid rgba(244,63,94,0.3)', color: ok ? 'var(--green)' : 'var(--rose)', backdropFilter:'blur(12px)', zIndex:'9999', animation:'fadeUp .3s ease-out both', fontFamily:'"Plus Jakarta Sans",sans-serif' }); document.body.appendChild(t); setTimeout(function() { t.style.opacity='0'; t.style.transition='opacity .4s'; setTimeout(function(){t.remove()},400) }, 3000); } document.addEventListener('DOMContentLoaded', function() { var form = document.getElementById('userForm'); if (form) { form.addEventListener('submit', async function(e) { e.preventDefault(); var formData = new FormData(e.target); var username = formData.get('username'); var btn = e.target.querySelector('button[type="submit"]'); var orig = btn.textContent; btn.disabled = true; btn.textContent = '...'; var response = await fetch('/admin/api/users', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ username: username, traffic_limit_gb: parseInt(formData.get('traffic_limit_gb')) || 0 }) }); var result = await response.json(); if (response.ok) { var msg = 'Пользователь ' + username + ' создан!'; toast(msg, true); setTimeout(function(){ location.reload() }, 1000); } else { toast('Ошибка: ' + (result.error || 'unknown'), false); btn.disabled = false; btn.textContent = orig; } }); } }); function editUser(id, tier, days, traffic, active) { document.getElementById('editId').value = id; document.getElementById('et').value = tier; document.getElementById('ed').value = days; document.getElementById('etr').value = traffic; document.getElementById('editActive').checked = active == 1; document.getElementById('editModal').classList.add('active'); } function closeEditModal() { document.getElementById('editModal').classList.remove('active'); } async function submitEditForm() { var form = document.getElementById('editForm'); var formData = new FormData(form); var data = { id: formData.get('id'), tier: formData.get('tier'), tariff_days_remaining: parseInt(formData.get('tariff_days_remaining')) || 0, traffic_limit_gb: formData.get('traffic_limit_gb') === '' ? 0 : parseInt(formData.get('traffic_limit_gb')), is_active: formData.get('is_active') === 'on' }; var btn = form.querySelector('button'); var orig = btn.textContent; btn.disabled = true; btn.textContent = '...'; var response = await fetch('/admin/api/users/update', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(data) }); if (response.ok) { toast('Сохранено!', true); setTimeout(function(){ location.reload() }, 1000); } else { var result = await response.json(); toast('Ошибка: ' + (result.error || 'unknown'), false); btn.disabled = false; btn.textContent = orig; } } function deleteUser(id, username) { if (confirm('Удалить пользователя ' + username + '? Это удалит его со всех серверов!')) { fetch('/admin/api/users/delete', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({id: id, username: username}) }).then(function(r) { if (r.ok) { toast('Удалён!', true); setTimeout(function(){ location.reload() }, 1000); } else { toast('Ошибка удаления', false); } }); } }