diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..29f2e14 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,21 @@ +.git/ +.claude/ +.agents/ +.codex/ +.superpowers/ +.env + +02/ +docs/ +submission/ +Tugas/ +DESIGN.md +SpesifikasiKebutuhanPerangkatLunak.docx +SpesifikasiKebutuhanPerangkatLunak.md + +**/tests/ +**/tmp/ +**/*.log +node_modules/ +.cache/ +__pycache__/ diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..f6bc1a2 --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +MARIADB_ROOT_PASSWORD=change-this-password diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f062ae5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +# Local agent/tooling metadata +.claude/ +.superpowers/ +.agents/ +.codex/ + +# Generated runtime/temp files +tmp/ +.env +*.tmp +*.temp +*.log +*.bak +*.swp + +# OS/editor noise +.DS_Store +Thumbs.db +desktop.ini +.vscode/ +.idea/ + +# Dependency/cache folders not required by this plain PHP submission +node_modules/ +.cache/ +__pycache__/ + +# Unrelated local design scratch file at repository root +DESIGN.md + +# Unrelated file +Tugas/ +superpowers + +# Internal development planning docs, not needed for submission +WebgisPovertyMapping/docs/superpowers/ +WebgisPovertyMapping/docs/archive/ +WebgisPovertyMapping/docs/audit-fix-task-plan.md +/docs +/02 +/submission +SpesifikasiKebutuhanPerangkatLunak.docx +SpesifikasiKebutuhanPerangkatLunak.md diff --git a/01/README.md b/01/README.md new file mode 100644 index 0000000..0fc54bc --- /dev/null +++ b/01/README.md @@ -0,0 +1,84 @@ +# Project 01 - WebGIS Dasar + +Project ini adalah tugas kelas WebGIS dasar berbasis Leaflet.js, PHP, dan MySQL/MariaDB. Fokusnya adalah pengelolaan layer geometri dasar: point, polyline, dan polygon. + +## Status Project + +Project ini disertakan sebagai artifact tugas kelas. Aplikasi final Tugas Besar ada di folder `../WebgisPovertyMapping`. + +File utama untuk demo project ini adalah: + +```text +index.php +``` + +File `index.html` dan endpoint root seperti `simpan.php`, `ambil_data.php`, `hapus.php`, dan `update_posisi.php` adalah peninggalan versi awal POI. Demo utama menggunakan `index.php` dan endpoint di folder `api/`. + +## Fitur + +| Fitur | Deskripsi | +| --- | --- | +| POI/lokasi usaha | Tambah, tampilkan, hapus, dan drag marker lokasi usaha | +| Data jalan | Gambar polyline jalan, simpan status jalan, hitung panjang | +| Data parsil | Gambar polygon bidang tanah, simpan status kepemilikan, hitung luas | +| CRUD API | Endpoint per layer di `api/point/`, `api/jalan/`, dan `api/parsil/` | +| Peta interaktif | Leaflet.js dengan tile OpenStreetMap | + +## Struktur Utama + +```text +01/ +├── index.php +├── koneksi.php +├── setup_database.sql +├── api/ +│ ├── point/ +│ ├── jalan/ +│ └── parsil/ +└── modules/ + ├── point.js + ├── jalan.js + └── parsil.js +``` + +## Database + +Project ini memakai database khusus: + +```text +db_webgis_01 +``` + +Import schema: + +```powershell +mysql -u root -P 3307 < setup_database.sql +``` + +Jika MySQL/MariaDB lokal memakai port lain, sesuaikan `DB_PORT` pada `koneksi.php`. + +## Konfigurasi + +Konfigurasi database ada di `koneksi.php`: + +```php +define('DB_HOST', 'localhost'); +define('DB_USER', 'root'); +define('DB_PASS', ''); +define('DB_NAME', 'db_webgis_01'); +define('DB_PORT', 3307); +``` + +## Akses Lokal + +```text +http://localhost/webgis/01/ +``` + +## Dependensi + +- Leaflet.js +- OpenStreetMap tile +- Google Fonts + +Dependensi frontend dimuat dari CDN, sehingga demo membutuhkan koneksi internet. diff --git a/01/ambil_data.php b/01/ambil_data.php new file mode 100644 index 0000000..2ff1c26 --- /dev/null +++ b/01/ambil_data.php @@ -0,0 +1,46 @@ +query( + "SELECT id, nama_tempat, no_wa, buka_24jam, latitude, longitude + FROM lokasi_usaha + ORDER BY id DESC" +); + +if (!$result) { + http_response_code(500); + echo json_encode(['status' => 'error', 'message' => 'Query gagal: ' . $conn->error]); + exit; +} + +$data = []; +while ($row = $result->fetch_assoc()) { + $data[] = [ + 'id' => (int)$row['id'], + 'nama_tempat' => $row['nama_tempat'], + 'no_wa' => $row['no_wa'], + 'buka_24jam' => (int)$row['buka_24jam'], + 'latitude' => (float)$row['latitude'], + 'longitude' => (float)$row['longitude'] + ]; +} + +echo json_encode([ + 'status' => 'success', + 'total' => count($data), + 'data' => $data +]); + +$conn->close(); \ No newline at end of file diff --git a/01/api/choropleth/ambil.php b/01/api/choropleth/ambil.php new file mode 100644 index 0000000..540179c --- /dev/null +++ b/01/api/choropleth/ambil.php @@ -0,0 +1,29 @@ +query( + "SELECT id, nama, deskripsi, attribute_key, palette, is_visible, created_at + FROM choropleth_layers ORDER BY created_at ASC" +); + +if ($result === false) { + echo json_encode(['status' => 'error', 'message' => 'Tabel belum ada. Jalankan setup_database.sql terlebih dahulu. (' . $conn->error . ')']); + $conn->close(); exit; +} + +$rows = []; +while ($r = $result->fetch_assoc()) { + $rows[] = [ + 'id' => (int)$r['id'], + 'nama' => $r['nama'], + 'deskripsi' => $r['deskripsi'], + 'attribute_key' => $r['attribute_key'], + 'palette' => $r['palette'], + 'is_visible' => (bool)$r['is_visible'], + 'created_at' => $r['created_at'], + ]; +} +$conn->close(); + +echo json_encode(['status' => 'success', 'data' => $rows, 'total' => count($rows)]); diff --git a/01/api/choropleth/geojson.php b/01/api/choropleth/geojson.php new file mode 100644 index 0000000..4c3119e --- /dev/null +++ b/01/api/choropleth/geojson.php @@ -0,0 +1,22 @@ + 'error', 'message' => 'ID tidak valid.']); exit; +} + +$stmt = $conn->prepare("SELECT geojson FROM choropleth_layers WHERE id = ?"); +$stmt->bind_param('i', $id); +$stmt->execute(); +$row = $stmt->get_result()->fetch_assoc(); +$stmt->close(); +$conn->close(); + +if (!$row) { + http_response_code(404); + echo json_encode(['status' => 'error', 'message' => 'Layer tidak ditemukan.']); exit; +} + +echo $row['geojson']; diff --git a/01/api/choropleth/hapus.php b/01/api/choropleth/hapus.php new file mode 100644 index 0000000..89e8efd --- /dev/null +++ b/01/api/choropleth/hapus.php @@ -0,0 +1,26 @@ + 'error', 'message' => 'Method tidak valid.']); exit; +} + +$id = (int)($_POST['id'] ?? 0); +if ($id <= 0) { + echo json_encode(['status' => 'error', 'message' => 'ID tidak valid.']); exit; +} + +$stmt = $conn->prepare("DELETE FROM choropleth_layers WHERE id = ?"); +$stmt->bind_param('i', $id); +$stmt->execute(); +$affected = $stmt->affected_rows; +$stmt->close(); +$conn->close(); + +if ($affected === 0) { + echo json_encode(['status' => 'error', 'message' => 'Layer tidak ditemukan.']); exit; +} + +echo json_encode(['status' => 'success']); diff --git a/01/api/choropleth/toggle.php b/01/api/choropleth/toggle.php new file mode 100644 index 0000000..a55d76a --- /dev/null +++ b/01/api/choropleth/toggle.php @@ -0,0 +1,27 @@ + 'error', 'message' => 'Method tidak valid.']); exit; +} + +$id = (int)($_POST['id'] ?? 0); +if ($id <= 0) { + echo json_encode(['status' => 'error', 'message' => 'ID tidak valid.']); exit; +} + +$stmt = $conn->prepare("UPDATE choropleth_layers SET is_visible = 1 - is_visible WHERE id = ?"); +$stmt->bind_param('i', $id); +$stmt->execute(); +$stmt->close(); + +$stmt2 = $conn->prepare("SELECT is_visible FROM choropleth_layers WHERE id = ?"); +$stmt2->bind_param('i', $id); +$stmt2->execute(); +$row = $stmt2->get_result()->fetch_assoc(); +$stmt2->close(); +$conn->close(); + +echo json_encode(['status' => 'success', 'is_visible' => (bool)$row['is_visible']]); diff --git a/01/api/choropleth/upload.php b/01/api/choropleth/upload.php new file mode 100644 index 0000000..1984a09 --- /dev/null +++ b/01/api/choropleth/upload.php @@ -0,0 +1,54 @@ + 'error', 'message' => 'Method tidak valid.']); exit; +} + +$nama = trim($_POST['nama'] ?? ''); +$deskripsi = trim($_POST['deskripsi'] ?? ''); +$attr_key = trim($_POST['attribute_key'] ?? ''); +$palette = in_array($_POST['palette'] ?? '', ['blue', 'orange', 'green', 'purple']) + ? $_POST['palette'] : 'blue'; + +if (!$nama || !$attr_key) { + echo json_encode(['status' => 'error', 'message' => 'Nama layer dan atribut wajib diisi.']); exit; +} + +if (empty($_FILES['geojson']['tmp_name']) || $_FILES['geojson']['error'] !== UPLOAD_ERR_OK) { + echo json_encode(['status' => 'error', 'message' => 'File GeoJSON tidak ditemukan atau gagal diupload.']); exit; +} + +if ($_FILES['geojson']['size'] > 10 * 1024 * 1024) { + echo json_encode(['status' => 'error', 'message' => 'File terlalu besar (maksimum 10 MB).']); exit; +} + +$raw = file_get_contents($_FILES['geojson']['tmp_name']); +if ($raw === false) { + echo json_encode(['status' => 'error', 'message' => 'Gagal membaca file.']); exit; +} + +$gj = json_decode($raw, true); +if (!$gj || !isset($gj['type']) || $gj['type'] !== 'FeatureCollection') { + echo json_encode(['status' => 'error', 'message' => 'File bukan GeoJSON FeatureCollection yang valid.']); exit; +} +if (empty($gj['features'])) { + echo json_encode(['status' => 'error', 'message' => 'GeoJSON tidak memiliki fitur/data.']); exit; +} + +$first_props = $gj['features'][0]['properties'] ?? []; +if (!array_key_exists($attr_key, $first_props)) { + $available = implode(', ', array_keys($first_props)); + echo json_encode(['status' => 'error', 'message' => "Atribut '{$attr_key}' tidak ditemukan. Tersedia: {$available}"]); exit; +} + +$stmt = $conn->prepare("INSERT INTO choropleth_layers (nama, deskripsi, geojson, attribute_key, palette) VALUES (?, ?, ?, ?, ?)"); +$stmt->bind_param('sssss', $nama, $deskripsi, $raw, $attr_key, $palette); +$stmt->execute(); +$id = $conn->insert_id; +$stmt->close(); +$conn->close(); + +echo json_encode(['status' => 'success', 'id' => $id, 'nama' => $nama]); diff --git a/01/api/jalan/ambil.php b/01/api/jalan/ambil.php new file mode 100644 index 0000000..e01ae96 --- /dev/null +++ b/01/api/jalan/ambil.php @@ -0,0 +1,24 @@ +query("SELECT id, nama_jalan, status_jalan, geojson, panjang_meter FROM data_jalan ORDER BY id DESC"); + +if (!$result) { + echo json_encode(['status' => 'error', 'message' => $conn->error]); + exit; +} + +$data = []; +while ($row = $result->fetch_assoc()) { + $data[] = $row; +} + +echo json_encode([ + 'status' => 'success', + 'total' => count($data), + 'data' => $data +]); + +$conn->close(); \ No newline at end of file diff --git a/01/api/jalan/hapus.php b/01/api/jalan/hapus.php new file mode 100644 index 0000000..da2f2cf --- /dev/null +++ b/01/api/jalan/hapus.php @@ -0,0 +1,27 @@ + 'error', 'message' => 'Method not allowed']); + exit; +} + +$id = (int) ($_POST['id'] ?? 0); +if (!$id) { + echo json_encode(['status' => 'error', 'message' => 'ID tidak valid']); + exit; +} + +$stmt = $conn->prepare("DELETE FROM data_jalan WHERE id = ?"); +$stmt->bind_param('i', $id); + +if ($stmt->execute() && $stmt->affected_rows > 0) { + echo json_encode(['status' => 'success', 'message' => 'Data jalan berhasil dihapus']); +} else { + echo json_encode(['status' => 'error', 'message' => 'Data tidak ditemukan atau gagal dihapus']); +} + +$stmt->close(); +$conn->close(); \ No newline at end of file diff --git a/01/api/jalan/simpan.php b/01/api/jalan/simpan.php new file mode 100644 index 0000000..d5d2083 --- /dev/null +++ b/01/api/jalan/simpan.php @@ -0,0 +1,56 @@ + 'error', 'message' => 'Method not allowed']); + exit; +} + +$nama = trim($_POST['nama_jalan'] ?? ''); +$status_jalan = trim($_POST['status_jalan'] ?? ''); +$geojson = trim($_POST['geojson'] ?? ''); +$panjang = (float) ($_POST['panjang_meter'] ?? 0); + +$allowed_status = ['Nasional', 'Provinsi', 'Kabupaten']; + +if (!$nama) { + echo json_encode(['status' => 'error', 'message' => 'Nama jalan tidak boleh kosong']); + exit; +} + +if (!in_array($status_jalan, $allowed_status)) { + echo json_encode(['status' => 'error', 'message' => 'Status jalan tidak valid']); + exit; +} + +// Validasi JSON +json_decode($geojson); +if (json_last_error() !== JSON_ERROR_NONE) { + echo json_encode(['status' => 'error', 'message' => 'Data geometri tidak valid']); + exit; +} + +$stmt = $conn->prepare("INSERT INTO data_jalan (nama_jalan, status_jalan, geojson, panjang_meter) VALUES (?, ?, ?, ?)"); +$stmt->bind_param('sssd', $nama, $status_jalan, $geojson, $panjang); + +if ($stmt->execute()) { + $id = $conn->insert_id; + echo json_encode([ + 'status' => 'success', + 'message' => 'Data jalan berhasil disimpan', + 'data' => [ + 'id' => $id, + 'nama_jalan' => $nama, + 'status_jalan' => $status_jalan, + 'geojson' => $geojson, + 'panjang_meter' => $panjang + ] + ]); +} else { + echo json_encode(['status' => 'error', 'message' => 'Gagal menyimpan: ' . $stmt->error]); +} + +$stmt->close(); +$conn->close(); \ No newline at end of file diff --git a/01/api/parsil/ambil.php b/01/api/parsil/ambil.php new file mode 100644 index 0000000..0fcef5d --- /dev/null +++ b/01/api/parsil/ambil.php @@ -0,0 +1,24 @@ +query("SELECT id, nama_parsil, status_kepemilikan, geojson, luas_m2 FROM data_parsil ORDER BY id DESC"); + +if (!$result) { + echo json_encode(['status' => 'error', 'message' => $conn->error]); + exit; +} + +$data = []; +while ($row = $result->fetch_assoc()) { + $data[] = $row; +} + +echo json_encode([ + 'status' => 'success', + 'total' => count($data), + 'data' => $data +]); + +$conn->close(); \ No newline at end of file diff --git a/01/api/parsil/hapus.php b/01/api/parsil/hapus.php new file mode 100644 index 0000000..2a6a540 --- /dev/null +++ b/01/api/parsil/hapus.php @@ -0,0 +1,27 @@ + 'error', 'message' => 'Method not allowed']); + exit; +} + +$id = (int) ($_POST['id'] ?? 0); +if (!$id) { + echo json_encode(['status' => 'error', 'message' => 'ID tidak valid']); + exit; +} + +$stmt = $conn->prepare("DELETE FROM data_parsil WHERE id = ?"); +$stmt->bind_param('i', $id); + +if ($stmt->execute() && $stmt->affected_rows > 0) { + echo json_encode(['status' => 'success', 'message' => 'Data parsil berhasil dihapus']); +} else { + echo json_encode(['status' => 'error', 'message' => 'Data tidak ditemukan atau gagal dihapus']); +} + +$stmt->close(); +$conn->close(); \ No newline at end of file diff --git a/01/api/parsil/simpan.php b/01/api/parsil/simpan.php new file mode 100644 index 0000000..a9341e8 --- /dev/null +++ b/01/api/parsil/simpan.php @@ -0,0 +1,55 @@ + 'error', 'message' => 'Method not allowed']); + exit; +} + +$nama = trim($_POST['nama_parsil'] ?? ''); +$status = trim($_POST['status_kepemilikan'] ?? ''); +$geojson = trim($_POST['geojson'] ?? ''); +$luas = (float) ($_POST['luas_m2'] ?? 0); + +$allowed_status = ['SHM', 'HGB', 'HGU', 'HP']; + +if (!$nama) { + echo json_encode(['status' => 'error', 'message' => 'Nama parsil tidak boleh kosong']); + exit; +} + +if (!in_array($status, $allowed_status)) { + echo json_encode(['status' => 'error', 'message' => 'Status kepemilikan tidak valid']); + exit; +} + +json_decode($geojson); +if (json_last_error() !== JSON_ERROR_NONE) { + echo json_encode(['status' => 'error', 'message' => 'Data geometri tidak valid']); + exit; +} + +$stmt = $conn->prepare("INSERT INTO data_parsil (nama_parsil, status_kepemilikan, geojson, luas_m2) VALUES (?, ?, ?, ?)"); +$stmt->bind_param('sssd', $nama, $status, $geojson, $luas); + +if ($stmt->execute()) { + $id = $conn->insert_id; + echo json_encode([ + 'status' => 'success', + 'message' => 'Data parsil berhasil disimpan', + 'data' => [ + 'id' => $id, + 'nama_parsil' => $nama, + 'status_kepemilikan' => $status, + 'geojson' => $geojson, + 'luas_m2' => $luas + ] + ]); +} else { + echo json_encode(['status' => 'error', 'message' => 'Gagal menyimpan: ' . $stmt->error]); +} + +$stmt->close(); +$conn->close(); \ No newline at end of file diff --git a/01/api/point/ambil.php b/01/api/point/ambil.php new file mode 100644 index 0000000..4bdabc6 --- /dev/null +++ b/01/api/point/ambil.php @@ -0,0 +1,24 @@ +query("SELECT id, nama_tempat, no_wa, buka_24jam, latitude, longitude FROM lokasi_usaha ORDER BY id DESC"); + +if (!$result) { + echo json_encode(['status' => 'error', 'message' => $conn->error]); + exit; +} + +$data = []; +while ($row = $result->fetch_assoc()) { + $data[] = $row; +} + +echo json_encode([ + 'status' => 'success', + 'total' => count($data), + 'data' => $data +]); + +$conn->close(); \ No newline at end of file diff --git a/01/api/point/hapus.php b/01/api/point/hapus.php new file mode 100644 index 0000000..014ecd0 --- /dev/null +++ b/01/api/point/hapus.php @@ -0,0 +1,27 @@ + 'error', 'message' => 'Method not allowed']); + exit; +} + +$id = (int) ($_POST['id'] ?? 0); +if (!$id) { + echo json_encode(['status' => 'error', 'message' => 'ID tidak valid']); + exit; +} + +$stmt = $conn->prepare("DELETE FROM lokasi_usaha WHERE id = ?"); +$stmt->bind_param('i', $id); + +if ($stmt->execute() && $stmt->affected_rows > 0) { + echo json_encode(['status' => 'success', 'message' => 'Data berhasil dihapus']); +} else { + echo json_encode(['status' => 'error', 'message' => 'Data tidak ditemukan atau gagal dihapus']); +} + +$stmt->close(); +$conn->close(); \ No newline at end of file diff --git a/01/api/point/simpan.php b/01/api/point/simpan.php new file mode 100644 index 0000000..6e4b787 --- /dev/null +++ b/01/api/point/simpan.php @@ -0,0 +1,44 @@ + 'error', 'message' => 'Method not allowed']); + exit; +} + +$nama = trim($_POST['nama_tempat'] ?? ''); +$wa = trim($_POST['no_wa'] ?? ''); +$buka24 = isset($_POST['buka_24jam']) ? (int) $_POST['buka_24jam'] : 0; +$lat = (float) ($_POST['latitude'] ?? 0); +$lng = (float) ($_POST['longitude'] ?? 0); + +if (!$nama) { + echo json_encode(['status' => 'error', 'message' => 'Nama tempat tidak boleh kosong']); + exit; +} + +$stmt = $conn->prepare("INSERT INTO lokasi_usaha (nama_tempat, no_wa, buka_24jam, latitude, longitude) VALUES (?, ?, ?, ?, ?)"); +$stmt->bind_param('ssidd', $nama, $wa, $buka24, $lat, $lng); + +if ($stmt->execute()) { + $id = $conn->insert_id; + echo json_encode([ + 'status' => 'success', + 'message' => 'Data berhasil disimpan', + 'data' => [ + 'id' => $id, + 'nama_tempat' => $nama, + 'no_wa' => $wa, + 'buka_24jam' => $buka24, + 'latitude' => $lat, + 'longitude' => $lng + ] + ]); +} else { + echo json_encode(['status' => 'error', 'message' => 'Gagal menyimpan: ' . $stmt->error]); +} + +$stmt->close(); +$conn->close(); \ No newline at end of file diff --git a/01/api/point/update_posisi.php b/01/api/point/update_posisi.php new file mode 100644 index 0000000..2e52b44 --- /dev/null +++ b/01/api/point/update_posisi.php @@ -0,0 +1,30 @@ + 'error', 'message' => 'Method not allowed']); + exit; +} + +$id = (int) ($_POST['id'] ?? 0); +$lat = (float) ($_POST['latitude'] ?? 0); +$lng = (float) ($_POST['longitude'] ?? 0); + +if (!$id) { + echo json_encode(['status' => 'error', 'message' => 'ID tidak valid']); + exit; +} + +$stmt = $conn->prepare("UPDATE lokasi_usaha SET latitude = ?, longitude = ? WHERE id = ?"); +$stmt->bind_param('ddi', $lat, $lng, $id); + +if ($stmt->execute() && $stmt->affected_rows > 0) { + echo json_encode(['status' => 'success', 'message' => 'Posisi diperbarui']); +} else { + echo json_encode(['status' => 'error', 'message' => 'Gagal memperbarui posisi']); +} + +$stmt->close(); +$conn->close(); \ No newline at end of file diff --git a/01/auth/helper.php b/01/auth/helper.php new file mode 100644 index 0000000..adcb987 --- /dev/null +++ b/01/auth/helper.php @@ -0,0 +1,20 @@ + 0, 'httponly' => true, 'samesite' => 'Strict']); + session_start(); + } +} + +function is_admin(): bool { + start_session(); + return !empty($_SESSION['admin_id']); +} + +function require_admin_json(): void { + if (!is_admin()) { + http_response_code(403); + echo json_encode(['status' => 'error', 'message' => 'Akses ditolak. Silahkan login terlebih dahulu.']); + exit; + } +} diff --git a/01/hapus.php b/01/hapus.php new file mode 100644 index 0000000..e4c07d6 --- /dev/null +++ b/01/hapus.php @@ -0,0 +1,44 @@ + 'error', 'message' => 'Metode tidak diizinkan.']); + exit; +} + +$idRaw = $_POST['id'] ?? null; + +if ($idRaw === null || !is_numeric($idRaw) || (int)$idRaw <= 0) { + http_response_code(400); + echo json_encode(['status' => 'error', 'message' => 'ID tidak valid.']); + exit; +} + +$id = (int)$idRaw; + +$stmt = $conn->prepare("DELETE FROM lokasi_usaha WHERE id = ?"); + +if (!$stmt) { + http_response_code(500); + echo json_encode(['status' => 'error', 'message' => 'Persiapan query gagal: ' . $conn->error]); + exit; +} + +$stmt->bind_param('i', $id); + +if ($stmt->execute()) { + if ($stmt->affected_rows > 0) { + echo json_encode(['status' => 'success', 'message' => 'Lokasi berhasil dihapus.']); + } else { + http_response_code(404); + echo json_encode(['status' => 'error', 'message' => 'Lokasi tidak ditemukan.']); + } +} else { + http_response_code(500); + echo json_encode(['status' => 'error', 'message' => $stmt->error]); +} + +$stmt->close(); +$conn->close(); diff --git a/01/index.html b/01/index.html index 4b60664..4e8a349 100644 --- a/01/index.html +++ b/01/index.html @@ -334,7 +334,7 @@ .radio-option input:checked+label { border-color: var(--c-accent); color: var(--c-accent-h); - background: rgba(46, 160, 67, .1); + background: rgba(13, 116, 144, .1); } .btn-save { @@ -591,7 +591,7 @@ width: 30px; height: 30px; border-radius: 8px; - background: rgba(248, 81, 73, .15); + background: rgba(239, 68, 68, .15); display: flex; align-items: center; justify-content: center; @@ -745,10 +745,10 @@