Sửa lỗi quản lí users, chỉnh sửa users
This commit is contained in:
+177
-13
@@ -277,13 +277,13 @@ function checkAuthStatus() {
|
||||
const avatarInitials = document.getElementById('avatar-initials');
|
||||
|
||||
if (token && username) {
|
||||
authGuest.style.display = 'none'; // Hide login form
|
||||
if (authGuest) authGuest.style.display = 'none'; // Hide login form
|
||||
authLoggedIn.style.display = 'block'; // Show welcome message and buttons
|
||||
avatarInitials.innerText = username.charAt(0).toUpperCase();
|
||||
|
||||
// Chỉ hiển thị các NÚT BẤM menu admin trong sidebar
|
||||
// Hiển thị các nút dành cho admin (Chủ sở hữu/Admin tối cao)
|
||||
const adminButtons = document.querySelectorAll('.dashboard-tabs .admin-only');
|
||||
if (role === 'Chủ sở hữu' || role === 'admin') {
|
||||
if (role === 'admin' || role === 'Chủ sở hữu') {
|
||||
adminButtons.forEach(btn => btn.style.display = 'block');
|
||||
} else {
|
||||
adminButtons.forEach(btn => btn.style.display = 'none');
|
||||
@@ -344,15 +344,66 @@ async function handleLogin() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Chuyển đổi giữa chế độ Đăng nhập và Đăng ký trong dropdown
|
||||
*/
|
||||
window.switchAuthMode = function(mode) {
|
||||
const loginSection = document.getElementById('login-section');
|
||||
const registerSection = document.getElementById('register-section');
|
||||
const loginBtn = document.getElementById('tab-login-btn');
|
||||
const registerBtn = document.getElementById('tab-register-btn');
|
||||
|
||||
if (mode === 'login') {
|
||||
loginSection.style.display = 'block';
|
||||
registerSection.style.display = 'none';
|
||||
loginBtn.classList.add('active');
|
||||
registerBtn.classList.remove('active');
|
||||
} else {
|
||||
loginSection.style.display = 'none';
|
||||
registerSection.style.display = 'block';
|
||||
loginBtn.classList.remove('active');
|
||||
registerBtn.classList.add('active');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles user registration
|
||||
*/
|
||||
async function handleRegister() {
|
||||
const username = document.getElementById('username-input').value.trim();
|
||||
const password = document.getElementById('password-input').value.trim();
|
||||
const errorMsg = document.getElementById('reg-error-msg');
|
||||
if (errorMsg) errorMsg.style.display = 'none';
|
||||
|
||||
if (!username || !password) {
|
||||
alert('Please fill in both fields');
|
||||
const fullName = document.getElementById('reg-fullname').value.trim();
|
||||
const email = document.getElementById('reg-email').value.trim();
|
||||
const username = document.getElementById('reg-username').value.trim();
|
||||
const password = document.getElementById('reg-password').value;
|
||||
const confirm = document.getElementById('reg-confirm').value;
|
||||
const agree = document.getElementById('reg-agree').checked;
|
||||
|
||||
// Kiểm tra các trường trống
|
||||
if (!fullName || !email || !username || !password || !confirm) {
|
||||
if (errorMsg) {
|
||||
errorMsg.innerText = 'Vui lòng điền đầy đủ thông tin';
|
||||
errorMsg.style.display = 'block';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Kiểm tra mật khẩu khớp nhau
|
||||
if (password !== confirm) {
|
||||
if (errorMsg) {
|
||||
errorMsg.innerText = 'Mật khẩu xác nhận không khớp';
|
||||
errorMsg.style.display = 'block';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Kiểm tra đồng ý quy định
|
||||
if (!agree) {
|
||||
if (errorMsg) {
|
||||
errorMsg.innerText = 'Bạn phải đồng ý với quy định của trang';
|
||||
errorMsg.style.display = 'block';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -360,15 +411,26 @@ async function handleRegister() {
|
||||
const response = await fetch(`${API_BASE_URL}/auth/register`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username, password, role: 'Thành viên' })
|
||||
body: JSON.stringify({
|
||||
fullName,
|
||||
email,
|
||||
username,
|
||||
password,
|
||||
agreedToRules: agree,
|
||||
role: 'Thành viên'
|
||||
})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
if (!response.ok) throw new Error(data.message || 'Registration failed');
|
||||
if (!response.ok) throw new Error(data.message || 'Đăng ký thất bại');
|
||||
|
||||
showNotification('Registration successful! You can now log in.', 'success');
|
||||
showNotification('Đăng ký thành công! Bạn có thể đăng nhập ngay bây giờ.', 'success');
|
||||
switchAuthMode('login'); // Tự động chuyển về tab đăng nhập sau khi thành công
|
||||
} catch (error) {
|
||||
showNotification(error.message, 'error');
|
||||
if (errorMsg) {
|
||||
errorMsg.innerText = error.message;
|
||||
errorMsg.style.display = 'block';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,7 +716,7 @@ async function loadScenes() {
|
||||
const ownerId = scene.createdBy?._id || scene.createdBy || scene.owner?._id || scene.owner;
|
||||
|
||||
// Phân quyền: Admin hoặc Chủ sở hữu Scene
|
||||
const isAdmin = userRole === 'Chủ sở hữu' || userRole === 'admin';
|
||||
const isAdmin = userRole === 'admin' || userRole === 'Chủ sở hữu';
|
||||
if (isAdmin || (currentUserId && ownerId && ownerId.toString() === currentUserId.toString())) {
|
||||
handleEditDeleteScene(scene);
|
||||
} else {
|
||||
@@ -1312,6 +1374,105 @@ async function loadMyScenes() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tải danh sách người dùng dành cho Admin tối cao
|
||||
*/
|
||||
async function loadAdminUsers() {
|
||||
const token = localStorage.getItem('jwt');
|
||||
const container = document.getElementById('admin-users-list');
|
||||
if (!container) return;
|
||||
|
||||
container.innerHTML = '<p>Đang tải danh sách người dùng...</p>';
|
||||
|
||||
try {
|
||||
const res = await fetch(`${API_BASE_URL}/admin/users`, {
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
});
|
||||
const users = await res.json();
|
||||
if (!res.ok) throw new Error(users.message);
|
||||
|
||||
let html = `
|
||||
<table class="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Họ tên</th>
|
||||
<th>Username</th>
|
||||
<th>Email</th>
|
||||
<th>Quyền hạn</th>
|
||||
<th>Reset Password</th>
|
||||
<th>Thao tác</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
`;
|
||||
|
||||
users.forEach(user => {
|
||||
html += `
|
||||
<tr>
|
||||
<td><input type="text" id="adm-fn-${user._id}" value="${user.fullName || ''}"></td>
|
||||
<td><strong>${user.username}</strong></td>
|
||||
<td><input type="email" id="adm-em-${user._id}" value="${user.email || ''}"></td>
|
||||
<td>
|
||||
<select id="adm-role-${user._id}">
|
||||
<option value="user" ${user.role === 'user' ? 'selected' : ''}>User</option>
|
||||
<option value="editor" ${user.role === 'editor' ? 'selected' : ''}>Editor</option>
|
||||
<option value="moderator" ${user.role === 'moderator' ? 'selected' : ''}>Moderator</option>
|
||||
<option value="admin" ${user.role === 'admin' ? 'selected' : ''}>Admin</option>
|
||||
</select>
|
||||
</td>
|
||||
<td><input type="password" id="adm-pw-${user._id}" placeholder="Mật khẩu mới"></td>
|
||||
<td>
|
||||
<button class="edit-btn-small" onclick="updateUserByAdmin('${user._id}')">Lưu</button>
|
||||
<button class="delete-btn-small" onclick="deleteUserByAdmin('${user._id}')">Xóa</button>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
|
||||
html += '</tbody></table>';
|
||||
container.innerHTML = html;
|
||||
} catch (e) {
|
||||
container.innerHTML = `<p style="color:red">Lỗi: ${e.message}</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
window.updateUserByAdmin = async function(userId) {
|
||||
const token = localStorage.getItem('jwt');
|
||||
const payload = {
|
||||
fullName: document.getElementById(`adm-fn-${userId}`).value,
|
||||
email: document.getElementById(`adm-em-${userId}`).value,
|
||||
role: document.getElementById(`adm-role-${userId}`).value,
|
||||
password: document.getElementById(`adm-pw-${userId}`).value
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await fetch(`${API_BASE_URL}/admin/users/${userId}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
const data = await res.json();
|
||||
if (!res.ok) throw new Error(data.message);
|
||||
showNotification(data.message, 'success');
|
||||
loadAdminUsers();
|
||||
} catch (e) { showNotification(e.message, 'error'); }
|
||||
};
|
||||
|
||||
window.deleteUserByAdmin = async function(userId) {
|
||||
if (!confirm('Xóa vĩnh viễn người dùng này?')) return;
|
||||
const token = localStorage.getItem('jwt');
|
||||
try {
|
||||
const res = await fetch(`${API_BASE_URL}/admin/users/${userId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
});
|
||||
const data = await res.json();
|
||||
if (!res.ok) throw new Error(data.message);
|
||||
showNotification(data.message, 'success');
|
||||
loadAdminUsers();
|
||||
} catch (e) { showNotification(e.message, 'error'); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Tải và hiển thị kho ảnh/media của người dùng
|
||||
*/
|
||||
@@ -1373,7 +1534,7 @@ async function loadMyAssets() {
|
||||
}
|
||||
|
||||
// Add delete button and its event listener
|
||||
if (asset.uploadedBy === currentUserId || (isTrash && userRole === 'Chủ sở hữu')) {
|
||||
if (asset.uploadedBy === currentUserId || (isTrash && (userRole === 'admin' || userRole === 'Chủ sở hữu'))) {
|
||||
const deleteButton = document.createElement('button');
|
||||
deleteButton.className = 'delete-btn-small';
|
||||
deleteButton.innerText = 'Xóa';
|
||||
@@ -1764,6 +1925,9 @@ function openDashboardTab(tabName) {
|
||||
if (tabName === 'media-library') {
|
||||
loadMyAssets();
|
||||
}
|
||||
if (tabName === 'user-management') {
|
||||
loadAdminUsers();
|
||||
}
|
||||
}
|
||||
|
||||
// Đánh dấu nút tab được chọn là active
|
||||
|
||||
@@ -166,7 +166,7 @@ function applyViewerSecurity() {
|
||||
const currentUserId = localStorage.getItem('userId');
|
||||
|
||||
// Phân quyền: Admin (Chủ sở hữu) hoặc Người tạo ra Scene này
|
||||
const isAdmin = userRole === 'Chủ sở hữu' || userRole === 'admin';
|
||||
const isAdmin = userRole === 'admin' || userRole === 'Chủ sở hữu';
|
||||
const isAuthorized = isAdmin ||
|
||||
(currentUserId && currentSceneOwnerId && currentUserId.toString() === currentSceneOwnerId.toString());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user