asteroid/template/users.chtml

306 lines
10 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<title data-text="title">Asteroid Radio - User Management</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="/asteroid/static/asteroid.css">
</head>
<body>
<div class="container">
<h1>👥 USER MANAGEMENT</h1>
<div class="nav">
<a href="/asteroid/admin">← Back to Admin</a>
<a href="/asteroid/">Home</a>
</div>
<!-- User Statistics -->
<div class="admin-section">
<h2>User Statistics</h2>
<div class="user-stats" id="user-stats">
<div class="stat-card">
<span class="stat-number" id="total-users">0</span>
<span class="stat-label">Total Users</span>
</div>
<div class="stat-card">
<span class="stat-number" id="active-users">0</span>
<span class="stat-label">Active Users</span>
</div>
<div class="stat-card">
<span class="stat-number" id="admin-users">0</span>
<span class="stat-label">Admins</span>
</div>
<div class="stat-card">
<span class="stat-number" id="dj-users">0</span>
<span class="stat-label">DJs</span>
</div>
</div>
</div>
<!-- User Management Actions -->
<div class="admin-section">
<h2>User Actions</h2>
<div class="controls">
<button class="btn btn-primary" onclick="loadUsers()">👥 View All Users</button>
<button class="btn btn-success" onclick="toggleCreateUserForm()"> Create New User</button>
<button class="btn btn-secondary" onclick="refreshStats()">🔄 Refresh Stats</button>
</div>
</div>
<!-- Create User Form (hidden by default) -->
<div class="admin-section" id="create-user-form" style="display: none;">
<h2>Create New User</h2>
<form onsubmit="createNewUser(event)">
<div class="form-group">
<label>Username:</label>
<input type="text" id="new-username" required>
</div>
<div class="form-group">
<label>Email:</label>
<input type="email" id="new-email" required>
</div>
<div class="form-group">
<label>Password:</label>
<input type="password" id="new-password" required minlength="6">
</div>
<div class="form-group">
<label>Role:</label>
<select id="new-role">
<option value="listener">Listener</option>
<option value="dj">DJ</option>
<option value="admin">Admin</option>
</select>
</div>
<div class="controls">
<button type="submit" class="btn btn-success">Create User</button>
<button type="button" class="btn btn-secondary" onclick="toggleCreateUserForm()">Cancel</button>
</div>
</form>
</div>
<!-- User List Container (populated by JavaScript) -->
<div class="admin-section" id="users-list-section" style="display: none;">
<h2>All Users</h2>
<div id="users-container">
<!-- Users table will be inserted here by JavaScript -->
</div>
</div>
</div>
<script>
// User Management JavaScript
// 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') {
const stats = result.stats;
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 = `
<table class="users-table">
<thead>
<tr>
<th>Username</th>
<th>Email</th>
<th>Role</th>
<th>Status</th>
<th>Last Login</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
${users.map(user => `
<tr>
<td>${user.username}</td>
<td>${user.email}</td>
<td>
<select onchange="updateUserRole('${user.id}', this.value)">
<option value="listener" ${user.role === 'listener' ? 'selected' : ''}>Listener</option>
<option value="dj" ${user.role === 'dj' ? 'selected' : ''}>DJ</option>
<option value="admin" ${user.role === 'admin' ? 'selected' : ''}>Admin</option>
</select>
</td>
<td>${user.active ? '✅ Active' : '❌ Inactive'}</td>
<td>${user['last-login'] ? new Date(user['last-login'] * 1000).toLocaleString() : 'Never'}</td>
<td class="user-actions">
${user.active ?
`<button class="btn btn-danger" onclick="deactivateUser('${user.id}')">Deactivate</button>` :
`<button class="btn btn-success" onclick="activateUser('${user.id}')">Activate</button>`
}
</td>
</tr>
`).join('')}
</tbody>
</table>
<button class="btn btn-secondary" onclick="hideUsersTable()">Close</button>
`;
}
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.');
}
}
function refreshStats() {
loadUserStats();
alert('Stats refreshed!');
}
// Update user stats every 30 seconds
setInterval(loadUserStats, 30000);
</script>
</body>
</html>