364 lines
16 KiB
PHP
364 lines
16 KiB
PHP
<?php
|
|
require_once 'koneksi.php';
|
|
cekLogin();
|
|
cekRole('admin');
|
|
|
|
$page = 'users';
|
|
$pageTitle = 'Manajemen User';
|
|
$pageSubtitle = 'Kelola Akun Pengguna Sistem';
|
|
|
|
$users = $conn->query("SELECT * FROM users ORDER BY role ASC, nama_lengkap ASC");
|
|
$total = $users->num_rows;
|
|
|
|
include 'includes/sidebar.php';
|
|
?>
|
|
|
|
<style>
|
|
.custom-header-wrapper {
|
|
display: flex !important;
|
|
justify-content: space-between !important;
|
|
align-items: center !important;
|
|
margin-bottom: 25px !important;
|
|
background: #ffffff !important;
|
|
padding: 20px 24px !important;
|
|
border-radius: 12px !important;
|
|
box-shadow: 0 1px 3px rgba(0,0,0,0.05) !important;
|
|
}
|
|
.custom-stat-grid {
|
|
display: grid !important;
|
|
grid-template-columns: repeat(4, 1fr) !important;
|
|
gap: 20px !important;
|
|
margin-bottom: 30px !important;
|
|
width: 100% !important;
|
|
}
|
|
.custom-stat-box {
|
|
background: #ffffff !important;
|
|
padding: 16px 20px !important;
|
|
border-radius: 12px !important;
|
|
display: flex !important;
|
|
align-items: center !important;
|
|
gap: 16px !important;
|
|
box-shadow: 0 1px 3px rgba(0,0,0,0.05) !important;
|
|
border: 1px solid #e2e8f0 !important;
|
|
}
|
|
.custom-stat-icon {
|
|
width: 48px !important;
|
|
height: 48px !important;
|
|
border-radius: 10px !important;
|
|
display: flex !important;
|
|
align-items: center !important;
|
|
justify-content: center !important;
|
|
flex-shrink: 0 !important;
|
|
}
|
|
.custom-stat-info {
|
|
display: flex !important;
|
|
flex-direction: column !important;
|
|
}
|
|
.custom-stat-info .num {
|
|
font-size: 24px !important;
|
|
font-weight: 800 !important;
|
|
line-height: 1.2 !important;
|
|
margin-bottom: 2px !important;
|
|
}
|
|
.custom-stat-info .lbl {
|
|
color: #64748b !important;
|
|
font-size: 13px !important;
|
|
font-weight: 500 !important;
|
|
}
|
|
|
|
/* Responsif jika dibuka di HP agar layout menyesuaikan otomatis */
|
|
@media (max-width: 768px) {
|
|
.custom-header-wrapper {
|
|
flex-direction: column !important;
|
|
align-items: flex-start !important;
|
|
gap: 15px !important;
|
|
}
|
|
.custom-stat-grid {
|
|
grid-template-columns: repeat(2, 1fr) !important;
|
|
gap: 12px !important;
|
|
}
|
|
}
|
|
@media (max-width: 480px) {
|
|
.custom-stat-grid {
|
|
grid-template-columns: 1fr !important;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<div class="custom-header-wrapper">
|
|
<div>
|
|
<h2 style="margin: 0; font-size: 24px; color: #1e293b; font-weight: 700; display: flex; align-items: center; gap: 10px;">
|
|
<span>👥</span> Manajemen User
|
|
</h2>
|
|
<p style="margin: 4px 0 0 0; color: #64748b; font-size: 14px;">
|
|
Total <strong style="color: #7c3aed; font-weight: 600;"><?= $total ?></strong> akun terdaftar dalam sistem
|
|
</p>
|
|
</div>
|
|
<button class="btn btn-purple" onclick="openModal('modalTambah')" style="display: flex; align-items: center; gap: 8px; padding: 10px 18px; font-weight: 600; border-radius: 8px; cursor: pointer;">
|
|
<i class="fa fa-user-plus"></i> Tambah User Baru
|
|
</button>
|
|
</div>
|
|
|
|
<?php
|
|
$roleStats = [];
|
|
$rs = $conn->query("SELECT role, COUNT(*) AS c FROM users GROUP BY role");
|
|
while ($r = $rs->fetch_assoc()) $roleStats[$r['role']] = $r['c'];
|
|
?>
|
|
<div class="custom-stat-grid">
|
|
<?php
|
|
$roles = [
|
|
'admin' => ['🛡️','Administrator','#7c3aed','#ede9fe'],
|
|
'relawan' => ['🙋','Relawan','#ea580c','#ffedd5'],
|
|
'pengurus' => ['🕌','Pengurus Ibadah','#2563eb','#dbeafe'],
|
|
'pemerintah' => ['🏛️','Pemerintah','#16a34a','#dcfce7'],
|
|
];
|
|
foreach ($roles as $key => [$ic, $lbl, $color, $bg]):
|
|
?>
|
|
<div class="custom-stat-box">
|
|
<div class="custom-stat-icon" style="background:<?= $bg ?>;">
|
|
<span style="font-size:22px"><?= $ic ?></span>
|
|
</div>
|
|
<div class="custom-stat-info">
|
|
<span class="num" style="color:<?= $color ?>;"><?= $roleStats[$key] ?? 0 ?></span>
|
|
<span class="lbl"><?= $lbl ?></span>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header"><h3><i class="fa fa-users" style="color:#7c3aed"></i> Daftar Akun</h3></div>
|
|
<div class="tbl-wrap">
|
|
<table>
|
|
<thead>
|
|
<tr><th>#</th><th>Nama Lengkap</th><th>Username</th><th>Email</th><th>Role</th><th>Status</th><th>Terakhir Login</th><th>Aksi</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php $no=1; $users->data_seek(0); while ($r = $users->fetch_assoc()): ?>
|
|
<?php
|
|
$roleLabel = ['admin'=>'Administrator','relawan'=>'Relawan','pengurus'=>'Pengurus Ibadah','pemerintah'=>'Pemerintah'];
|
|
$roleClass = ['admin'=>'badge-purple','relawan'=>'badge-orange','pengurus'=>'badge-blue','pemerintah'=>'badge-green'];
|
|
?>
|
|
<tr>
|
|
<td style="color:#94a3b8;font-weight:600"><?= $no++ ?></td>
|
|
<td>
|
|
<div style="display:flex;align-items:center;gap:10px">
|
|
<div style="width:34px;height:34px;border-radius:50%;background:<?= ['admin'=>'#7c3aed','relawan'=>'#ea580c','pengurus'=>'#2563eb','pemerintah'=>'#16a34a'][$r['role']]??'#64748b' ?>;display:flex;align-items:center;justify-content:center;color:white;font-weight:700;font-size:13px;flex-shrink:0">
|
|
<?= strtoupper(substr($r['nama_lengkap'],0,1)) ?>
|
|
</div>
|
|
<span style="font-weight:700"><?= htmlspecialchars($r['nama_lengkap']) ?></span>
|
|
</div>
|
|
</td>
|
|
<td style="font-family:monospace;font-size:13px;color:#2563eb">@<?= htmlspecialchars($r['username']) ?></td>
|
|
<td style="font-size:12px;color:#64748b"><?= htmlspecialchars($r['email']) ?></td>
|
|
<td><span class="badge <?= $roleClass[$r['role']]??'badge-gray' ?>"><?= $roleLabel[$r['role']]??$r['role'] ?></span></td>
|
|
<td>
|
|
<?php if ($r['aktif']): ?>
|
|
<span class="badge badge-green">● Aktif</span>
|
|
<?php else: ?>
|
|
<span class="badge badge-red">● Nonaktif</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td style="font-size:12px;color:#64748b">
|
|
<?= $r['last_login'] ? date('d M Y H:i', strtotime($r['last_login'])) : '<span style="color:#94a3b8">Belum pernah</span>' ?>
|
|
</td>
|
|
<td>
|
|
<div style="display:flex;gap:4px">
|
|
<button class="btn btn-primary btn-sm" onclick='editUser(<?= json_encode($r) ?>)' title="Edit User"><i class="fa fa-edit"></i></button>
|
|
<button class="btn btn-warning btn-sm" onclick="resetPassword(<?= $r['id'] ?>, '<?= htmlspecialchars($r['nama_lengkap'], ENT_QUOTES) ?>')" title="Reset Password"><i class="fa fa-key"></i></button>
|
|
<?php if ($r['id'] != $_SESSION['user_id']): ?>
|
|
<button class="btn <?= $r['aktif']?'btn-ghost':'btn-success' ?> btn-sm" onclick="toggleAktif(<?= $r['id'] ?>, <?= $r['aktif'] ?>)" title="<?= $r['aktif']?'Nonaktifkan':'Aktifkan' ?>">
|
|
<i class="fa <?= $r['aktif']?'fa-ban':'fa-check' ?>"></i>
|
|
</button>
|
|
<button class="btn btn-danger btn-sm" onclick="hapusUser(<?= $r['id'] ?>)" title="Hapus User"><i class="fa fa-trash"></i></button>
|
|
<?php endif; ?>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endwhile; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal-overlay" id="modalTambah">
|
|
<div class="modal-box" style="max-width:480px">
|
|
<div class="modal-head">
|
|
<h3><i class="fa fa-user-plus" style="color:#7c3aed"></i> Tambah User Baru</h3>
|
|
<button class="btn-close" onclick="closeModal('modalTambah')">✕</button>
|
|
</div>
|
|
<form method="POST" action="proses.php" onsubmit="return validasiPassword('modalTambah')">
|
|
<input type="hidden" name="aksi" value="tambah_user">
|
|
<div class="modal-body">
|
|
<div class="form-group"><label>Nama Lengkap *</label><input class="form-control" name="nama_lengkap" required placeholder="Nama lengkap pengguna"></div>
|
|
<div class="form-grid-2">
|
|
<div class="form-group"><label>Username *</label><input class="form-control" name="username" required placeholder="username unik"></div>
|
|
<div class="form-group"><label>Role *</label>
|
|
<select class="form-control" name="role">
|
|
<option value="relawan">🙋 Relawan</option>
|
|
<option value="pengurus">🕌 Pengurus Ibadah</option>
|
|
<option value="pemerintah">🏛️ Pemerintah</option>
|
|
<option value="admin">🛡️ Admin</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="form-group"><label>Email *</label><input class="form-control" type="email" name="email" required placeholder="email@domain.com"></div>
|
|
<div class="form-grid-2">
|
|
<div class="form-group"><label>Password *</label><input class="form-control" type="password" name="password" required placeholder="Min. 6 karakter" minlength="6"></div>
|
|
<div class="form-group"><label>Konfirmasi Password *</label><input class="form-control" type="password" name="password2" required placeholder="Ulangi password"></div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-foot">
|
|
<button type="button" class="btn btn-ghost" onclick="closeModal('modalTambah')">Batal</button>
|
|
<button type="submit" class="btn btn-purple"><i class="fa fa-save"></i> Buat Akun</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal-overlay" id="modalEdit">
|
|
<div class="modal-box" style="max-width:480px">
|
|
<div class="modal-head">
|
|
<h3><i class="fa fa-edit" style="color:#2563eb"></i> Edit User</h3>
|
|
<button class="btn-close" onclick="closeModal('modalEdit')">✕</button>
|
|
</div>
|
|
<form method="POST" action="proses.php">
|
|
<input type="hidden" name="aksi" value="edit_user">
|
|
<input type="hidden" name="id" id="eu_id">
|
|
<div class="modal-body">
|
|
<div class="form-group"><label>Nama Lengkap *</label><input class="form-control" name="nama_lengkap" id="eu_nama" required></div>
|
|
<div class="form-grid-2">
|
|
<div class="form-group"><label>Username *</label><input class="form-control" name="username" id="eu_username" required></div>
|
|
<div class="form-group"><label>Role</label>
|
|
<select class="form-control" name="role" id="eu_role">
|
|
<option value="relawan">🙋 Relawan</option>
|
|
<option value="pengurus">🕌 Pengurus Ibadah</option>
|
|
<option value="pemerintah">🏛️ Pemerintah</option>
|
|
<option value="admin">🛡️ Admin</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="form-group"><label>Email *</label><input class="form-control" type="email" name="email" id="eu_email" required></div>
|
|
</div>
|
|
<div class="modal-foot">
|
|
<button type="button" class="btn btn-ghost" onclick="closeModal('modalEdit')">Batal</button>
|
|
<button type="submit" class="btn btn-primary"><i class="fa fa-save"></i> Simpan</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal-overlay" id="modalReset">
|
|
<div class="modal-box" style="max-width:400px">
|
|
<div class="modal-head">
|
|
<h3><i class="fa fa-key" style="color:#ea580c"></i> Reset Password</h3>
|
|
<button class="btn-close" onclick="closeModal('modalReset')">✕</button>
|
|
</div>
|
|
<form method="POST" action="proses.php" onsubmit="return validasiPassword('modalReset')">
|
|
<input type="hidden" name="aksi" value="reset_password">
|
|
<input type="hidden" name="id" id="rp_id">
|
|
<div class="modal-body">
|
|
<p style="font-size:13px;color:#64748b;margin-bottom:16px">Reset password untuk: <strong id="rp_nama"></strong></p>
|
|
<div class="form-group"><label>Password Baru *</label><input class="form-control" type="password" name="password_baru" required placeholder="Min. 6 karakter" minlength="6"></div>
|
|
<div class="form-group"><label>Konfirmasi *</label><input class="form-control" type="password" name="password_baru2" required placeholder="Ulangi password"></div>
|
|
</div>
|
|
<div class="modal-foot">
|
|
<button type="button" class="btn btn-ghost" onclick="closeModal('modalReset')">Batal</button>
|
|
<button type="submit" class="btn btn-warning"><i class="fa fa-key"></i> Reset</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function openModal(id) {
|
|
const modal = document.getElementById(id);
|
|
if(modal) {
|
|
modal.style.display = 'flex';
|
|
}
|
|
}
|
|
|
|
function closeModal(id) {
|
|
const modal = document.getElementById(id);
|
|
if(modal) {
|
|
modal.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function editUser(data) {
|
|
document.getElementById('eu_id').value = data.id;
|
|
document.getElementById('eu_nama').value = data.nama_lengkap;
|
|
document.getElementById('eu_username').value = data.username;
|
|
document.getElementById('eu_email').value = data.email;
|
|
document.getElementById('eu_role').value = data.role;
|
|
|
|
openModal('modalEdit');
|
|
}
|
|
|
|
function resetPassword(id, nama) {
|
|
document.getElementById('rp_id').value = id;
|
|
document.getElementById('rp_nama').innerText = nama;
|
|
|
|
openModal('modalReset');
|
|
}
|
|
|
|
function hapusUser(id) {
|
|
if (confirm('Apakah Anda yakin ingin menghapus user ini secara permanen?')) {
|
|
const form = document.createElement('form');
|
|
form.method = 'POST';
|
|
form.action = 'proses.php';
|
|
|
|
form.innerHTML = `
|
|
<input type="hidden" name="aksi" value="hapus_user">
|
|
<input type="hidden" name="id" value="${id}">
|
|
`;
|
|
document.body.appendChild(form);
|
|
form.submit();
|
|
}
|
|
}
|
|
|
|
function toggleAktif(id, statusSekarang) {
|
|
const pesan = statusSekarang ? 'menonaktifkan' : 'mengaktifkan';
|
|
if (confirm(`Apakah Anda yakin ingin ${pesan} akun ini?`)) {
|
|
const form = document.createElement('form');
|
|
form.method = 'POST';
|
|
form.action = 'proses.php';
|
|
|
|
form.innerHTML = `
|
|
<input type="hidden" name="aksi" value="toggle_aktif">
|
|
<input type="hidden" name="id" value="${id}">
|
|
<input type="hidden" name="aktif" value="${statusSekarang ? 0 : 1}">
|
|
`;
|
|
document.body.appendChild(form);
|
|
form.submit();
|
|
}
|
|
}
|
|
|
|
function validasiPassword(modalId) {
|
|
let p1, p2;
|
|
if(modalId === 'modalTambah') {
|
|
p1 = document.querySelector('#modalTambah input[name="password"]').value;
|
|
p2 = document.querySelector('#modalTambah input[name="password2"]').value;
|
|
} else {
|
|
p1 = document.querySelector('#modalReset input[name="password_baru"]').value;
|
|
p2 = document.querySelector('#modalReset input[name="password_baru2"]').value;
|
|
}
|
|
|
|
if (p1 !== p2) {
|
|
alert('Konfirmasi password tidak cocok! Silakan periksa kembali.');
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Menutup modal jika pengguna mengklik area luar modal-box
|
|
window.onclick = function(event) {
|
|
if (event.target.classList.contains('modal-overlay')) {
|
|
event.target.style.display = 'none';
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<?php
|
|
include 'includes/footer.php';
|
|
?>
|