AWS Route53 Settings
Configure AWS credentials and hosted zones for PTR record management.
Enter the hosted zone IDs for your forward DNS zones (A records)
| ${escapeHtml(user.email)} |
${user.display_name ? escapeHtml(user.display_name) : '-'} |
${user.role === 'admin' ? 'Admin' : 'Staff'}
|
${user.active == 1 ? 'Active' : 'Inactive'}
|
${formatDate(user.created_at)} |
|
`).join('');
} catch (error) {
console.error('Error loading users:', error);
showNotification('Failed to load users: ' + error.message, 'error');
}
}
async function addUser() {
const email = document.getElementById('newUserEmail').value.trim();
const displayName = document.getElementById('newUserDisplayName').value.trim();
const role = document.getElementById('newUserRole').value;
if (!email) {
showNotification('Please enter an email address', 'error');
return;
}
try {
const response = await fetch('api.php?action=admin_user_save', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': CSRF_TOKEN
},
body: JSON.stringify({
email: email,
display_name: displayName || null,
role: role
})
});
const data = await response.json();
if (!data.success) {
throw new Error(data.error || 'Failed to add user');
}
showNotification('User added successfully', 'success');
document.getElementById('newUserEmail').value = '';
document.getElementById('newUserDisplayName').value = '';
document.getElementById('newUserRole').value = 'staff';
loadUsers();
} catch (error) {
console.error('Error adding user:', error);
showNotification('Failed to add user: ' + error.message, 'error');
}
}
async function toggleUser(userId) {
try {
const response = await fetch('api.php?action=admin_user_toggle', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': CSRF_TOKEN
},
body: JSON.stringify({ id: userId })
});
const data = await response.json();
if (!data.success) {
throw new Error(data.error || 'Failed to toggle user status');
}
showNotification('User status updated', 'success');
loadUsers();
} catch (error) {
console.error('Error toggling user:', error);
showNotification('Failed to toggle user: ' + error.message, 'error');
}
}
async function deleteUser(userId, email) {
if (!confirm(`Are you sure you want to delete the user "${email}"? This action cannot be undone.`)) {
return;
}
try {
const response = await fetch('api.php?action=admin_user_delete', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': CSRF_TOKEN
},
body: JSON.stringify({ id: userId })
});
const data = await response.json();
if (!data.success) {
throw new Error(data.error || 'Failed to delete user');
}
showNotification('User deleted successfully', 'success');
loadUsers();
} catch (error) {
console.error('Error deleting user:', error);
showNotification('Failed to delete user: ' + error.message, 'error');
}
}
function escapeHtml(text) {
if (!text) return '';
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function formatDate(dateStr) {
if (!dateStr) return '-';
const date = new Date(dateStr);
return date.toLocaleDateString('en-GB', {
day: '2-digit',
month: 'short',
year: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
}