menambahkan fitur edit data pengguna dan memperbarui landing page

This commit is contained in:
powji17
2026-06-10 17:39:36 +07:00
parent 7c1b4375e7
commit 6158f4b1a4
16 changed files with 869 additions and 455 deletions
@@ -0,0 +1,19 @@
<?php
require_once '../../auth.php';
requireRole('admin');
header('Content-Type: application/json');
$conn = new mysqli("localhost", "root", "", "webgis");
$id = (int) $_GET['id'];
$stmt = $conn->prepare("SELECT id, nama, username, role FROM users WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result();
$data = $result->fetch_assoc();
echo $data ? json_encode($data) : json_encode(["status" => "error", "message" => "User tidak ditemukan"]);
$stmt->close();
$conn->close();
?>
@@ -0,0 +1,28 @@
<?php
require_once '../../auth.php';
requireRole('admin');
header('Content-Type: application/json');
$conn = new mysqli("localhost", "root", "", "webgis");
$data = json_decode(file_get_contents("php://input"), true);
$id = (int) $data['id'];
// Tidak boleh hapus diri sendiri
if ($id === (int) $_SESSION['user']) {
echo json_encode(["status" => "error", "message" => "Tidak bisa menghapus akun sendiri"]);
exit;
}
$stmt = $conn->prepare("DELETE FROM users WHERE id = ?");
$stmt->bind_param("i", $id);
if ($stmt->execute()) {
echo json_encode(["status" => "success"]);
} else {
echo json_encode(["status" => "error", "message" => $stmt->error]);
}
$stmt->close();
$conn->close();
?>
@@ -0,0 +1,55 @@
<?php
require_once '../../auth.php';
requireRole('admin');
header('Content-Type: application/json');
$conn = new mysqli("localhost", "root", "", "webgis");
$data = json_decode(file_get_contents("php://input"), true);
if (!$data || !isset($data['id'])) {
echo json_encode(["status" => "error", "message" => "Data tidak lengkap"]);
exit;
}
$id = (int) $data['id'];
$nama = trim($data['nama']);
$username = trim($data['username']);
$role = $data['role'];
if (!$nama || !$username || !in_array($role, ['admin', 'operator'])) {
echo json_encode(["status" => "error", "message" => "Data tidak valid"]);
exit;
}
// Cek username sudah dipakai user lain
$cek = $conn->prepare("SELECT id FROM users WHERE username = ? AND id != ?");
$cek->bind_param("si", $username, $id);
$cek->execute();
$cek->store_result();
if ($cek->num_rows > 0) {
echo json_encode(["status" => "error", "message" => "Username sudah digunakan user lain"]);
$cek->close();
$conn->close();
exit;
}
$cek->close();
// Update dengan atau tanpa password baru
if (!empty($data['password'])) {
$hash = password_hash($data['password'], PASSWORD_DEFAULT);
$stmt = $conn->prepare("UPDATE users SET nama=?, username=?, password=?, role=? WHERE id=?");
$stmt->bind_param("ssssi", $nama, $username, $hash, $role, $id);
} else {
$stmt = $conn->prepare("UPDATE users SET nama=?, username=?, role=? WHERE id=?");
$stmt->bind_param("sssi", $nama, $username, $role, $id);
}
if ($stmt->execute()) {
echo json_encode(["status" => "success"]);
} else {
echo json_encode(["status" => "error", "message" => $stmt->error]);
}
$stmt->close();
$conn->close();
?>
+247 -91
View File
@@ -1,83 +1,72 @@
/* ===== RESET & BASE ===== */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
height: 100vh; width: 100vw; margin: 0; padding: 0;
display: flex; font-family: Arial, sans-serif; overflow: hidden;
}
#sidebar {
width: 280px; background-color: #f8f9fa; padding: 20px;
box-shadow: 2px 0 5px rgba(0,0,0,0.2); z-index: 1000; overflow-y: auto;
}
#sidebar h3 { margin-top: 0; border-bottom: 2px solid #ddd; padding-bottom: 10px; }
/* Styling Ikon Mode */
.mode-selector { margin-bottom: 20px; }
.mode-buttons {
height: 100vh;
width: 100vw;
overflow: hidden;
display: flex;
justify-content: center;
gap: 8px;
margin-bottom: 8px;
}
.mode-btn {
flex: 0 0 auto; /* tidak melebar penuh */
width: 110px;
padding: 10px 8px;
text-align: center;
}
.mode-btn i { font-size: 24px; margin-bottom: 8px; display: block; }
.mode-btn:hover { background: #e9ecef; }
/* Warna saat tombol mode aktif */
.mode-btn.active[data-mode="point"] { border-color: #e74c3c; color: #e74c3c; background: #fadbd8; }
.mode-btn.active[data-mode="polyline"] { border-color: #3498db; color: #3498db; background: #d6eaf8; }
.mode-btn.active[data-mode="polygon"] { border-color: #2ecc71; color: #2ecc71; background: #d5f5e3; }
.mode-btn.active[data-mode="prasejahtera"] { border-color: #c0392b; color: #ffffff; background: #e74c3c; }
.mode-btn.active[data-mode="ibadah"] { border-color: #6c3483; color: #ffffff; background: #8e44ad; }
/* Styling tombol edit aktif */
.mode-btn.active[data-mode="edit_jalan"] { background-color: #f1c40f !important; color: white !important; }
.mode-btn.active[data-mode="edit_kavling"] { background-color: #27ae60 !important; color: white !important; }
/* Styling Input & Action Buttons */
.action-buttons {
display: none; background: #fff; padding: 15px;
border-radius: 8px; border: 1px solid #ddd; margin-top: 10px; margin-bottom: 20px;
font-family: 'Segoe UI', Arial, sans-serif;
}
.action-buttons input, .action-buttons select {
width: 100%; margin-bottom: 15px; padding: 8px; box-sizing: border-box;
border: 1px solid #ccc; border-radius: 4px;
/* ===== SIDEBAR ===== */
#sidebar {
width: 280px;
min-width: 280px;
background: white;
display: flex;
flex-direction: column;
padding: 0;
box-shadow: 2px 0 12px rgba(0,0,0,0.10);
z-index: 1000;
overflow-y: auto;
}
.action-buttons button {
width: 100%; padding: 10px; margin-bottom: 8px; cursor: pointer;
border-radius: 5px; font-weight: bold;
/* Header sidebar */
.sidebar-header {
background: #1B2A4A;
color: white;
padding: 18px 20px;
font-size: 16px;
font-weight: 700;
display: flex;
align-items: center;
gap: 10px;
letter-spacing: 0.3px;
flex-shrink: 0;
}
.btn-success { background-color: #2ecc71; color: white; border: none; }
.btn-danger { background-color: #e74c3c; color: white; border: none; }
#map-container { flex: 1; position: relative; }
#map { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }
.sidebar-body {
padding: 16px;
display: flex;
flex-direction: column;
gap: 10px;
flex: 1;
}
/* ===== USER INFO ===== */
.user-info {
display: flex;
flex-direction: column;
align-items: center;
padding: 12px;
padding: 16px 12px;
background: #f0f4f8;
border-radius: 8px;
margin-bottom: 12px;
gap: 4px;
border-radius: 10px;
gap: 6px;
}
.user-info i {
font-size: 28px;
font-size: 32px;
color: #1B2A4A;
}
.user-info span {
font-weight: 600;
font-size: 14px;
font-weight: 700;
font-size: 15px;
color: #1B2A4A;
}
@@ -85,52 +74,219 @@ html, body {
font-size: 11px;
background: #1B2A4A;
color: white;
padding: 2px 8px;
padding: 3px 10px;
border-radius: 20px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
/* ===== DIVIDER ===== */
.sidebar-divider {
height: 1px;
background: #e8edf2;
margin: 2px 0;
}
/* ===== LABEL SECTION ===== */
.sidebar-label {
font-size: 11px;
font-weight: 700;
color: #aab4c0;
text-transform: uppercase;
letter-spacing: 0.8px;
padding: 0 2px;
}
/* ===== TOMBOL MODE (Prasejahtera & Rumah Ibadah) ===== */
.mode-buttons {
display: flex;
gap: 8px;
justify-content: center;
}
.mode-btn {
flex: 1;
padding: 12px 6px;
background: #f0f4f8;
border: 2px solid transparent;
border-radius: 10px;
cursor: pointer;
font-size: 12px;
font-weight: 600;
color: #4a5568;
text-align: center;
transition: all 0.2s;
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
line-height: 1.3;
}
.mode-btn i {
font-size: 20px;
color: #1B2A4A;
display: block;
margin-bottom: 0;
}
.mode-btn:hover {
background: #e2e8f0;
border-color: #1B2A4A;
}
/* Warna saat tombol mode aktif */
.mode-btn.active,
.mode-btn.active[data-mode="prasejahtera"] {
background: #e74c3c;
border-color: #c0392b;
color: white;
}
.mode-btn.active i,
.mode-btn.active[data-mode="prasejahtera"] i {
color: white;
}
.mode-btn.active[data-mode="ibadah"],
.mode-btn.mode-ibadah.active {
background: #8e44ad;
border-color: #6c3483;
color: white;
}
.mode-btn.active[data-mode="ibadah"] i,
.mode-btn.mode-ibadah.active i {
color: white;
}
/* Mode lain (polyline, polygon, dll — tetap dipertahankan) */
.mode-btn.active[data-mode="point"] { border-color: #e74c3c; color: #e74c3c; background: #fadbd8; }
.mode-btn.active[data-mode="polyline"] { border-color: #3498db; color: #3498db; background: #d6eaf8; }
.mode-btn.active[data-mode="polygon"] { border-color: #2ecc71; color: #2ecc71; background: #d5f5e3; }
.mode-btn.active[data-mode="edit_jalan"] { background: #f1c40f; border-color: #d4ac0d; color: white; }
.mode-btn.active[data-mode="edit_kavling"] { background: #27ae60; border-color: #1e8449; color: white; }
/* ===== ACTION BUTTONS (panel dalam sidebar, dipertahankan) ===== */
.action-buttons {
display: none;
background: #fff;
padding: 15px;
border-radius: 8px;
border: 1px solid #ddd;
margin-top: 4px;
}
.action-buttons input,
.action-buttons select {
width: 100%;
margin-bottom: 15px;
padding: 8px;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 4px;
}
.action-buttons button {
width: 100%;
padding: 10px;
margin-bottom: 8px;
cursor: pointer;
border-radius: 5px;
font-weight: bold;
}
.btn-success { background-color: #2ecc71; color: white; border: none; }
.btn-danger { background-color: #e74c3c; color: white; border: none; }
/* ===== MENU LINK (Kelola User) ===== */
.menu-link {
display: flex;
align-items: center;
gap: 10px;
padding: 11px 14px;
background: #f0f4f8;
border-radius: 10px;
text-decoration: none;
font-size: 14px;
font-weight: 600;
color: #1B2A4A;
transition: background 0.2s;
width: 100%;
border: none;
cursor: pointer;
}
.menu-link:hover { background: #e2e8f0; }
/* ===== VIEWER INFO ===== */
.viewer-info {
font-size: 13px;
color: #888;
text-align: center;
margin-bottom: 10px;
}
.btn-login, .btn-logout, .menu-link {
display: block;
width: 100%;
padding: 10px;
text-align: center;
border-radius: 8px;
font-size: 14px;
font-weight: 600;
text-decoration: none;
margin-bottom: 8px;
cursor: pointer;
border: none;
padding: 12px;
background: #f0f4f8;
border-radius: 10px;
}
/* ===== TOMBOL LOGIN & LOGOUT ===== */
.btn-login {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 12px;
background: #1B2A4A;
color: white;
}
.btn-logout {
background: #fdecea;
color: #c0392b;
}
.menu-link,
.btn-logout,
.btn-login {
width: auto; /* tidak full width lagi */
display: block;
margin: 0 auto 8px auto;
padding: 10px 24px;
text-align: center;
border-radius: 10px;
text-decoration: none;
font-size: 14px;
font-weight: 600;
transition: background 0.2s;
width: 100%;
border: none;
cursor: pointer;
}
.btn-login:hover { background: #253d6e; }
.btn-logout {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 11px;
background: #fdecea;
color: #c0392b;
border-radius: 10px;
text-decoration: none;
font-size: 14px;
font-weight: 600;
border: none;
cursor: pointer;
transition: background 0.2s;
width: 100%;
margin-top: auto;
}
.btn-logout:hover { background: #f5b7b1; }
.menu-link:hover { background: #dce4f0; }
/* ===== MAP CONTAINER ===== */
#map-container {
flex: 1;
position: relative;
}
#map {
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
}
/* ===== LAYER CONTROL ===== */
.leaflet-control-layers {
border-radius: 10px !important;
border: none !important;
box-shadow: 0 2px 12px rgba(0,0,0,0.12) !important;
font-family: 'Segoe UI', Arial, sans-serif !important;
font-size: 13px !important;
}
+49 -33
View File
@@ -17,46 +17,62 @@ $role = $isLoggedIn ? $_SESSION['role'] : 'viewer';
</head>
<body>
<div id="sidebar">
<h3>Menu Pemetaan</h3>
<?php if ($isLoggedIn): ?>
<!-- Tampil kalau sudah login -->
<div class="user-info">
<i class="fa-solid fa-circle-user"></i>
<span><?= htmlspecialchars($_SESSION['nama']) ?></span>
<small><?= ucfirst($role) ?></small>
</div>
<div class="sidebar-header">
<i class="fa-solid fa-map-location-dot"></i>
Sistem Pemetaan
</div>
<?php if (in_array($role, ['admin', 'operator'])): ?>
<div class="mode-buttons">
<button class="mode-btn" data-mode="prasejahtera" onclick="ubahMode('prasejahtera')">
<i class="fa-solid fa-house-chimney-crack"></i> Prasejahtera
</button>
<button class="mode-btn mode-ibadah" data-mode="ibadah" onclick="ubahMode('ibadah')">
<i class="fa-solid fa-place-of-worship"></i> Rumah Ibadah
</button>
<div class="sidebar-body">
<?php if ($isLoggedIn): ?>
<div class="user-info">
<i class="fa-solid fa-circle-user"></i>
<span><?= htmlspecialchars($_SESSION['nama']) ?></span>
<small><?= ucfirst($role) ?></small>
</div>
<?php endif; ?>
<?php if ($role === 'admin'): ?>
<a href="users.php" class="menu-link">
<i class="fa-solid fa-users-gear"></i> Kelola User
<?php if (in_array($role, ['admin', 'operator'])): ?>
<div class="sidebar-divider"></div>
<span class="sidebar-label">Input Data</span>
<div class="mode-buttons">
<button class="mode-btn" data-mode="prasejahtera" onclick="ubahMode('prasejahtera')">
<i class="fa-solid fa-house-chimney-crack"></i>
Prasejahtera
</button>
<button class="mode-btn mode-ibadah" data-mode="ibadah" onclick="ubahMode('ibadah')">
<i class="fa-solid fa-place-of-worship"></i>
Rumah Ibadah
</button>
</div>
<?php endif; ?>
<?php if ($role === 'admin'): ?>
<div class="sidebar-divider"></div>
<span class="sidebar-label">Manajemen</span>
<a href="users.php" class="menu-link">
<i class="fa-solid fa-users-gear"></i> Kelola User
</a>
<?php endif; ?>
<div class="sidebar-divider"></div>
<a href="logout.php" class="btn-logout">
<i class="fa-solid fa-right-from-bracket"></i> Logout
</a>
<?php else: ?>
<div class="viewer-info">
<i class="fa-solid fa-eye"></i> Anda melihat sebagai <b>Viewer</b>
</div>
<a href="login.php" class="btn-login">
<i class="fa-solid fa-right-to-bracket"></i> Login
</a>
<?php endif; ?>
<a href="logout.php" class="btn-logout">
<i class="fa-solid fa-right-from-bracket"></i> Logout
</a>
<?php else: ?>
<!-- Tampil kalau belum login (viewer) -->
<p class="viewer-info">
<i class="fa-solid fa-eye"></i> Anda melihat sebagai <b>Viewer</b>
</p>
<a href="login.php" class="btn-login">
<i class="fa-solid fa-right-to-bracket"></i> Login
</a>
<?php endif; ?>
</div>
</div>
<div id="map-container">
+196 -55
View File
@@ -17,7 +17,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['
if (!$nama || !$username || !$password || !in_array($role, ['admin', 'operator'])) {
$error = "Semua field wajib diisi dengan benar.";
} else {
// Cek apakah username sudah ada
$cek = $conn->prepare("SELECT id FROM users WHERE username = ?");
$cek->bind_param("s", $username);
$cek->execute();
@@ -43,8 +42,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['
// --- HAPUS USER ---
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'hapus') {
$id = (int) $_POST['id'];
// Tidak boleh hapus diri sendiri
if ($id === (int) $_SESSION['user']) {
$error = "Tidak bisa menghapus akun yang sedang aktif.";
} else {
@@ -59,7 +56,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['
}
}
// --- AMBIL SEMUA USER ---
$users = $conn->query("SELECT id, nama, username, role, created_at FROM users ORDER BY created_at DESC");
$conn->close();
?>
@@ -79,7 +75,6 @@ $conn->close();
min-height: 100vh;
}
/* NAVBAR */
.navbar {
background: #1B2A4A;
color: white;
@@ -89,10 +84,7 @@ $conn->close();
justify-content: space-between;
}
.navbar h1 {
font-size: 18px;
font-weight: 600;
}
.navbar h1 { font-size: 18px; font-weight: 600; }
.navbar a {
color: white;
@@ -107,18 +99,21 @@ $conn->close();
.navbar a:hover { opacity: 1; }
/* CONTAINER */
.container {
max-width: 900px;
max-width: 1100px;
margin: 32px auto;
padding: 0 20px;
display: grid;
grid-template-columns: 1fr 320px;
grid-template-columns: 1fr 300px;
gap: 24px;
align-items: start;
}
/* CARD */
thead th:last-child,
tbody td:last-child {
min-width: 160px;
}
.card {
background: white;
border-radius: 12px;
@@ -137,9 +132,11 @@ $conn->close();
gap: 8px;
}
/* Header edit punya warna berbeda */
.card-header.edit { background: #2980b9; }
.card-body { padding: 20px; }
/* ALERT */
.alert {
padding: 12px 16px;
border-radius: 8px;
@@ -153,12 +150,7 @@ $conn->close();
.alert-success { background: #eafaf1; color: #1e8449; }
.alert-error { background: #fdecea; color: #c0392b; }
/* TABEL */
table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
}
table { width: 100%; border-collapse: collapse; font-size: 14px; }
thead th {
background: #f0f4f8;
@@ -177,11 +169,7 @@ $conn->close();
}
tbody tr:hover { background: #fafbfc; }
tbody td {
padding: 12px 14px;
color: #333;
}
tbody td { padding: 12px 14px; color: #333; }
.badge {
display: inline-block;
@@ -204,10 +192,11 @@ $conn->close();
margin-left: 4px;
}
.btn-hapus {
.action-buttons { display: flex; gap: 6px; }
.btn-edit, .btn-hapus {
background: none;
border: none;
color: #e74c3c;
cursor: pointer;
font-size: 13px;
padding: 4px 8px;
@@ -215,10 +204,15 @@ $conn->close();
transition: background 0.15s;
}
.btn-edit { color: #2980b9; }
.btn-hapus { color: #e74c3c; }
.btn-edit:hover { background: #e8f4fd; }
.btn-hapus:hover { background: #fdecea; }
.btn-edit:disabled,
.btn-hapus:disabled { opacity: 0.3; cursor: not-allowed; }
/* FORM */
.form-group { margin-bottom: 14px; }
.form-group label {
@@ -243,14 +237,17 @@ $conn->close();
}
.form-group input:focus,
.form-group select:focus {
border-color: #1B2A4A;
.form-group select:focus { border-color: #1B2A4A; }
.form-group .hint {
font-size: 11px;
color: #aaa;
margin-top: 4px;
}
.btn-submit {
width: 100%;
padding: 11px;
background: #1B2A4A;
color: white;
border: none;
border-radius: 8px;
@@ -262,13 +259,44 @@ $conn->close();
align-items: center;
justify-content: center;
gap: 6px;
margin-bottom: 8px;
}
.btn-submit:hover { background: #253d6e; }
.btn-submit.tambah { background: #1B2A4A; }
.btn-submit.tambah:hover { background: #253d6e; }
.btn-submit.simpan { background: #2980b9; }
.btn-submit.simpan:hover { background: #2471a3; }
.btn-batal {
width: 100%;
padding: 9px;
background: none;
border: 1px solid #ddd;
border-radius: 8px;
font-size: 14px;
color: #888;
cursor: pointer;
transition: background 0.2s;
}
.btn-batal:hover { background: #f0f4f8; }
@media (max-width: 680px) {
.container { grid-template-columns: 1fr; }
}
.action-buttons {
display: flex;
gap: 4px;
align-items: center;
flex-wrap: nowrap;
}
/* Pastikan kolom Aksi cukup lebar */
tbody td:last-child {
white-space: nowrap;
min-width: 130px;
}
</style>
</head>
<body>
@@ -291,15 +319,13 @@ $conn->close();
<?php if ($error): ?>
<div class="alert alert-error">
<i class="fa-solid fa-circle-exclamation"></i>
<?= $error ?>
<i class="fa-solid fa-circle-exclamation"></i> <?= $error ?>
</div>
<?php endif; ?>
<?php if ($success): ?>
<div class="alert alert-success">
<i class="fa-solid fa-circle-check"></i>
<?= $success ?>
<i class="fa-solid fa-circle-check"></i> <?= $success ?>
</div>
<?php endif; ?>
@@ -332,14 +358,17 @@ $conn->close();
</td>
<td><?= date('d M Y', strtotime($u['created_at'])) ?></td>
<td>
<form method="POST" onsubmit="return konfirmasiHapus(this)">
<input type="hidden" name="action" value="hapus">
<input type="hidden" name="id" value="<?= $u['id'] ?>">
<button type="submit" class="btn-hapus"
<div class="action-buttons">
<button class="btn-edit"
onclick="bukaFormEdit(<?= $u['id'] ?>, '<?= htmlspecialchars($u['nama'], ENT_QUOTES) ?>', '<?= htmlspecialchars($u['username'], ENT_QUOTES) ?>', '<?= $u['role'] ?>')">
<i class="fa-solid fa-pen-to-square"></i> Edit
</button>
<button class="btn-hapus"
onclick="hapusUser(<?= $u['id'] ?>)"
<?= $u['id'] == $_SESSION['user'] ? 'disabled title="Tidak bisa hapus akun sendiri"' : '' ?>>
<i class="fa-solid fa-trash"></i> Hapus
</button>
</form>
</div>
</td>
</tr>
<?php endwhile; ?>
@@ -348,40 +377,59 @@ $conn->close();
</div>
</div>
<!-- FORM TAMBAH USER -->
<div class="card">
<div class="card-header">
<i class="fa-solid fa-user-plus"></i> Tambah User Baru
<!-- PANEL KANAN: FORM TAMBAH / EDIT -->
<div class="card" id="form-card">
<!-- Header: berubah sesuai mode -->
<div class="card-header" id="form-header">
<i class="fa-solid fa-user-plus"></i>
<span id="form-title">Tambah User Baru</span>
</div>
<div class="card-body">
<form method="POST">
<input type="hidden" name="action" value="tambah">
<form method="POST" id="form-tambah" onsubmit="return validasiForm()">
<input type="hidden" name="action" value="tambah" id="form-action">
<input type="hidden" id="edit-id" value="">
<div class="form-group">
<label>Nama Lengkap</label>
<input type="text" name="nama" placeholder="Contoh: Budi Santoso" required>
<input type="text" name="nama" id="input-nama"
placeholder="Contoh: Budi Santoso" required>
</div>
<div class="form-group">
<label>Username</label>
<input type="text" name="username" placeholder="Contoh: budi123" required>
<input type="text" name="username" id="input-username"
placeholder="Contoh: budi123" required>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" placeholder="Min. 6 karakter" required>
<input type="password" name="password" id="input-password"
placeholder="Min. 6 karakter">
<p class="hint" id="password-hint" style="display:none;">
<i class="fa-solid fa-circle-info"></i>
Kosongkan jika tidak ingin mengubah password
</p>
</div>
<div class="form-group">
<label>Role</label>
<select name="role">
<select name="role" id="input-role">
<option value="operator">Operator</option>
<option value="admin">Admin</option>
</select>
</div>
<button type="submit" class="btn-submit">
<i class="fa-solid fa-user-plus"></i> Tambah User
<button type="submit" class="btn-submit tambah" id="btn-submit">
<i class="fa-solid fa-user-plus"></i>
<span id="btn-submit-text">Tambah User</span>
</button>
<!-- Tombol Batal hanya muncul saat mode Edit -->
<button type="button" class="btn-batal" id="btn-batal"
style="display:none;" onclick="batalEdit()">
<i class="fa-solid fa-xmark"></i> Batal Edit
</button>
</form>
</div>
@@ -390,8 +438,101 @@ $conn->close();
</div>
<script>
function konfirmasiHapus(form) {
return confirm("Yakin ingin menghapus user ini?");
const SESSION_USER_ID = <?= (int) $_SESSION['user'] ?>;
let modeEdit = false;
function bukaFormEdit(id, nama, username, role) {
modeEdit = true;
// Isi form dengan data user yang dipilih
document.getElementById('edit-id').value = id;
document.getElementById('input-nama').value = nama;
document.getElementById('input-username').value = username;
document.getElementById('input-role').value = role;
document.getElementById('input-password').value = '';
// Ubah tampilan form ke mode Edit
document.getElementById('form-header').classList.add('edit');
document.getElementById('form-title').textContent = 'Edit User';
document.getElementById('form-header').querySelector('i').className = 'fa-solid fa-user-pen';
document.getElementById('btn-submit').className = 'btn-submit simpan';
document.getElementById('btn-submit-text').textContent = 'Simpan Perubahan';
document.getElementById('btn-submit').querySelector('i').className = 'fa-solid fa-save';
document.getElementById('password-hint').style.display = 'block';
document.getElementById('btn-batal').style.display = 'block';
document.getElementById('input-password').required = false;
// Scroll ke form (berguna di mobile)
document.getElementById('form-card').scrollIntoView({ behavior: 'smooth' });
}
function batalEdit() {
modeEdit = false;
// Reset form ke mode Tambah
document.getElementById('form-tambah').reset();
document.getElementById('edit-id').value = '';
document.getElementById('form-header').classList.remove('edit');
document.getElementById('form-title').textContent = 'Tambah User Baru';
document.getElementById('form-header').querySelector('i').className = 'fa-solid fa-user-plus';
document.getElementById('btn-submit').className = 'btn-submit tambah';
document.getElementById('btn-submit-text').textContent = 'Tambah User';
document.getElementById('btn-submit').querySelector('i').className = 'fa-solid fa-user-plus';
document.getElementById('password-hint').style.display = 'none';
document.getElementById('btn-batal').style.display = 'none';
document.getElementById('input-password').required = true;
}
function validasiForm() {
if (!modeEdit) return true; // Mode tambah, biarkan PHP handle
// Mode edit: kirim via fetch, bukan submit form biasa
let id = document.getElementById('edit-id').value;
let nama = document.getElementById('input-nama').value.trim();
let username = document.getElementById('input-username').value.trim();
let password = document.getElementById('input-password').value;
let role = document.getElementById('input-role').value;
if (!nama || !username) {
alert('Nama dan username wajib diisi.');
return false;
}
fetch('api/users/update_user.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id, nama, username, password, role })
})
.then(res => res.json())
.then(data => {
if (data.status === 'success') {
// Reload halaman untuk refresh tabel
window.location.reload();
} else {
alert('Gagal: ' + (data.message || 'Terjadi kesalahan'));
}
});
return false; // Cegah submit form biasa
}
function hapusUser(id) {
if (!confirm('Yakin ingin menghapus user ini?')) return;
fetch('api/users/hapus_user.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: id })
})
.then(res => res.json())
.then(data => {
if (data.status === 'success') {
window.location.reload();
} else {
alert('Gagal: ' + (data.message || 'Terjadi kesalahan'));
}
});
}
</script>