// User Management JavaScript
let usersData = [];
let userModal;
let passwordModal;
const rolePermissions = {
Cashier: ["View Products", "Process Orders", "View Customers"],
Accountant: [
"View Products",
"View Orders",
"View Reports",
"View Financial Data",
],
Admin: [
"Manage Products",
"Manage Portfolio",
"Manage Blog",
"Manage Pages",
"Manage Users",
"View Reports",
],
MasterAdmin: [
"Full System Access",
"Manage Settings",
"Manage Users",
"Manage All Content",
"View Logs",
"System Configuration",
],
};
document.addEventListener("DOMContentLoaded", function () {
userModal = new bootstrap.Modal(document.getElementById("userModal"));
passwordModal = new bootstrap.Modal(document.getElementById("passwordModal"));
checkAuth().then((authenticated) => {
if (authenticated) {
loadUsers();
}
});
});
async function loadUsers() {
try {
const response = await fetch("/api/admin/users", {
credentials: "include",
});
const data = await response.json();
if (data.success) {
usersData = data.users;
renderUsers(usersData);
}
} catch (error) {
console.error("Failed to load users:", error);
}
}
function renderUsers(users) {
const tbody = document.getElementById("usersTableBody");
if (users.length === 0) {
tbody.innerHTML = `
|
No users found
|
`;
return;
}
tbody.innerHTML = users
.map(
(u) => `
| ${u.id} |
${escapeHtml(u.name)} |
${escapeHtml(u.email)} |
@${escapeHtml(u.username)} |
${u.role} |
${u.isactive ? "Active" : "Disabled"} |
${formatDate(u.createdat)} |
|
`
)
.join("");
}
function filterUsers() {
const searchTerm = document.getElementById("searchInput").value.toLowerCase();
const filtered = usersData.filter(
(u) =>
u.name.toLowerCase().includes(searchTerm) ||
u.email.toLowerCase().includes(searchTerm) ||
u.username.toLowerCase().includes(searchTerm)
);
renderUsers(filtered);
}
function showCreateUser() {
document.getElementById("modalTitle").textContent = "Create New User";
document.getElementById("userForm").reset();
document.getElementById("userId").value = "";
document.getElementById("userActive").checked = true;
document.getElementById("userPasswordNeverExpires").checked = false;
document.getElementById("userRole").value = "Cashier";
updatePermissionsPreview();
userModal.show();
}
async function editUser(id) {
try {
const response = await fetch(`/api/admin/users/${id}`, {
credentials: "include",
});
const data = await response.json();
if (data.success) {
const user = data.user;
document.getElementById("modalTitle").textContent = "Edit User";
document.getElementById("userId").value = user.id;
document.getElementById("userName").value = user.name;
document.getElementById("userUsername").value = user.username;
document.getElementById("userEmail").value = user.email;
document.getElementById("userPassword").value = "";
document.getElementById("userPasswordConfirm").value = "";
document.getElementById("userRole").value = user.role;
document.getElementById("userActive").checked = user.isactive;
document.getElementById("userPasswordNeverExpires").checked =
user.passwordneverexpires || false;
updatePermissionsPreview();
userModal.show();
}
} catch (error) {
console.error("Failed to load user:", error);
showError("Failed to load user details");
}
}
async function saveUser() {
const id = document.getElementById("userId").value;
const password = document.getElementById("userPassword").value;
const passwordConfirm = document.getElementById("userPasswordConfirm").value;
// Password validation (only for new users or when changing password)
if (!id || password) {
if (!password) {
showError("Password is required for new users");
return;
}
if (password !== passwordConfirm) {
showError("Passwords do not match");
return;
}
if (password.length < 8) {
showError("Password must be at least 8 characters long");
return;
}
}
const formData = {
name: document.getElementById("userName").value,
username: document.getElementById("userUsername").value,
email: document.getElementById("userEmail").value,
role: document.getElementById("userRole").value,
isactive: document.getElementById("userActive").checked,
passwordneverexpires: document.getElementById("userPasswordNeverExpires")
.checked,
};
if (password) {
formData.password = password;
}
if (!formData.name || !formData.username || !formData.email) {
showError("Please fill in all required fields");
return;
}
showLoading(id ? "Updating user..." : "Creating user...");
try {
const url = id ? `/api/admin/users/${id}` : "/api/admin/users";
const method = id ? "PUT" : "POST";
const response = await fetch(url, {
method: method,
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify(formData),
});
const data = await response.json();
hideLoading();
if (data.success) {
showSuccess(
id ? "User updated successfully" : "User created successfully"
);
userModal.hide();
loadUsers();
} else {
showError(data.message || "Failed to save user");
}
} catch (error) {
console.error("Failed to save user:", error);
hideLoading();
showError("Failed to save user");
}
}
function showChangePassword(id, name) {
document.getElementById("passwordUserId").value = id;
document.getElementById("passwordUserName").value = name;
document.getElementById("passwordUserDisplay").textContent = name;
document.getElementById("passwordForm").reset();
passwordModal.show();
}
async function changePassword() {
const id = document.getElementById("passwordUserId").value;
const newPassword = document.getElementById("newPassword").value;
const confirmPassword = document.getElementById("confirmNewPassword").value;
if (!newPassword || !confirmPassword) {
showError("Please enter and confirm the new password");
return;
}
if (newPassword !== confirmPassword) {
showError("Passwords do not match");
return;
}
if (newPassword.length < 8) {
showError("Password must be at least 8 characters long");
return;
}
showLoading("Changing password...");
try {
const response = await fetch(`/api/admin/users/${id}/password`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({ password: newPassword }),
});
const data = await response.json();
hideLoading();
if (data.success) {
showSuccess("Password changed successfully");
passwordModal.hide();
} else {
showError(data.message || "Failed to change password");
}
} catch (error) {
console.error("Failed to change password:", error);
hideLoading();
showError("Failed to change password");
}
}
async function deleteUser(id, name) {
if (
!confirm(
`Are you sure you want to delete user "${name}"? This action cannot be undone.`
)
)
return;
showLoading("Deleting user...");
try {
const response = await fetch(`/api/admin/users/${id}`, {
method: "DELETE",
credentials: "include",
});
const data = await response.json();
hideLoading();
if (data.success) {
showSuccess("User deleted successfully");
loadUsers();
} else {
showError(data.message || "Failed to delete user");
}
} catch (error) {
console.error("Failed to delete user:", error);
hideLoading();
showError("Failed to delete user");
}
}
function updatePermissionsPreview() {
const role = document.getElementById("userRole").value;
const permissions = rolePermissions[role] || [];
const container = document.getElementById("permissionsPreview");
container.innerHTML = permissions
.map(
(perm) => `
${perm}
`
)
.join("");
}
function escapeHtml(text) {
const map = {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'",
};
return text.replace(/[&<>"']/g, (m) => map[m]);
}
function formatDate(dateString) {
return new Date(dateString).toLocaleDateString("en-US", {
year: "numeric",
month: "short",
day: "numeric",
});
}
// Custom notification system
function showNotification(type, title, message) {
const container = document.getElementById("notificationContainer");
const notification = document.createElement("div");
notification.className = `notification notification-${type}`;
const icon =
type === "success"
? ''
: '';
notification.innerHTML = `
${icon}
`;
container.appendChild(notification);
// Auto remove after 3 seconds
setTimeout(() => {
if (notification.parentElement) {
notification.classList.add("removing");
setTimeout(() => {
if (notification.parentElement) {
notification.remove();
}
}, 300);
}
}, 3000);
}
function closeNotification(button) {
const notification = button.closest(".notification");
notification.classList.add("removing");
setTimeout(() => {
notification.remove();
}, 300);
}
function showSuccess(message) {
showNotification("success", "Success!", message);
}
function showError(message) {
showNotification("error", "Error", message);
}
// Loading overlay functions
function showLoading(message = "Saving...") {
const overlay = document.createElement("div");
overlay.className = "loading-overlay";
overlay.id = "loadingOverlay";
overlay.innerHTML = `
`;
document.body.appendChild(overlay);
}
function hideLoading() {
const overlay = document.getElementById("loadingOverlay");
if (overlay) {
overlay.remove();
}
}