role
This commit is contained in:
114
public/js/app.js
114
public/js/app.js
@@ -1586,11 +1586,17 @@ class AccountManager {
|
|||||||
<div class="users-page p-4 md:p-6 w-full h-full flex flex-col overflow-hidden">
|
<div class="users-page p-4 md:p-6 w-full h-full flex flex-col overflow-hidden">
|
||||||
<div class="page-header flex justify-between items-center mb-6 shrink-0">
|
<div class="page-header flex justify-between items-center mb-6 shrink-0">
|
||||||
<h1 class="text-2xl font-bold text-slate-900 dark:text-slate-50">Users Management</h1>
|
<h1 class="text-2xl font-bold text-slate-900 dark:text-slate-50">Users Management</h1>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<button id="addRoleBtn" class="border border-outline-variant/40 hover:bg-slate-100 dark:hover:bg-slate-800 text-slate-700 dark:text-slate-200 font-bold py-2 px-4 rounded-lg transition-all active:scale-95 flex items-center gap-2">
|
||||||
|
<span class="material-symbols-outlined text-base">badge</span>
|
||||||
|
<span>Add Role</span>
|
||||||
|
</button>
|
||||||
<button id="addUserBtn" class="bg-primary hover:bg-primary-dim text-on-primary font-bold py-2 px-4 rounded-lg transition-all active:scale-95 flex items-center gap-2">
|
<button id="addUserBtn" class="bg-primary hover:bg-primary-dim text-on-primary font-bold py-2 px-4 rounded-lg transition-all active:scale-95 flex items-center gap-2">
|
||||||
<span class="material-symbols-outlined text-base">add</span>
|
<span class="material-symbols-outlined text-base">add</span>
|
||||||
<span>Add User</span>
|
<span>Add User</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Search and Filter -->
|
<!-- Search and Filter -->
|
||||||
<div class="users-controls mb-4 flex gap-3 shrink-0">
|
<div class="users-controls mb-4 flex gap-3 shrink-0">
|
||||||
@@ -1716,6 +1722,11 @@ class AccountManager {
|
|||||||
if (addBtn) {
|
if (addBtn) {
|
||||||
addBtn.onclick = () => this.openUserModal();
|
addBtn.onclick = () => this.openUserModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const addRoleBtn = document.getElementById('addRoleBtn');
|
||||||
|
if (addRoleBtn) {
|
||||||
|
addRoleBtn.onclick = () => this.openRoleModal();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getFilteredUsers() {
|
getFilteredUsers() {
|
||||||
@@ -1799,6 +1810,102 @@ class AccountManager {
|
|||||||
this.showUserFormModal(null);
|
this.showUserFormModal(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openRoleModal() {
|
||||||
|
this.showRoleFormModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
showRoleFormModal() {
|
||||||
|
const html = `
|
||||||
|
<div class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 modal-backdrop open" id="roleModal">
|
||||||
|
<div class="bg-white dark:bg-slate-900 rounded-lg p-6 w-full max-w-md modal-content">
|
||||||
|
<h2 class="text-xl font-bold mb-4 text-slate-900 dark:text-slate-50">Add New Role</h2>
|
||||||
|
<form id="roleForm" class="space-y-4">
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1">Role Name</label>
|
||||||
|
<input type="text" id="roleName" placeholder="Manager" class="w-full px-3 py-2 border border-outline-variant/30 rounded-lg bg-surface-container-low dark:bg-slate-800" required>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium mb-1">Description</label>
|
||||||
|
<textarea id="roleDescription" placeholder="Describe this role permissions" class="w-full px-3 py-2 border border-outline-variant/30 rounded-lg bg-surface-container-low dark:bg-slate-800 min-h-[90px]"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-3 pt-2">
|
||||||
|
<button type="button" onclick="closeRoleModal()" class="flex-1 px-4 py-2 bg-outline/10 hover:bg-outline/20 rounded-lg transition-colors">Cancel</button>
|
||||||
|
<button type="submit" class="flex-1 px-4 py-2 bg-primary hover:bg-primary-dim text-on-primary font-bold rounded-lg transition-colors">Save Role</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const editingContainer = document.getElementById('roleModalContainer');
|
||||||
|
if (editingContainer) {
|
||||||
|
editingContainer.innerHTML = html;
|
||||||
|
} else {
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.id = 'roleModalContainer';
|
||||||
|
document.body.appendChild(container);
|
||||||
|
container.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
const form = document.getElementById('roleForm');
|
||||||
|
if (form) {
|
||||||
|
form.addEventListener('submit', (e) => this.saveRole(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
const modal = document.getElementById('roleModal');
|
||||||
|
if (modal) {
|
||||||
|
modal.addEventListener('click', function(e) {
|
||||||
|
if (e.target === this) {
|
||||||
|
closeRoleModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async saveRole(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const roleName = document.getElementById('roleName')?.value.trim();
|
||||||
|
const description = document.getElementById('roleDescription')?.value.trim();
|
||||||
|
|
||||||
|
if (!roleName) {
|
||||||
|
this.notifyFailure('Role name is required');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const roleExists = this.roles.some(role =>
|
||||||
|
String(role.RoleName || '').trim().toLowerCase() === roleName.toLowerCase()
|
||||||
|
);
|
||||||
|
if (roleExists) {
|
||||||
|
this.notifyWarning('Role already exists');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${this.apiBase}/roles`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: this.getAuthHeaders(true),
|
||||||
|
body: JSON.stringify({ roleName, description: description || null })
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
if (!response.ok || !data.success) {
|
||||||
|
this.notifyFailure(data.message || 'Create role failed');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.notifySuccess('Role created');
|
||||||
|
closeRoleModal();
|
||||||
|
await this.fetchRoles();
|
||||||
|
if (this.currentPage === 'users') {
|
||||||
|
this.renderView('users');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
this.notifyFailure('Create role failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
showUserFormModal(userId) {
|
showUserFormModal(userId) {
|
||||||
const user = userId ? this.users.find(u => u.UserId == userId) : null;
|
const user = userId ? this.users.find(u => u.UserId == userId) : null;
|
||||||
|
|
||||||
@@ -2178,6 +2285,13 @@ function closeUserModal() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function closeRoleModal() {
|
||||||
|
const roleModalContainer = document.getElementById('roleModalContainer');
|
||||||
|
if (roleModalContainer) {
|
||||||
|
roleModalContainer.innerHTML = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function closeUserDetailsModal() {
|
function closeUserDetailsModal() {
|
||||||
const detailsContainer = document.getElementById('userDetailsModalContainer');
|
const detailsContainer = document.getElementById('userDetailsModalContainer');
|
||||||
if (detailsContainer) {
|
if (detailsContainer) {
|
||||||
|
|||||||
Reference in New Issue
Block a user