Files
hyzendust.github.io/layouts/admin/single.html
2026-06-14 15:49:41 +05:30

220 lines
5.5 KiB
HTML

{{ define "main" }}
<div id="admin-gate" style="display: none">
<p>You do not have permission to access this page.</p>
</div>
<div id="admin-panel" style="display: none">
<h1>User Management</h1>
<label class="admin-search" for="admin-user-search">
<span class="admin-search__label">Search users</span>
<input
id="admin-user-search"
class="admin-search__input"
type="search"
placeholder="Search by username or email"
autocomplete="off"
/>
</label>
<div id="admin-msg" class="auth-message" style="display: none" aria-live="polite"></div>
<div id="admin-table-wrap"></div>
</div>
<script>
(function () {
var BACKEND = 'https://backend.freedoms4.org/admin.php';
var username = localStorage.getItem('f4_username');
var gate = document.getElementById('admin-gate');
var panel = document.getElementById('admin-panel');
var msg = document.getElementById('admin-msg');
var wrap = document.getElementById('admin-table-wrap');
var search = document.getElementById('admin-user-search');
var allUsers = [];
if (username !== 'hyzen') {
gate.style.display = '';
return;
}
panel.style.display = '';
function showMsg(text, type) {
msg.textContent = text;
msg.className = 'auth-message auth-message--' + type;
msg.style.display = 'block';
setTimeout(function () {
msg.style.display = 'none';
}, 3000);
}
function escHtml(s) {
return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
function renderTable(users) {
if (!users.length) {
wrap.innerHTML = '<p>No matching users found.</p>';
return;
}
var html =
'<table class="admin-table">' +
'<tbody><tr class="admin-table__header">' +
'<th>#</th><th>Username</th><th>Email</th><th>Joined</th><th>Status</th><th>Actions</th>' +
'</tr>';
function userRow(u) {
var joined = new Date(u.created_at).toLocaleDateString();
var blocked = u.blocked === true || u.blocked === 't' || u.blocked === '1';
var status = blocked
? '<span class="admin-badge admin-badge--blocked">Blocked</span>'
: '<span class="admin-badge admin-badge--active">Active</span>';
var blockBtn = blocked
? '<button class="admin-btn admin-btn--unblock" data-id="' +
u.id +
'" data-action="unblock_user">Unblock</button>'
: '<button class="admin-btn admin-btn--block" data-id="' +
u.id +
'" data-action="block_user">Block</button>';
var deleteBtn =
'<button class="admin-btn admin-btn--delete" data-id="' +
u.id +
'" data-username="' +
escHtml(u.username) +
'" data-action="delete_user">Delete Records</button>';
return (
'<tr id="user-row-' +
u.id +
'">' +
'<td>' +
u.id +
'</td>' +
'<td>' +
escHtml(u.username) +
'</td>' +
'<td>' +
escHtml(u.email) +
'</td>' +
'<td>' +
joined +
'</td>' +
'<td>' +
status +
'</td>' +
'<td class="admin-actions">' +
blockBtn +
' ' +
deleteBtn +
'</td>' +
'</tr>'
);
}
users.forEach(function (u) {
html += userRow(u);
});
html += '</tbody></table>';
wrap.innerHTML = html;
wrap.querySelectorAll('[data-action]').forEach(function (btn) {
btn.addEventListener('click', function () {
var action = btn.dataset.action;
var id = parseInt(btn.dataset.id, 10);
var uname = btn.dataset.username || '';
if (action === 'delete_user') {
if (
!confirm(
'Permanently delete user ' + uname + '? This cannot be undone.'
)
)
return;
} else if (action === 'block_user') {
if (
!confirm(
"This will permanently delete the user's email history and cannot be undone."
)
)
return;
}
btn.disabled = true;
fetch(BACKEND, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ action: action, user_id: id }),
})
.then(function (r) {
return r.json();
})
.then(function (data) {
if (data.success) {
if (action === 'delete_user') {
allUsers = allUsers.filter(function (u) {
return Number(u.id) !== id;
});
filterUsers();
showMsg('User deleted.', 'success');
} else {
loadUsers();
}
} else {
showMsg(data.message || 'Action failed.', 'error');
btn.disabled = false;
}
})
.catch(function () {
showMsg('Network error.', 'error');
btn.disabled = false;
});
});
});
}
function loadUsers() {
wrap.innerHTML = '<p>Loading&hellip;</p>';
fetch(BACKEND + '?action=list_users', {
credentials: 'include',
})
.then(function (r) {
return r.json();
})
.then(function (data) {
if (data.success) {
allUsers = data.users;
filterUsers();
} else {
wrap.innerHTML =
'<p class="admin-error">' +
escHtml(data.message || 'Failed to load users.') +
'</p>';
}
})
.catch(function () {
wrap.innerHTML = '<p class="admin-error">Network error.</p>';
});
}
function filterUsers() {
var query = search.value.trim().toLowerCase();
var users = allUsers.filter(function (u) {
return (
u.username !== username &&
(!query ||
String(u.username).toLowerCase().includes(query) ||
String(u.email).toLowerCase().includes(query))
);
});
renderTable(users);
}
search.addEventListener('input', filterUsers);
loadUsers();
})();
</script>
{{ end }}