import { api } from '../api.js';
export class AdminDashboard extends HTMLElement {
constructor() {
super();
this.users = [];
}
async connectedCallback() {
await this.loadUsers();
}
async loadUsers() {
try {
this.users = await api.listUsers();
this.render();
} catch (error) {
console.error('Failed to load users:', error);
this.innerHTML = '<p class="error-message">Failed to load users. Do you have admin privileges?</p>';
}
}
render() {
this.innerHTML = `
<div class="admin-dashboard-container">
<h2>Admin Dashboard</h2>
<div class="admin-section">
<h3>User Management</h3>
<button id="createUserButton" class="button button-primary">Create New User</button>
<div class="user-list">
${this.users.map(user => this.renderUser(user)).join('')}
</div>
</div>
<div id="userModal" class="modal">
<div class="modal-content">
<span class="close-button">&times;</span>
<h3>Edit User</h3>
<form id="userForm">
<input type="hidden" id="userId">
<label for="username">Username:</label>
<input type="text" id="username" required>
<label for="email">Email:</label>
<input type="email" id="email" required>
<label for="password">Password (leave blank to keep current):</label>
<input type="password" id="password">
<label for="isSuperuser">Superuser:</label>
<input type="checkbox" id="isSuperuser">
<label for="isActive">Active:</label>
<input type="checkbox" id="isActive">
<label for="is2faEnabled">2FA Enabled:</label>
<input type="checkbox" id="is2faEnabled">
<label for="storageQuotaBytes">Storage Quota (Bytes):</label>
<input type="number" id="storageQuotaBytes">
<label for="planType">Plan Type:</label>
<input type="text" id="planType">
<button type="submit" class="button button-primary">Save</button>
</form>
</div>
</div>
</div>
`;
this.querySelector('#createUserButton').addEventListener('click', () => this._showUserModal());
this.querySelector('.user-list').addEventListener('click', this._handleUserAction.bind(this));
this.querySelector('.close-button').addEventListener('click', () => this.querySelector('#userModal').style.display = 'none');
this.querySelector('#userForm').addEventListener('submit', this._handleUserFormSubmit.bind(this));
}
_handleUserAction(event) {
const target = event.target;
const userItem = target.closest('.user-item');
if (!userItem) return;
const userId = userItem.dataset.userId; // Assuming user ID will be stored in data-userId attribute
if (target.classList.contains('button-danger')) {
this._deleteUser(userId);
} else if (target.classList.contains('button')) { // Edit button
this._showUserModal(userId);
}
}
_showUserModal(userId = null) {
const modal = this.querySelector('#userModal');
const form = this.querySelector('#userForm');
form.reset(); // Clear previous form data
if (userId) {
const user = this.users.find(u => u.id == userId);
if (user) {
this.querySelector('#userId').value = user.id;
this.querySelector('#username').value = user.username;
this.querySelector('#email').value = user.email;
this.querySelector('#isSuperuser').checked = user.is_superuser;
this.querySelector('#isActive').checked = user.is_active;
this.querySelector('#is2faEnabled').checked = user.is_2fa_enabled;
this.querySelector('#storageQuotaBytes').value = user.storage_quota_bytes;
this.querySelector('#planType').value = user.plan_type;
this.querySelector('h3').textContent = 'Edit User';
}
} else {
this.querySelector('#userId').value = '';
this.querySelector('h3').textContent = 'Create New User';
}
modal.style.display = 'block';
}
async _handleUserFormSubmit(event) {
event.preventDefault();
const userId = this.querySelector('#userId').value;
const userData = {
username: this.querySelector('#username').value,
email: this.querySelector('#email').value,
password: this.querySelector('#password').value || undefined, // Only send if not empty
is_superuser: this.querySelector('#isSuperuser').checked,
is_active: this.querySelector('#isActive').checked,
is_2fa_enabled: this.querySelector('#is2faEnabled').checked,
storage_quota_bytes: parseInt(this.querySelector('#storageQuotaBytes').value),
plan_type: this.querySelector('#planType').value,
};
try {
if (userId) {
await api.updateUser(userId, userData);
} else {
await api.createUser(userData);
}
this.querySelector('#userModal').style.display = 'none';
await this.loadUsers(); // Refresh the list
} catch (error) {
console.error('Failed to save user:', error);
alert('Failed to save user: ' + error.message);
}
}
async _deleteUser(userId) {
if (!confirm('Are you sure you want to delete this user?')) {
return;
}
try {
await api.deleteUser(userId);
await this.loadUsers(); // Refresh the list
} catch (error) {
console.error('Failed to delete user:', error);
alert('Failed to delete user: ' + error.message);
}
}
renderUser(user) {
const formatBytes = (bytes) => {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};
return `
<div class="user-item" data-user-id="${user.id}">
<span>
${user.username} (${user.email}) - Superuser: ${user.is_superuser ? 'Yes' : 'No'} - 2FA: ${user.is_2fa_enabled ? 'Yes' : 'No'} - Active: ${user.is_active ? 'Yes' : 'No'} - Storage: ${formatBytes(user.storage_quota_bytes)} - Plan: ${user.plan_type}
</span>
<div class="user-actions">
<button class="button button-small">Edit</button>
<button class="button button-small button-danger">Delete</button>
</div>
</div>
`;
}
}
customElements.define('admin-dashboard', AdminDashboard);