registerPage('users', async (content, params = {}) => {
document.getElementById('topbar-title').textContent = 'Users';
let userTypes = [], clients = [];
async function preload() {
const [tr, cr] = await Promise.all([
api('users.php', { action: 'user_types' }),
api('clients.php', { action: 'list' }),
]);
userTypes = tr.user_types || [];
clients = cr.clients || [];
}
async function render(search = '') {
const r = await api('users.php', { action: 'list', search });
if (!r.success) { document.getElementById('users-table').innerHTML = emptyHTML(); return; }
const rows = r.users;
document.getElementById('users-table').innerHTML = rows.length === 0 ? emptyHTML('No users found') : `
| Username | Full Name | Email | Type | Assessor # | Clients | Actions |
${rows.map(u => `
| ${u.safesure_users_name} |
${u.name || '—'} |
${u.email || '—'} |
${typeBadge(u.user_type_name)} |
${u.assessor_number || '—'} |
${u.clients_multi || '—'} |
|
`).join('')}
`;
}
content.innerHTML = `
`;
await preload();
const typeSel = document.getElementById('uf-type');
userTypes.forEach(t => typeSel.innerHTML += ``);
function renderClientCheckboxes(selectedIds = []) {
const selected = typeof selectedIds === 'string' ? selectedIds.split(',').map(s => s.trim()) : selectedIds;
document.getElementById('uf-clients').innerHTML = clients.map(c => `
`).join('');
}
window.syncClientHidden = () => {
const checked = [...document.querySelectorAll('#uf-clients input:checked')].map(c => c.value);
document.getElementById('uf-clients-hidden').value = checked.join(',');
};
document.getElementById('user-search').addEventListener('input', e => render(e.target.value));
render();
window.userAdd = () => {
document.getElementById('user-modal-title').textContent = 'New User';
document.getElementById('uf-id').value = '';
document.getElementById('uf-username').value = '';
document.getElementById('uf-name').value = '';
document.getElementById('uf-email').value = '';
document.getElementById('uf-password').value = '';
document.getElementById('uf-assessor').value = '';
document.getElementById('uf-moderator').value = '';
document.getElementById('uf-type').value = '2';
document.getElementById('pw-hint').textContent = '(required)';
renderClientCheckboxes([]);
openModal('user-modal');
};
window.userEdit = async (id) => {
const r = await api('users.php', { action: 'get', id });
if (!r.success) { toast('Failed', 'error'); return; }
const u = r.user;
document.getElementById('user-modal-title').textContent = 'Edit User';
document.getElementById('uf-id').value = u.record_id;
document.getElementById('uf-username').value = u.safesure_users_name;
document.getElementById('uf-name').value = u.name || '';
document.getElementById('uf-email').value = u.email || '';
document.getElementById('uf-password').value = '';
document.getElementById('uf-assessor').value = u.assessor_number || '';
document.getElementById('uf-moderator').value = u.moderator_number || '';
document.getElementById('uf-type').value = u.user_type_id;
document.getElementById('pw-hint').textContent = '(leave blank to keep)';
renderClientCheckboxes(u.clients_multi || '');
syncClientHidden();
openModal('user-modal');
};
window.userSave = async () => {
const id = document.getElementById('uf-id').value;
syncClientHidden();
const params = {
action: id ? 'update' : 'create', id,
safesure_users_name: document.getElementById('uf-username').value,
name: document.getElementById('uf-name').value,
email: document.getElementById('uf-email').value,
password: document.getElementById('uf-password').value,
user_type_id: document.getElementById('uf-type').value,
assessor_number: document.getElementById('uf-assessor').value,
moderator_number: document.getElementById('uf-moderator').value,
clients_multi: document.getElementById('uf-clients-hidden').value,
};
const r = await api('users.php', params, 'POST');
if (r.success) { toast(r.message, 'success'); closeModal('user-modal'); render(); }
else toast(r.error, 'error');
};
window.userDelete = async (id) => {
if (!confirm('Delete this user? Their active session token will also be revoked.')) return;
const r = await api('users.php', { action: 'delete', id }, 'POST');
if (r.success) { toast('User deleted', 'success'); render(); }
else toast(r.error, 'error');
};
});