Update: search panel, colors

This commit is contained in:
hyzen
2026-06-13 12:04:53 +05:30
parent e79fa2eb5f
commit bae7bd8325
4 changed files with 126 additions and 26 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1364,6 +1364,7 @@
border-collapse: collapse; border-collapse: collapse;
font-size: 0.88rem; font-size: 0.88rem;
margin-top: 1rem; margin-top: 1rem;
background: var(--background-color);
} }
.admin-table th, .admin-table th,
@@ -1373,9 +1374,9 @@
border-bottom: 1px solid var(--background-color1, #e0e0e0); border-bottom: 1px solid var(--background-color1, #e0e0e0);
} }
.admin-table th { .admin-table__header th {
font-weight: 700; font-weight: 700;
background: var(--background-color1, #f5f5f5); background: var(--background-color);
} }
.admin-table tr:last-child td { .admin-table tr:last-child td {
@@ -1400,11 +1401,39 @@
background: #d4edda; background: #d4edda;
color: #155724; color: #155724;
} }
.admin-badge--admin {
background: #dbeafe;
color: #1e3a8a;
}
.admin-badge--blocked { .admin-badge--blocked {
background: #f8d7da; background: #f8d7da;
color: #721c24; color: #721c24;
} }
.admin-search {
display: block;
max-width: 32rem;
margin-top: 1rem;
}
.admin-search__label {
display: block;
margin-bottom: 0.35rem;
font-size: 0.88rem;
font-weight: 600;
}
.admin-search__input {
box-sizing: border-box;
width: 100%;
padding: 0.55rem 0.7rem;
border: 1px solid var(--background-color1, #ccc);
border-radius: 4px;
background: var(--background-color);
color: var(--foreground-color);
font: inherit;
}
.admin-btn { .admin-btn {
padding: 0.25rem 0.65rem; padding: 0.25rem 0.65rem;
border: none; border: none;

View File

@@ -6,6 +6,16 @@
<div id="admin-panel" style="display: none"> <div id="admin-panel" style="display: none">
<h1>User Management</h1> <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-msg" class="auth-message" style="display: none" aria-live="polite"></div>
<div id="admin-table-wrap"></div> <div id="admin-table-wrap"></div>
</div> </div>
@@ -19,6 +29,8 @@
var panel = document.getElementById('admin-panel'); var panel = document.getElementById('admin-panel');
var msg = document.getElementById('admin-msg'); var msg = document.getElementById('admin-msg');
var wrap = document.getElementById('admin-table-wrap'); var wrap = document.getElementById('admin-table-wrap');
var search = document.getElementById('admin-user-search');
var allUsers = [];
if (username !== 'hyzen') { if (username !== 'hyzen') {
gate.style.display = ''; gate.style.display = '';
@@ -41,24 +53,32 @@
function renderTable(users) { function renderTable(users) {
if (!users.length) { if (!users.length) {
wrap.innerHTML = '<p>No users found.</p>'; wrap.innerHTML = '<p>No matching users found.</p>';
return; return;
} }
var adminIndex = users.findIndex(function (u) {
return u.username === username;
});
var adminUser = adminIndex === -1 ? null : users[adminIndex];
var otherUsers = users.filter(function (u) {
return u.username !== username;
});
var html = var html =
'<table class="admin-table">' + '<table class="admin-table">' +
'<thead><tr>' + '<tbody><tr class="admin-table__header">' +
'<th>#</th><th>Username</th><th>Email</th><th>Joined</th><th>Status</th><th>Actions</th>' + '<th>#</th><th>Username</th><th>Email</th><th>Joined</th><th>Status</th>' +
'</tr></thead><tbody>'; (adminUser ? '<th rowspan="2">Actions</th>' : '<th>Actions</th>') +
'</tr>';
users.forEach(function (u) { function userRow(u, isCurrentUser) {
var joined = new Date(u.created_at).toLocaleDateString(); var joined = new Date(u.created_at).toLocaleDateString();
var blocked = u.blocked === true || u.blocked === 't' || u.blocked === '1'; var blocked = u.blocked === true || u.blocked === 't' || u.blocked === '1';
var status = blocked var status = isCurrentUser
? '<span class="admin-badge admin-badge--blocked">Blocked</span>' ? '<span class="admin-badge admin-badge--admin">Admin</span>'
: '<span class="admin-badge admin-badge--active">Active</span>'; : blocked
? '<span class="admin-badge admin-badge--blocked">Blocked</span>'
var isCurrentUser = u.username === username; : '<span class="admin-badge admin-badge--active">Active</span>';
var blockBtn = ''; var blockBtn = '';
var deleteBtn = ''; var deleteBtn = '';
@@ -79,7 +99,7 @@
'" data-action="delete_user">Delete Records</button>'; '" data-action="delete_user">Delete Records</button>';
} }
html += return (
'<tr id="user-row-' + '<tr id="user-row-' +
u.id + u.id +
'">' + '">' +
@@ -98,12 +118,18 @@
'<td>' + '<td>' +
status + status +
'</td>' + '</td>' +
'<td class="admin-actions">' + (isCurrentUser
blockBtn + ? ''
' ' + : '<td class="admin-actions">' + blockBtn + ' ' + deleteBtn + '</td>') +
deleteBtn + '</tr>'
'</td>' + );
'</tr>'; }
if (adminUser) {
html += userRow(adminUser, true);
}
otherUsers.forEach(function (u) {
html += userRow(u, false);
}); });
html += '</tbody></table>'; html += '</tbody></table>';
@@ -145,11 +171,12 @@
.then(function (data) { .then(function (data) {
if (data.success) { if (data.success) {
if (action === 'delete_user') { if (action === 'delete_user') {
var row = document.getElementById('user-row-' + id); allUsers = allUsers.filter(function (u) {
if (row) row.remove(); return Number(u.id) !== id;
});
filterUsers();
showMsg('User deleted.', 'success'); showMsg('User deleted.', 'success');
} else { } else {
// Reload to reflect new block state
loadUsers(); loadUsers();
} }
} else { } else {
@@ -175,7 +202,8 @@
}) })
.then(function (data) { .then(function (data) {
if (data.success) { if (data.success) {
renderTable(data.users); allUsers = data.users;
filterUsers();
} else { } else {
wrap.innerHTML = wrap.innerHTML =
'<p class="admin-error">' + '<p class="admin-error">' +
@@ -188,6 +216,19 @@
}); });
} }
function filterUsers() {
var query = search.value.trim().toLowerCase();
var users = allUsers.filter(function (u) {
return (
!query ||
String(u.username).toLowerCase().includes(query) ||
String(u.email).toLowerCase().includes(query)
);
});
renderTable(users);
}
search.addEventListener('input', filterUsers);
loadUsers(); loadUsers();
})(); })();
</script> </script>

View File

@@ -1364,6 +1364,7 @@
border-collapse: collapse; border-collapse: collapse;
font-size: 0.88rem; font-size: 0.88rem;
margin-top: 1rem; margin-top: 1rem;
background: var(--background-color);
} }
.admin-table th, .admin-table th,
@@ -1373,9 +1374,9 @@
border-bottom: 1px solid var(--background-color1, #e0e0e0); border-bottom: 1px solid var(--background-color1, #e0e0e0);
} }
.admin-table th { .admin-table__header th {
font-weight: 700; font-weight: 700;
background: var(--background-color1, #f5f5f5); background: var(--background-color);
} }
.admin-table tr:last-child td { .admin-table tr:last-child td {
@@ -1400,11 +1401,39 @@
background: #d4edda; background: #d4edda;
color: #155724; color: #155724;
} }
.admin-badge--admin {
background: #dbeafe;
color: #1e3a8a;
}
.admin-badge--blocked { .admin-badge--blocked {
background: #f8d7da; background: #f8d7da;
color: #721c24; color: #721c24;
} }
.admin-search {
display: block;
max-width: 32rem;
margin-top: 1rem;
}
.admin-search__label {
display: block;
margin-bottom: 0.35rem;
font-size: 0.88rem;
font-weight: 600;
}
.admin-search__input {
box-sizing: border-box;
width: 100%;
padding: 0.55rem 0.7rem;
border: 1px solid var(--background-color1, #ccc);
border-radius: 4px;
background: var(--background-color);
color: var(--foreground-color);
font: inherit;
}
.admin-btn { .admin-btn {
padding: 0.25rem 0.65rem; padding: 0.25rem 0.65rem;
border: none; border: none;