384 lines
15 KiB
JavaScript
384 lines
15 KiB
JavaScript
// --- Fitur Autentikasi dan Manajemen User (RBAC) ---
|
|
|
|
(function() {
|
|
window.currentUser = null;
|
|
|
|
// Elements
|
|
const authWidget = document.getElementById('authWidget');
|
|
const loginModal = document.getElementById('loginModal');
|
|
const loginUsernameInput = document.getElementById('loginUsername');
|
|
const loginPasswordInput = document.getElementById('loginPassword');
|
|
const loginSubmitBtn = document.getElementById('loginSubmitBtn');
|
|
const loginErrorMsg = document.getElementById('loginErrorMsg');
|
|
const closeLoginModal = document.getElementById('closeLoginModal');
|
|
|
|
// User Management Modal Elements
|
|
const userManagementModal = document.getElementById('userManagementModal');
|
|
const closeUserManagementModal = document.getElementById('closeUserManagementModal');
|
|
const menuUsersBtn = document.getElementById('menuUsers');
|
|
const userTableBody = document.getElementById('userTableBody');
|
|
const btnSaveUser = document.getElementById('btnSaveUser');
|
|
const btnCancelUserEdit = document.getElementById('btnCancelUserEdit');
|
|
const userFormTitle = document.getElementById('userFormTitle');
|
|
|
|
const manageUserId = document.getElementById('manageUserId');
|
|
const manageUsername = document.getElementById('manageUsername');
|
|
const managePassword = document.getElementById('managePassword');
|
|
const manageRole = document.getElementById('manageRole');
|
|
const manageIbadahId = document.getElementById('manageIbadahId');
|
|
const manageIbadahGroup = document.getElementById('manageIbadahGroup');
|
|
|
|
// Startup Session Check
|
|
function checkSession() {
|
|
fetch('api/check_session.php')
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
if (data.status === 'success' && data.isLoggedIn) {
|
|
window.currentUser = data.data;
|
|
} else {
|
|
window.currentUser = null;
|
|
}
|
|
updateAuthUI();
|
|
refreshAllLayers();
|
|
})
|
|
.catch(err => {
|
|
console.error("Session check failed:", err);
|
|
window.currentUser = null;
|
|
updateAuthUI();
|
|
});
|
|
}
|
|
|
|
// Update UI based on logged-in state
|
|
function updateAuthUI() {
|
|
if (!authWidget) return;
|
|
|
|
const dashboardBtn = document.getElementById('menuDashboard');
|
|
|
|
if (window.currentUser) {
|
|
// Logged In state
|
|
const roleLabel = window.currentUser.role === 'admin' ? 'Admin' : 'Pengelola';
|
|
const extraLabel = window.currentUser.nama_ibadah ? ` - ${window.currentUser.nama_ibadah}` : '';
|
|
|
|
authWidget.innerHTML = `
|
|
<div class="user-profile-pill">
|
|
<div class="user-profile-info">
|
|
<div class="user-profile-name">👤 ${escHtml(window.currentUser.username)}</div>
|
|
<div class="user-profile-role">${roleLabel}${escHtml(extraLabel)}</div>
|
|
</div>
|
|
<button class="btn-profile-logout" id="authLogoutBtn" title="Logout">
|
|
<i class="fas fa-sign-out-alt"></i>
|
|
</button>
|
|
</div>
|
|
`;
|
|
|
|
document.getElementById('authLogoutBtn').addEventListener('click', logout);
|
|
|
|
// Show Dashboard button for all logged-in users
|
|
if (dashboardBtn) dashboardBtn.style.display = 'flex';
|
|
|
|
// Show user management button in sidebar for Admin
|
|
const adminDivider = document.getElementById('sidebarAdminDivider');
|
|
if (window.currentUser.role === 'admin') {
|
|
if (menuUsersBtn) menuUsersBtn.style.display = 'flex';
|
|
if (adminDivider) adminDivider.style.display = 'block';
|
|
} else {
|
|
if (menuUsersBtn) menuUsersBtn.style.display = 'none';
|
|
if (adminDivider) adminDivider.style.display = 'none';
|
|
}
|
|
} else {
|
|
// Logged Out state
|
|
authWidget.innerHTML = `
|
|
<button class="btn-login" id="authLoginBtn"><i class="fas fa-sign-in-alt"></i> Login</button>
|
|
`;
|
|
document.getElementById('authLoginBtn').addEventListener('click', showLoginModal);
|
|
if (menuUsersBtn) menuUsersBtn.style.display = 'none';
|
|
if (dashboardBtn) dashboardBtn.style.display = 'none';
|
|
const adminDivider = document.getElementById('sidebarAdminDivider');
|
|
if (adminDivider) adminDivider.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function refreshAllLayers() {
|
|
if (typeof loadSpbu === 'function') loadSpbu();
|
|
if (typeof loadJalan === 'function') loadJalan();
|
|
if (typeof loadParsil === 'function') loadParsil();
|
|
if (typeof loadRumahIbadah === 'function') loadRumahIbadah();
|
|
if (typeof loadPendudukMiskin === 'function') loadPendudukMiskin();
|
|
if (window.refreshActivePanel) window.refreshActivePanel();
|
|
}
|
|
|
|
// Login Modals logic
|
|
function showLoginModal() {
|
|
loginUsernameInput.value = '';
|
|
loginPasswordInput.value = '';
|
|
loginErrorMsg.style.display = 'none';
|
|
loginModal.classList.add('show');
|
|
}
|
|
|
|
function hideLoginModal() {
|
|
loginModal.classList.remove('show');
|
|
}
|
|
|
|
if (closeLoginModal) {
|
|
closeLoginModal.addEventListener('click', hideLoginModal);
|
|
}
|
|
|
|
loginSubmitBtn.addEventListener('click', function() {
|
|
const username = loginUsernameInput.value.trim();
|
|
const password = loginPasswordInput.value;
|
|
|
|
if (!username || !password) {
|
|
loginErrorMsg.textContent = 'Username dan password wajib diisi';
|
|
loginErrorMsg.style.display = 'block';
|
|
return;
|
|
}
|
|
|
|
fetch('api/login.php', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ username, password })
|
|
})
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
if (data.status === 'success') {
|
|
window.currentUser = data.data;
|
|
hideLoginModal();
|
|
updateAuthUI();
|
|
refreshAllLayers();
|
|
showToast('Login berhasil', 'success');
|
|
} else {
|
|
loginErrorMsg.textContent = data.message || 'Login gagal';
|
|
loginErrorMsg.style.display = 'block';
|
|
}
|
|
})
|
|
.catch(err => {
|
|
console.error(err);
|
|
loginErrorMsg.textContent = 'Koneksi ke server terputus';
|
|
loginErrorMsg.style.display = 'block';
|
|
});
|
|
});
|
|
|
|
function logout() {
|
|
fetch('api/logout.php')
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
window.currentUser = null;
|
|
updateAuthUI();
|
|
refreshAllLayers();
|
|
showToast('Logout berhasil', 'success');
|
|
})
|
|
.catch(err => {
|
|
console.error(err);
|
|
showToast('Gagal logout', 'error');
|
|
});
|
|
}
|
|
|
|
// User Management Modal Logic
|
|
if (menuUsersBtn) {
|
|
menuUsersBtn.addEventListener('click', function() {
|
|
userManagementModal.classList.add('show');
|
|
loadUsers();
|
|
populateIbadahDropdown();
|
|
resetUserForm();
|
|
});
|
|
}
|
|
|
|
// Dashboard Button
|
|
const menuDashboardBtn = document.getElementById('menuDashboard');
|
|
if (menuDashboardBtn) {
|
|
menuDashboardBtn.addEventListener('click', function() {
|
|
if (typeof window.openDashboard === 'function') window.openDashboard();
|
|
});
|
|
}
|
|
|
|
if (closeUserManagementModal) {
|
|
closeUserManagementModal.addEventListener('click', function() {
|
|
userManagementModal.classList.remove('show');
|
|
});
|
|
}
|
|
|
|
// Show/hide ibadah dropdown based on selected role in form
|
|
if (manageRole) {
|
|
manageRole.addEventListener('change', function() {
|
|
if (this.value === 'admin') {
|
|
manageIbadahGroup.style.display = 'none';
|
|
manageIbadahId.value = '';
|
|
} else {
|
|
manageIbadahGroup.style.display = 'flex';
|
|
}
|
|
});
|
|
}
|
|
|
|
function populateIbadahDropdown() {
|
|
if (!manageIbadahId) return;
|
|
manageIbadahId.innerHTML = '<option value="">-- Pilih Rumah Ibadah --</option>';
|
|
if (typeof ibadahDataList !== 'undefined') {
|
|
ibadahDataList.forEach(ib => {
|
|
const opt = document.createElement('option');
|
|
opt.value = ib.id;
|
|
opt.textContent = `${ib.jenis || '🕌'} ${ib.nama}`;
|
|
manageIbadahId.appendChild(opt);
|
|
});
|
|
}
|
|
}
|
|
|
|
function loadUsers() {
|
|
if (!userTableBody) return;
|
|
userTableBody.innerHTML = '<tr><td colspan="4" style="text-align:center; padding:15px; color:#aaa;">Memuat user...</td></tr>';
|
|
|
|
fetch('api/users/read.php')
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
if (data.status === 'success') {
|
|
userTableBody.innerHTML = '';
|
|
if (data.data.length === 0) {
|
|
userTableBody.innerHTML = '<tr><td colspan="4" style="text-align:center; padding:15px; color:#aaa;">Belum ada user</td></tr>';
|
|
return;
|
|
}
|
|
data.data.forEach(user => {
|
|
const tr = document.createElement('tr');
|
|
tr.style.borderBottom = '1px solid #e2e8f0';
|
|
|
|
const roleBadge = user.role === 'admin'
|
|
? '<span class="data-card-badge badge-red">Admin</span>'
|
|
: '<span class="data-card-badge badge-blue">Pengelola</span>';
|
|
|
|
tr.innerHTML = `
|
|
<td style="padding:10px 12px; font-weight:600;">${escHtml(user.username)}</td>
|
|
<td style="padding:10px 12px;">${roleBadge}</td>
|
|
<td style="padding:10px 12px; color:#64748b;">${escHtml(user.nama_ibadah)}</td>
|
|
<td style="padding:10px 12px; text-align:center; display:flex; gap:6px; justify-content:center;">
|
|
<button class="btn-card-action btn-card-edit" title="Edit User" onclick="editUser(${JSON.stringify(user).replace(/"/g, '"')})">
|
|
<i class="fas fa-pen"></i>
|
|
</button>
|
|
<button class="btn-card-action btn-card-delete" title="Hapus User" onclick="deleteUser(${user.id})">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</td>
|
|
`;
|
|
userTableBody.appendChild(tr);
|
|
});
|
|
}
|
|
})
|
|
.catch(err => {
|
|
userTableBody.innerHTML = '<tr><td colspan="4" style="text-align:center; padding:15px; color:#ef4444;">Gagal memuat user</td></tr>';
|
|
});
|
|
}
|
|
|
|
window.editUser = function(user) {
|
|
userFormTitle.textContent = 'Edit Pengguna';
|
|
manageUserId.value = user.id;
|
|
manageUsername.value = user.username;
|
|
managePassword.value = ''; // Password cleared in edit
|
|
manageRole.value = user.role;
|
|
|
|
if (user.role === 'admin') {
|
|
manageIbadahGroup.style.display = 'none';
|
|
manageIbadahId.value = '';
|
|
} else {
|
|
manageIbadahGroup.style.display = 'flex';
|
|
manageIbadahId.value = user.ibadah_id || '';
|
|
}
|
|
|
|
btnCancelUserEdit.style.display = 'inline-block';
|
|
};
|
|
|
|
window.deleteUser = function(id) {
|
|
if (confirm('Apakah Anda yakin ingin menghapus user ini?')) {
|
|
fetch('api/users/delete.php', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ id })
|
|
})
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
if (data.status === 'success') {
|
|
showToast(data.message, 'success');
|
|
loadUsers();
|
|
resetUserForm();
|
|
} else {
|
|
showToast(data.message || 'Gagal menghapus user', 'error');
|
|
}
|
|
})
|
|
.catch(err => {
|
|
showToast('Koneksi terputus', 'error');
|
|
});
|
|
}
|
|
};
|
|
|
|
btnSaveUser.addEventListener('click', function() {
|
|
const id = manageUserId.value;
|
|
const username = manageUsername.value.trim();
|
|
const password = managePassword.value;
|
|
const role = manageRole.value;
|
|
const ibadah_id = manageIbadahId.value;
|
|
|
|
if (!username) {
|
|
alert('Username wajib diisi');
|
|
return;
|
|
}
|
|
|
|
if (!id && !password) {
|
|
alert('Password wajib diisi untuk user baru');
|
|
return;
|
|
}
|
|
|
|
const payload = { username, role, ibadah_id };
|
|
if (id) payload.id = id;
|
|
if (password) payload.password = password;
|
|
|
|
const endpoint = id ? 'api/users/update.php' : 'api/users/create.php';
|
|
|
|
fetch(endpoint, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(payload)
|
|
})
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
if (data.status === 'success') {
|
|
showToast(data.message, 'success');
|
|
loadUsers();
|
|
resetUserForm();
|
|
} else {
|
|
alert(data.message || 'Gagal menyimpan user');
|
|
}
|
|
})
|
|
.catch(err => {
|
|
alert('Koneksi terputus');
|
|
});
|
|
});
|
|
|
|
btnCancelUserEdit.addEventListener('click', resetUserForm);
|
|
|
|
function resetUserForm() {
|
|
userFormTitle.textContent = 'Tambah User Baru';
|
|
manageUserId.value = '';
|
|
manageUsername.value = '';
|
|
managePassword.value = '';
|
|
manageRole.value = 'pengelola';
|
|
manageIbadahGroup.style.display = 'flex';
|
|
manageIbadahId.value = '';
|
|
btnCancelUserEdit.style.display = 'none';
|
|
}
|
|
|
|
// Helper functions
|
|
function escHtml(str) {
|
|
if (!str) return '';
|
|
return String(str).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
|
|
}
|
|
|
|
// Toast Notification helper
|
|
function showToast(message, type = 'success') {
|
|
if (typeof window.showToast === 'function') {
|
|
window.showToast(message, type);
|
|
return;
|
|
}
|
|
// Fallback alert
|
|
alert(message);
|
|
}
|
|
|
|
// Run session check on initialization
|
|
checkSession();
|
|
})();
|