Replace all inline onclick handlers with addEventListener
All checks were successful
Build and Push Frontend Docker Image / build (push) Successful in 57s

Inline onclick handlers on async functions fail silently when
promises reject. This affected delete buttons, edit buttons,
modal close/cancel buttons, and pagination.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-01-08 00:28:32 +00:00
parent 965559f88d
commit ff54cf7363

View File

@@ -479,11 +479,28 @@ async function loadUsers() {
</div> </div>
</div> </div>
<div class="user-actions"> <div class="user-actions">
<button class="btn btn-sm btn-secondary" onclick="editUser(${user.id})">Edit</button> <button class="btn btn-sm btn-secondary edit-user-btn" data-user-id="${user.id}">Edit</button>
${user.id !== currentUser.id ? `<button class="btn btn-sm btn-danger" onclick="deleteUser(${user.id})">Delete</button>` : ''} ${user.id !== currentUser.id ? `<button class="btn btn-sm btn-danger delete-user-btn" data-user-id="${user.id}">Delete</button>` : ''}
</div> </div>
</div> </div>
`).join(''); `).join('');
container.querySelectorAll('.edit-user-btn').forEach(btn => {
btn.addEventListener('click', () => editUser(parseInt(btn.dataset.userId, 10)));
});
container.querySelectorAll('.delete-user-btn').forEach(btn => {
btn.addEventListener('click', async () => {
const userId = parseInt(btn.dataset.userId, 10);
if (!confirm('Are you sure you want to delete this user?')) return;
try {
await api(`/users/${userId}`, { method: 'DELETE' });
loadUsers();
} catch (error) {
alert(error.message);
}
});
});
} catch (error) { } catch (error) {
container.innerHTML = `<p class="error-message">${error.message}</p>`; container.innerHTML = `<p class="error-message">${error.message}</p>`;
} }
@@ -493,7 +510,7 @@ document.getElementById('add-user-btn').addEventListener('click', () => {
showModal(` showModal(`
<div class="modal-header"> <div class="modal-header">
<h3>Add User</h3> <h3>Add User</h3>
<button class="modal-close" onclick="hideModal()">&times;</button> <button class="modal-close">&times;</button>
</div> </div>
<form id="add-user-form"> <form id="add-user-form">
<div class="form-group"> <div class="form-group">
@@ -512,7 +529,7 @@ document.getElementById('add-user-btn').addEventListener('click', () => {
<label><input type="checkbox" name="isAdmin"> Admin</label> <label><input type="checkbox" name="isAdmin"> Admin</label>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="hideModal()">Cancel</button> <button type="button" class="btn btn-secondary modal-cancel-btn">Cancel</button>
<button type="submit" class="btn btn-primary">Create</button> <button type="submit" class="btn btn-primary">Create</button>
</div> </div>
</form> </form>
@@ -548,7 +565,7 @@ async function editUser(id) {
showModal(` showModal(`
<div class="modal-header"> <div class="modal-header">
<h3>Edit User: ${escapeHtml(user.username)}</h3> <h3>Edit User: ${escapeHtml(user.username)}</h3>
<button class="modal-close" onclick="hideModal()">&times;</button> <button class="modal-close">&times;</button>
</div> </div>
<form id="edit-user-form"> <form id="edit-user-form">
<div class="form-group"> <div class="form-group">
@@ -571,7 +588,7 @@ async function editUser(id) {
<input type="password" name="newPassword" minlength="12" placeholder="New password"> <input type="password" name="newPassword" minlength="12" placeholder="New password">
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="hideModal()">Cancel</button> <button type="button" class="btn btn-secondary modal-cancel-btn">Cancel</button>
<button type="submit" class="btn btn-primary">Save</button> <button type="submit" class="btn btn-primary">Save</button>
</div> </div>
</form> </form>
@@ -610,17 +627,6 @@ async function editUser(id) {
} }
} }
async function deleteUser(id) {
if (!confirm('Are you sure you want to delete this user?')) return;
try {
await api(`/users/${id}`, { method: 'DELETE' });
loadUsers();
} catch (error) {
alert(error.message);
}
}
async function loadAdminGallery(page = 1) { async function loadAdminGallery(page = 1) {
adminCurrentPage = page; adminCurrentPage = page;
const grid = document.getElementById('admin-gallery-grid'); const grid = document.getElementById('admin-gallery-grid');
@@ -639,8 +645,14 @@ async function loadAdminGallery(page = 1) {
// Modal // Modal
function showModal(content) { function showModal(content) {
document.getElementById('modal-content').innerHTML = content; const modalContent = document.getElementById('modal-content');
modalContent.innerHTML = content;
document.getElementById('modal-overlay').classList.remove('hidden'); document.getElementById('modal-overlay').classList.remove('hidden');
// Attach close handlers to modal-close buttons and cancel buttons
modalContent.querySelectorAll('.modal-close, .modal-cancel-btn').forEach(btn => {
btn.addEventListener('click', hideModal);
});
} }
function hideModal() { function hideModal() {
@@ -660,18 +672,26 @@ function renderPagination(container, pagination, loadFn) {
} }
let html = ''; let html = '';
html += `<button ${page === 1 ? 'disabled' : ''} onclick="(${loadFn.name})(${page - 1})">Prev</button>`; html += `<button class="pagination-btn" data-page="${page - 1}" ${page === 1 ? 'disabled' : ''}>Prev</button>`;
for (let i = 1; i <= totalPages; i++) { for (let i = 1; i <= totalPages; i++) {
if (i === 1 || i === totalPages || (i >= page - 1 && i <= page + 1)) { if (i === 1 || i === totalPages || (i >= page - 1 && i <= page + 1)) {
html += `<button class="${i === page ? 'active' : ''}" onclick="(${loadFn.name})(${i})">${i}</button>`; html += `<button class="pagination-btn ${i === page ? 'active' : ''}" data-page="${i}">${i}</button>`;
} else if (i === page - 2 || i === page + 2) { } else if (i === page - 2 || i === page + 2) {
html += '<span>...</span>'; html += '<span>...</span>';
} }
} }
html += `<button ${page === totalPages ? 'disabled' : ''} onclick="(${loadFn.name})(${page + 1})">Next</button>`; html += `<button class="pagination-btn" data-page="${page + 1}" ${page === totalPages ? 'disabled' : ''}>Next</button>`;
container.innerHTML = html; container.innerHTML = html;
container.querySelectorAll('.pagination-btn').forEach(btn => {
btn.addEventListener('click', () => {
if (!btn.disabled) {
loadFn(parseInt(btn.dataset.page, 10));
}
});
});
} }
// Utilities // Utilities