From c2e7cfe9430ea0634e111bfed041e11512c159cd Mon Sep 17 00:00:00 2001 From: Luis Pereira Date: Sat, 4 Oct 2025 17:49:17 +0100 Subject: [PATCH] feat: move users javascript code to own file --- static/js/users.js | 220 +++++++++++++++++++++++++++++++++++++++++++ template/users.chtml | 216 +----------------------------------------- 2 files changed, 221 insertions(+), 215 deletions(-) create mode 100644 static/js/users.js diff --git a/static/js/users.js b/static/js/users.js new file mode 100644 index 0000000..22b184c --- /dev/null +++ b/static/js/users.js @@ -0,0 +1,220 @@ +// Load user stats on page load +document.addEventListener('DOMContentLoaded', function() { + loadUserStats(); +}); + +async function loadUserStats() { + try { + const response = await fetch('/asteroid/api/users/stats'); + const result = await response.json(); + + if (result.status === 'success') { + // TODO: move this stats builder to server + // const stats = result.stats; + const stats = { + total: 0, + active: 0, + admins: 0, + djs: 0, + }; + if (result.users) { + result.users.forEach((user) => { + stats.total += 1; + if (user.active) stats.active += 1; + if (user.role == "admin") stats.admins += 1; + if (user.role == "dj") stats.djs += 1; + }) + } + document.getElementById('total-users').textContent = stats.total; + document.getElementById('active-users').textContent = stats.active; + document.getElementById('admin-users').textContent = stats.admins; + document.getElementById('dj-users').textContent = stats.djs; + } + } catch (error) { + console.error('Error loading user stats:', error); + } +} + +async function loadUsers() { + try { + const response = await fetch('/asteroid/api/users'); + const result = await response.json(); + + if (result.status === 'success') { + showUsersTable(result.users); + document.getElementById('users-list-section').style.display = 'block'; + } + } catch (error) { + console.error('Error loading users:', error); + alert('Error loading users. Please try again.'); + } +} + +function showUsersTable(users) { + const container = document.getElementById('users-container'); + container.innerHTML = ` + + + + + + + + + + + + + ${users.map(user => ` + + + + + + + + + `).join('')} + +
UsernameEmailRoleStatusLast LoginActions
${user.username}${user.email} + + ${user.active ? '✅ Active' : '❌ Inactive'}${user['last-login'] ? new Date(user['last-login'] * 1000).toLocaleString() : 'Never'}
+ + `; +} + +function hideUsersTable() { + document.getElementById('users-list-section').style.display = 'none'; +} + +async function updateUserRole(userId, newRole) { + try { + const formData = new FormData(); + formData.append('role', newRole); + + const response = await fetch(`/asteroid/api/users/${userId}/role`, { + method: 'POST', + body: formData + }); + + const result = await response.json(); + + if (result.status === 'success') { + loadUserStats(); + alert('User role updated successfully'); + } else { + alert('Error updating user role: ' + result.message); + } + } catch (error) { + console.error('Error updating user role:', error); + alert('Error updating user role. Please try again.'); + } +} + +async function deactivateUser(userId) { + if (!confirm('Are you sure you want to deactivate this user?')) { + return; + } + + try { + const response = await fetch(`/asteroid/api/users/${userId}/deactivate`, { + method: 'POST' + }); + + const result = await response.json(); + + if (result.status === 'success') { + loadUsers(); + loadUserStats(); + alert('User deactivated successfully'); + } else { + alert('Error deactivating user: ' + result.message); + } + } catch (error) { + console.error('Error deactivating user:', error); + alert('Error deactivating user. Please try again.'); + } +} + +async function activateUser(userId) { + try { + const response = await fetch(`/asteroid/api/users/${userId}/activate`, { + method: 'POST' + }); + + const result = await response.json(); + + if (result.status === 'success') { + loadUsers(); + loadUserStats(); + alert('User activated successfully'); + } else { + alert('Error activating user: ' + result.message); + } + } catch (error) { + console.error('Error activating user:', error); + alert('Error activating user. Please try again.'); + } +} + +function toggleCreateUserForm() { + const form = document.getElementById('create-user-form'); + if (form.style.display === 'none') { + form.style.display = 'block'; + // Clear form + document.getElementById('new-username').value = ''; + document.getElementById('new-email').value = ''; + document.getElementById('new-password').value = ''; + document.getElementById('new-role').value = 'listener'; + } else { + form.style.display = 'none'; + } +} + +async function createNewUser(event) { + event.preventDefault(); + + const username = document.getElementById('new-username').value; + const email = document.getElementById('new-email').value; + const password = document.getElementById('new-password').value; + const role = document.getElementById('new-role').value; + + try { + const formData = new FormData(); + formData.append('username', username); + formData.append('email', email); + formData.append('password', password); + formData.append('role', role); + + const response = await fetch('/asteroid/api/users/create', { + method: 'POST', + body: formData + }); + + const result = await response.json(); + + if (result.status === 'success') { + alert(`User "${username}" created successfully!`); + toggleCreateUserForm(); + loadUserStats(); + loadUsers(); + } else { + alert('Error creating user: ' + result.message); + } + } catch (error) { + console.error('Error creating user:', error); + alert('Error creating user. Please try again.'); + } +} + +// Update user stats every 30 seconds +setInterval(loadUserStats, 30000); diff --git a/template/users.chtml b/template/users.chtml index 32b5b9f..e96d19f 100644 --- a/template/users.chtml +++ b/template/users.chtml @@ -5,6 +5,7 @@ +
@@ -86,220 +87,5 @@
- -