Files
Py-3XUI-multiserver/web/js/admin.js
T

115 lines
4.1 KiB
JavaScript

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);
}
});
}
}