Files
webgis-poverty-pontianak/assets/js/features/auth.js
T

370 lines
14 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;
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 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';
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();
});
}
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, '&quot;')})">
<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,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}
// 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();
})();