From 319a5c878f0b8eb2b741a929f88159aa481134f9 Mon Sep 17 00:00:00 2001 From: NelsonDavey17 Date: Fri, 12 Jun 2026 22:45:38 +0700 Subject: [PATCH] 2nd commit: Pemisahan halaman autentifikasi dengan halaman utama, modifikasi ikon, dan pemisahakan fitur berdasarkan role --- README.md | 184 ++++++++---------------- app.js | 105 ++++++-------- components/modals.php | 40 ++---- components/sidebar.php | 20 +-- index.php | 13 +- login.php | 91 ++++++++++++ otak_auth/api_register.php | 7 +- otak_auth/api_session.php | 2 +- otak_kemiskinan/api_hapus_anggota.php | 3 + otak_kemiskinan/api_hapus_ibadah.php | 3 + otak_kemiskinan/api_hapus_penduduk.php | 3 + otak_kemiskinan/api_simpan_penduduk.php | 3 + otak_spbu/api_hapus_spbu.php | 3 + otak_spbu/api_simpan_spbu.php | 3 + style.css | 4 +- 15 files changed, 248 insertions(+), 236 deletions(-) create mode 100644 login.php diff --git a/README.md b/README.md index eada998..33a90c7 100644 --- a/README.md +++ b/README.md @@ -1,117 +1,67 @@ -# πŸ—ΊοΈ WebGIS Pemetaan Kemiskinan dan Distribusi Bantuan (Kota Pontianak) +# πŸ—ΊοΈ WebGIS-Pontianak (Pemetaan Kemiskinan & Tata Ruang) -Sebuah Sistem Informasi Geografis (*Geographic Information System / GIS*) berbasis web yang dirancang dengan arsitektur *Single Page Application (SPA)* untuk: +Sebuah Sistem Informasi Geografis (*Geographic Information System / GIS*) komprehensif berbasis web yang dirancang untuk memetakan infrastruktur kota dan demografi sosial, dengan fokus utama pada pemetaan kemiskinan dan distribusi bantuan di Pontianak. -* Memetakan demografi kemiskinan -* Mengkalkulasi kelayakan bantuan secara otomatis -* Mengelola respons darurat musibah -* Memfasilitasi pendataan talenta untuk pemberdayaan warga - -Sistem ini dibangun dengan kontrol otorisasi tingkat lanjut (*Role-Based Access Control / RBAC* & *Geofencing*) serta menggunakan algoritma *Sistem Pendukung Keputusan (SPK)* terintegrasi. +Sistem ini dikembangkan dengan arsitektur **Multi-Page Application** tersinkronisasi dan dilindungi oleh kontrol akses berbasis peran (*Role-Based Access Control / RBAC*) tingkat lanjut. --- ## ✨ Fitur Utama (Core Features) -### πŸ” Gatekeeper Authentication +### πŸ” Keamanan & Autentikasi Berlapis +- **Halaman Login Terisolasi:** Autentikasi dipisah sepenuhnya dari halaman utama peta (`login.php`) untuk mencegah kebocoran *resource* ke klien yang tidak sah. +- **Proteksi Kata Sandi BCRYPT:** Standar keamanan industri, divalidasi minimal 8 karakter baik di sisi klien (*frontend*) maupun server (*backend*). +- **Role-Based Access Control (RBAC):** Pemisahan hak akses ketat antara *Admin* (hak penuh) dan *User* biasa (hanya-baca & lapor musibah). +- **Server-side Gatekeeper:** Validasi *Session* ketat berbasis PHP di setiap akses masuk API maupun perlindungan pengalihan instan (*instant redirection*) di halaman utama. +- **Stylish Notification:** Notifikasi *pop-up* responsif berbasis SweetAlert2 untuk menyambut identitas pengguna. -* Sistem layar kunci persisten -* Enkripsi kata sandi menggunakan standar *BCRYPT* -* Validasi sesi berbasis API (*Anti Client-Side Amnesia*) +### πŸ—ΊοΈ Pemetaan Spasial Multi-Layer +- **Leaflet.js Interaktif:** Peta dinamis dengan *FontAwesome Icon* premium untuk visualisasi marker. +- **Peta Aset Beragam:** Menampilkan visualisasi tumpang tindih untuk *Polyline* (Jaringan Jalan), *Polygon* (Parsil Tanah), dan *Marker* (SPBU & Rumah Ibadah). +- **Z-Index & Event Handling Terkelola:** Penempatan *interactive: false* pada radius wewenang rumah ibadah agar tidak menutupi klik (pointer events) dari poligon jalan dan tanah di bawahnya. +- **Reverse Geocoding:** Pelacakan koordinat GPS *real-time* terintegrasi Nominatim API. -### πŸ—ΊοΈ Pemetaan Spasial & Geofencing +### πŸ“Š Algoritma SPK Kemiskinan & Kesejahteraan +Sistem penentuan status keluarga (Sangat Miskin, Miskin, Rentan) yang dikalkulasi secara terpusat berdasarkan parameter *Garis Kemiskinan* dinamis. Modul ini menyertakan *Smart Autofill* untuk merekomendasikan jumlah logistik. -* Visualisasi interaktif menggunakan *Leaflet.js* -* Penentuan radius wewenang operasional -* *Reverse Geocoding* via *Nominatim API* - -### πŸ“Š SPK Kemiskinan Otomatis - -* Klasifikasi tingkat kemiskinan: - - * Sangat Miskin - * Miskin - * Rentan -* Menggunakan: - - * Garis Kemiskinan Regional - * *Proxy Means Testing (PMT)* - -### πŸ“¦ Distribusi Bantuan Cerdas (Smart Autofill) - -* Rekomendasi logistik berbasis status kemiskinan -* Perhitungan proporsional (*pro-rata*) - -### 🚨 Manajemen Krisis (Visual Alert) - -* Peringatan dini berbasis geospasial -* Animasi visual (kelap-kelip merah) untuk lokasi darurat - -### πŸ”„ Resolusi Musibah Otomatis (Auto-Resolve) - -* Menggunakan *Database Transactions* -* Status darurat otomatis selesai setelah bantuan disalurkan - -### 🎯 Filter Pelatihan Algoritmik - -* Seleksi otomatis kandidat pelatihan berdasarkan: - - * Usia produktif - * Tingkat pendidikan - * Status pengangguran +### 🚨 Manajemen Bantuan & Krisis Darurat +- Pemantauan rumah tangga yang berada di dalam maupun luar radius cakupan wewenang rumah ibadah. +- Peringatan darurat musibah dengan efek kelap-kelip visual pada marker (*SOS Blink*). +- Pencatatan riwayat distribusi bantuan dengan hak visibilitas CRUD yang otomatis disembunyikan dari antarmuka User biasa demi mencegah manipulasi data. --- ## πŸ› οΈ Stack Teknologi (Tech Stack) ### Frontend - -* HTML5 & CSS3 (*Native*) -* JavaScript (*ES6+ / Vanilla JS*) -* *Leaflet.js* -* *Fetch API* +* **UI/UX:** HTML5, CSS3 Murni (Custom RBAC rules, Smooth Animations, Glassmorphism), SweetAlert2 +* **Peta Geospasial:** Leaflet.js +* **Logika Aplikasi:** Vanilla JavaScript (ES6+), Fetch API ### Backend - -* PHP 8.x (API & Session Handling) -* PDO (*PHP Data Objects*) -* MySQL / MariaDB +* **Logika Server & Sesi:** PHP 8.x (*Stateful Session Management*) +* **Jembatan Database:** PDO (*PHP Data Objects*) dengan arsitektur *Prepared Statements* +* **Database Relasional:** MySQL / MariaDB --- -## βš™οΈ Persyaratan Sistem (Prerequisites) - -Untuk menjalankan proyek ini secara lokal: - -* Web Server (*XAMPP / MAMP / Laragon*) -* PHP β‰₯ 7.4 (disarankan 8.x) -* MySQL / MariaDB -* Koneksi internet (untuk OpenStreetMap & Nominatim API) - ---- - -## πŸš€ Panduan Instalasi (Installation Guide) - -### 1. Clone Repositori +## πŸš€ Panduan Instalasi Lokal +### 1. Kloning Repositori ```bash -git clone https://github.com/ChronosSilver/WebGis-SIG-UAS.git +git clone https://github.com/ChronosSilver/SIG-Poverty-Mapping.git ``` -### 2. Konfigurasi Database - -* Buka: `http://localhost/phpmyadmin` -* Buat database: - - ``` - webgis_kemiskinan - ``` -* Import file `.sql` dari repositori - -### 3. Konfigurasi Koneksi PHP - -Edit file `koneksi.php`: +### 2. Persiapan Database +1. Buka *control panel* MySQL Anda (`http://localhost/phpmyadmin`) +2. Buat database kosong baru dengan nama: + ``` + webgis_pontianak + ``` +3. Import file cadangan `.sql` yang disertakan di repositori ini ke dalam database tersebut. +### 3. Konfigurasi Sistem +Sistem ini menggunakan parameter *default* localhost (contoh: XAMPP). Jika *password* MySQL Anda kosong, tidak ada yang perlu diedit. Sesuaikan pengaturan ini di dalam file `koneksi.php`: ```php $host = "localhost"; $user = "root"; @@ -119,52 +69,34 @@ $pass = ""; $dbname = "webgis_pontianak"; ``` -### 4. Jalankan Aplikasi - -Akses melalui browser: - +### 4. Eksekusi WebGIS +Akses direktori proyek melalui browser pilihan Anda: ``` -http://localhost/004(fin)/ +http://localhost/SIG1/webgis/Poverty_Mapping/ ``` --- -## πŸ”’ Akses Pengujian (Dummy Credentials) - -Gunakan akun berikut: - +## πŸ“‚ Struktur Direktori Terbaru ``` -Username: admin -Password: admin -``` - -> Anda juga dapat membuat akun baru melalui fitur registrasi. - ---- - -## πŸ“‚ Struktur Direktori - -``` -πŸ“¦ root-directory - ┣ πŸ“‚ components # UI modular (Sidebar, Modal) - ┣ πŸ“‚ otak_auth # API autentikasi - ┣ πŸ“‚ otak_kemiskinan # CRUD & SPK warga - ┣ πŸ“‚ otak_jalan # Data Polyline - ┣ πŸ“‚ otak_tanah # Data Polygon - ┣ πŸ“‚ otak_spbu # Data SPBU - ┣ πŸ“œ app.js # Logika utama sistem - ┣ πŸ“œ style.css # UI & animasi - ┣ πŸ“œ koneksi.php # Koneksi database - β”— πŸ“œ index.php # Entry point +πŸ“¦ Poverty_Mapping + ┣ πŸ“‚ components # Kerangka antarmuka modular (Sidebar, Modal Template) + ┣ πŸ“‚ otak_auth # API gerbang keamanan & manajer sesi PHP + ┣ πŸ“‚ otak_kemiskinan # Endpoint CRUD penduduk, bantuan & laporan musibah + ┣ πŸ“‚ otak_jalan # Endpoint spasial penyimpan Polyline Jalan + ┣ πŸ“‚ otak_tanah # Endpoint spasial penyimpan Polygon Parsil Tanah + ┣ πŸ“‚ otak_spbu # Endpoint penampung data POI SPBU + ┣ πŸ“œ app.js # Otak logika SPA Frontend & Leaflet Rendering + ┣ πŸ“œ style.css # Desain tema global & Filter Visibilitas RBAC + ┣ πŸ“œ koneksi.php # Jembatan asinkron ke MySQL PDO + ┣ πŸ“œ login.php # Lobi isolasi layar kunci (Gatekeeper Entry) + β”— πŸ“œ index.php # Kanvas Peta Utama WebGIS (Terproteksi Sesi) ``` --- -## πŸ“ Lisensi +## πŸ“ Pengembang & Lisensi +Sistem Informasi Geografis (*SIG*) berbasis web ini merupakan purwarupa penelitian/tugas akhir yang secara kontinu berevolusi dari tahun ke tahun. +**Hak Cipta (2026) oleh Nelson Davey (NIM: D1041231058) - Universitas Tanjungpura**. -Proyek ini dikembangkan sebagai bagian dari penelitian akademik / tugas perkuliahan -Universitas Tanjungpura (2026) oleh Nelson Davey (D1041231058). - -Segala bentuk distribusi dan modifikasi mengikuti kebijakan hak cipta yang berlaku. - ---- \ No newline at end of file +Mendukung prinsip kode aman dengan akses terotentikasi berlapis. Segala bentuk salinan, distribusi, dan modifikasi harus mencantumkan sumber orisinalitas serta mengikuti kebijakan akademik yang berlaku. \ No newline at end of file diff --git a/app.js b/app.js index 3b5b935..e06e5bf 100644 --- a/app.js +++ b/app.js @@ -22,7 +22,7 @@ const state = { // KUNCI AUTENTIKASI user: null, - authMode: 'login' // 'login' atau 'register' + }; const dataStore = { @@ -160,46 +160,6 @@ function triggerToastNotification(pesan) { // ==================================================== // AUTENTIKASI: GATEKEEPER & SINKRONISASI SESI // ==================================================== -window.switchAuthTab = (mode) => { - state.authMode = mode; - - document.getElementById('tab-login').classList.toggle('active', mode === 'login'); - document.getElementById('tab-register').classList.toggle('active', mode === 'register'); - - document.getElementById('btn-submit-auth').innerText = mode === 'login' ? 'Login Sistem' : 'Daftar Akun Baru'; - document.getElementById('auth-error-msg').innerText = ''; -}; - -window.eksekusiAuth = () => { - const user = document.getElementById('auth-username').value; - const pass = document.getElementById('auth-password').value; - const errMsg = document.getElementById('auth-error-msg'); - - if(!user || !pass) { - errMsg.innerText = "Username dan Password tidak boleh kosong!"; - return; - } - - errMsg.innerText = "Memproses request ke server..."; - - const endpoint = state.authMode === 'login' ? 'otak_auth/api_login.php' : 'otak_auth/api_register.php'; - - safeFetch(endpoint, { username: user, password: pass }) - .then(res => { - if(state.authMode === 'register') { - triggerToastNotification(res.pesan); - switchAuthTab('login'); - } else { - state.user = res.user; - document.getElementById('auth-screen').style.display = 'none'; - triggerToastNotification(`Selamat datang, ${res.user}!`); - muatDataSemua(); // Booting peta dilanjutkan - } - }) - .catch(err => { - errMsg.innerText = err.message; - }); -}; window.eksekusiLogout = () => { if(!confirm("Anda yakin ingin keluar dari sistem?")) return; @@ -207,7 +167,7 @@ window.eksekusiLogout = () => { safeFetch('otak_auth/api_logout.php') .then(res => { state.user = null; - document.getElementById('auth-screen').style.display = 'flex'; + window.location.href = 'login.php'; document.getElementById('auth-username').value = ''; document.getElementById('auth-password').value = ''; triggerToastNotification("Sesi diakhiri secara aman."); @@ -227,12 +187,30 @@ const cekSesiBackend = () => { safeFetch('otak_auth/api_session.php') .then(res => { state.user = res.username; - document.getElementById('auth-screen').style.display = 'none'; + window.USER_ROLE = res.role; + if(window.USER_ROLE !== 'admin') { + document.body.classList.add('role-user'); + } else { + if(typeof RightToolbar !== 'undefined') map.addControl(new RightToolbar()); + } + if (sessionStorage.getItem('just_logged_in') === 'true') { + Swal.fire({ + title: 'Login Berhasil!', + html: `Selamat ${res.username} masuk ke WebGIS-Pontianak sebagai ${res.role.toUpperCase()}`, + icon: 'success', + timer: 3000, + showConfirmButton: false, + toast: true, + position: 'top-end' + }); + sessionStorage.removeItem('just_logged_in'); + } + muatDataSemua(); }) .catch(err => { console.log("Tertahan di gerbang autentikasi: " + err.message); - document.getElementById('auth-screen').style.display = 'flex'; + window.location.href = 'login.php'; }); }; @@ -440,15 +418,15 @@ const RightToolbar = L.Control.extend({ onAdd: function() { const c = L.DomUtil.create('div', 'custom-leaflet-toolbar'); c.innerHTML = ` - - - + + + `; L.DomEvent.disableClickPropagation(c); return c; } }); -map.addControl(new RightToolbar()); + // ==================================================== // EVENT LISTENER ROUTER (KLIK PETA UTAMA) @@ -495,7 +473,7 @@ map.on('click', async function(e) { if(alamatInput) alamatInput.value = "Sedang melacak alamat dari satelit..."; document.getElementById('spbu-action-wrapper').innerHTML = ` - + `; document.getElementById('modal-spbu').style.display = 'flex'; @@ -702,8 +680,8 @@ function renderSPBU() { document.getElementById('spbu-modal-title').innerText = "Detail & Kelola SPBU"; document.getElementById('spbu-action-wrapper').innerHTML = ` - - + + `; document.getElementById('modal-spbu').style.display = 'flex'; @@ -904,7 +882,8 @@ function renderKemiskinan() { fillColor: '#D69E2E', fillOpacity: 0.15, radius: d.radius_meter, - weight: 1 + weight: 1, + interactive: false }).addTo(map); mapLayers.radiusIbadah[d.id] = circle; @@ -1175,7 +1154,7 @@ window.selesaiGambarJalan = function() { bukaGembokForm('jalan'); document.getElementById('jalan-action-wrapper').innerHTML = ` - + `; @@ -1211,8 +1190,8 @@ window.handleRoadClick = function(id) { document.getElementById('jalan-modal-title').innerText = "Detail & Kelola Jalan"; document.getElementById('jalan-action-wrapper').innerHTML = ` - - + + `; @@ -1241,7 +1220,7 @@ window.selesaiGambarTanah = function() { bukaGembokForm('tanah'); document.getElementById('tanah-action-wrapper').innerHTML = ` - + `; @@ -1277,8 +1256,8 @@ window.handleLandClick = function(id) { document.getElementById('tanah-modal-title').innerText = "Detail & Kelola Tanah"; document.getElementById('tanah-action-wrapper').innerHTML = ` - - + + `; @@ -1825,7 +1804,7 @@ window.muatDaftarAnggota = (idPenduduk, isBernaung) => { pelatihanHtml = `
- +
`; } else { @@ -1841,8 +1820,8 @@ window.muatDaftarAnggota = (idPenduduk, isBernaung) => { ${m.pekerjaan || 'Menganggur'} ${pelatihanHtml} - - + + `; @@ -1866,7 +1845,7 @@ window.resetFormAnggota = () => { const btnContainer = document.getElementById('anggota-pekerjaan').parentElement.nextElementSibling; if(btnContainer) { - btnContainer.innerHTML = ``; + btnContainer.innerHTML = ``; } }; @@ -1883,7 +1862,7 @@ window.bukaFormEditAnggota = (id, nik, nama, lahir, pendidikan, pekerjaan) => { const btnContainer = document.getElementById('anggota-pekerjaan').parentElement.nextElementSibling; if(btnContainer) { btnContainer.innerHTML = ` - + `; } diff --git a/components/modals.php b/components/modals.php index fbecf56..444ef22 100644 --- a/components/modals.php +++ b/components/modals.php @@ -389,7 +389,7 @@
- +
@@ -401,8 +401,8 @@
- - + +
@@ -424,8 +424,8 @@
- - + +
@@ -600,8 +600,8 @@ -

Tambah Anggota Baru

-
+

Tambah Anggota Baru

+
@@ -661,31 +661,7 @@
-
-
-

WebGIS Pontianak

- - -
- - -
- - -
- - -
-
- - -
- - - -

-
-
+ \ No newline at end of file diff --git a/components/sidebar.php b/components/sidebar.php index 190e8ed..31a7a30 100644 --- a/components/sidebar.php +++ b/components/sidebar.php @@ -7,7 +7,7 @@