commit 3da59f80dab41774bdf0b4fad9e7749c4e24216f Author: unknown Date: Wed Jun 10 23:21:21 2026 +0700 fix : dockerfile diff --git a/01/.gitignore b/01/.gitignore new file mode 100644 index 0000000..03966d8 --- /dev/null +++ b/01/.gitignore @@ -0,0 +1,17 @@ +# Development files +.vscode/ +.idea/ + +# Local XAMPP/PHP Server files +error_log +access_log +*.log + +# Environment specific configuration +# (Note: we leave koneksi.php tracked for this template, +# but usually it should be ignored in a real production repo) +# php/koneksi.php + +# OS generated files +.DS_Store +Thumbs.db diff --git a/01/QUICK_START.md b/01/QUICK_START.md new file mode 100644 index 0000000..99ca834 --- /dev/null +++ b/01/QUICK_START.md @@ -0,0 +1,193 @@ +# ⚡ QUICK START - Mulai Cepat dalam 5 Menit + +## 🎯 Langkah 1: Ekstrak & Tempatkan File + +1. **Extract ZIP** ke folder web Anda: + - Windows: `C:\xampp\htdocs\pemetaan-kemiskinan` + - Linux: `/var/www/html/pemetaan-kemiskinan` + +2. **Pastikan XAMPP/Web Server JALAN** + - Buka XAMPP Control Panel + - Klik **"Start"** untuk Apache + - Klik **"Start"** untuk MySQL + +--- + +## 🎯 Langkah 2: Setup Database (3 Langkah Mudah) + +### Cara A: Menggunakan phpMyAdmin (PALING MUDAH) + +1. **Buka browser** → ketik: `http://localhost/phpmyadmin` +2. **Klik menu "Import"** di bagian atas +3. **Klik "Choose File"** → pilih file `database.sql` dari folder pemetaan-kemiskinan +4. **Klik tombol "Import"** → SELESAI ✅ + +Tunggu 5-10 detik, database akan terbuat otomatis dengan semua tabel yang diperlukan. + +### Cara B: Manual (Jika Cara A tidak berhasil) + +1. Buka phpMyAdmin → `http://localhost/phpmyadmin` +2. Di sebelah kiri, cari **"Create new database"** +3. Ketik nama: `pemetaan_kemiskinan` +4. Klik **"Create"** +5. Pilih database yang baru dibuat +6. Klik tab **"SQL"** +7. Copy-paste semua kode dari file `database.sql` +8. Klik **"Go"** + +--- + +## 🎯 Langkah 3: Verifikasi Koneksi + +1. **Buka file**: `php/koneksi.php` +2. **Periksa konfigurasi** (biasanya tidak perlu diubah): + ```php + $host = "localhost"; + $username = "root"; + $password = ""; // Kosongkan jika XAMPP default + $database = "pemetaan_kemiskinan"; + ``` +3. **Jika ada password MySQL**, ubah baris: + ```php + $password = "password_anda_di_sini"; + ``` + +--- + +## 🎯 Langkah 4: Buka Aplikasi + +**Buka browser dan ketik:** +``` +http://localhost/pemetaan-kemiskinan/ +``` + +✅ **SELESAI! Aplikasi siap digunakan!** + +--- + +## 🎮 Test Aplikasi + +### Test Input Masyarakat Miskin: + +1. Map akan muncul dengan area Pontianak +2. Klik tombol di sidebar → Tab "Masyarakat" +3. **Klik di peta** untuk set koordinat lokasi +4. Isi form dengan data: + ``` + Nama: Siti Nur Azizah + Tanggal Lahir: 1985-03-15 + Jenis Kelamin: Perempuan + Alamat: Jl. Mahakam No. 25 + Kelurahan: Sungai Jawi + Kecamatan: Pontianak Kota + No HP: 081234567890 + Status BPJS: Ya + (Koordinat sudah otomatis dari klik peta) + ``` +5. Klik **"Simpan Data"** → Data berhasil disimpan ✅ +6. Lihat marker merah di peta, dan nama muncul di sidebar list + +### Test Input Rumah Ibadah: + +1. Klik tab **"Rumah Ibadah"** di sidebar +2. **Klik di peta** untuk koordinat +3. Isi form: + ``` + Nama: Masjid Al-Hidayah + Jenis: Masjid + Alamat: Jl. Diponegoro No. 45 + Nama Pemimpin: Ustaz Ahmad + ``` +4. Klik **"Simpan Data"** → Marker hijau muncul ✅ + +--- + +## 📱 Interface Penjelasan + +``` +┌─────────────────────────────────────────┐ +│ SIDEBAR (300px) │ MAP (Sisa) │ +│ │ │ +│ 📍 Pemetaan Kemiskinan │ Marker Merah │ +│ [Masyarakat] [Ibadah] │ Masyarakat │ +│ │ │ +│ [Search Box] │ Marker Hijau │ +│ [Filter Dropdown] │ Rumah Ibadah │ +│ │ │ +│ - Nama 1 │ │ +│ - Nama 2 │ Klik di peta │ +│ - Nama 3 │ = Set Koordinat +│ │ │ +│ [Tombol Hapus] │ Klik Marker │ +│ │ = Lihat Detail +└─────────────────────────────────────────┘ +``` + +--- + +## ❓ FAQ + +**Q: Koordinat tidak ketangkap saat klik peta?** +A: Pastikan modal form sudah terbuka (berwarna putih). Klik dulu field nama atau di peta, baru akan bisa set koordinat otomatis. + +**Q: Data tidak tampil di peta?** +A: Cek browser console (F12), atau pastikan latitude longitude valid (antara -90 hingga 90 untuk lat, -180 hingga 180 untuk lng). + +**Q: Database tidak terbuat?** +A: Cek di phpMyAdmin apakah database `pemetaan_kemiskinan` sudah ada. Jika belum, buat manual atau coba import ulang file `database.sql`. + +**Q: Error "Access denied" saat jalankan?** +A: Password MySQL tidak cocok. Edit file `php/koneksi.php` dan ubah password sesuai konfigurasi MySQL Anda. + +**Q: Peta tidak muncul?** +A: Periksa koneksi internet (butuh untuk CDN Leaflet & OpenStreetMap). Atau cek browser console untuk error. + +--- + +## 🔧 Struktur File Penting + +``` +pemetaan-kemiskinan/ +├── index.html ← Buka file ini di browser +├── database.sql ← File untuk import database +├── config.php ← Konfigurasi umum +├── php/ +│ ├── koneksi.php ← EDIT INI jika ada password MySQL +│ ├── simpan_masyarakat.php +│ ├── simpan_rumah_ibadah.php +│ ├── ambil_data_masyarakat.php +│ └── ... +├── js/ +│ └── main.js ← Logic aplikasi +└── docs/ + └── PANDUAN_PHPMY_ADMIN.md ← Dokumentasi detail +``` + +--- + +## 📞 Jika Ada Masalah + +1. **Cek Browser Console** (Tekan F12): + - Lihat tab "Console" + - Ada error merah? Catat error message-nya + - Refresh halaman (Ctrl+F5) + +2. **Cek phpMyAdmin**: + - Database ada? + - Tabel ada? (masyarakat_miskin, rumah_ibadah, dll) + - Ada data sample? + +3. **Cek File koneksi.php**: + - Username & password MySQL cocok? + - Nama database benar? (`pemetaan_kemiskinan`) + +4. **Restart Web Server**: + - Tutup XAMPP + - Buka kembali XAMPP + - Start Apache & MySQL + +--- + +**✅ Selesai! Nikmati aplikasi pemetaan kemiskinan Anda!** + +*Untuk dokumentasi lengkap, baca file `README.md`* diff --git a/01/README.md b/01/README.md new file mode 100644 index 0000000..6c52df3 --- /dev/null +++ b/01/README.md @@ -0,0 +1,64 @@ +# WebGIS Poverty Mapping - Pontianak + +Sistem Informasi Geografis (GIS) Terpadu untuk pemetaan kemiskinan, fasilitas tata kota, dan pelaporan masyarakat di Kota Pontianak. Dibangun dengan HTML, CSS, JavaScript (Leaflet.js), dan PHP (MySQL). + +## 🚀 Fitur Utama +1. **Fasilitas & Tata Kota**: Pemetaan jalan raya (Polyline), batas area taman/perumahan (Polygon), dan titik lokasi SPBU (Marker). +2. **Sosial & Kemasyarakatan**: Pemetaan data warga miskin dengan detail bantuan, status BPJS, serta pemetaan lokasi rumah ibadah. +3. **Portal Publik (Read-Only Mode)**: Akses bagi warga untuk melihat data fasilitas terdekat tanpa kemampuan merubah atau menghapus data. + +## 🛠️ Persiapan Lingkungan Lokal (Local Development) + +### Syarat Sistem +- XAMPP (Apache & MySQL) +- PHP 7.4 atau lebih baru (Rekomendasi PHP 8+) + +### Langkah Instalasi +1. Nyalakan modul **Apache** dan **MySQL** di XAMPP Control Panel Anda. +2. Buka `phpMyAdmin` (`http://localhost/phpmyadmin`). +3. Buat database baru bernama `pemetaan_kemiskinan`. +4. Import file `database.sql` yang ada di direktori utama ke dalam database tersebut. File ini sudah berisi skema tabel dan beberapa *dummy data* (titik awal). +5. Akses portal di `http://localhost/web_miskin/01` (sesuaikan port jika diperlukan). + +## 📤 Git Push & Kolaborasi + +Proyek ini telah dilengkapi dengan `.gitignore`. +Untuk mengunggah kode ke GitHub/GitLab: + +```bash +git init +git add . +git commit -m "Initial commit WebGIS" +git branch -M main +git remote add origin https://github.com/username-anda/repo-anda.git +git push -u origin main +``` + +## 🌐 Panduan Deployment (cPanel Hosting) + +Untuk mendeploy proyek ini ke internet (contoh menggunakan Niagahoster, Hostinger, atau cPanel standar): + +1. **Siapkan Database di Server** + - Masuk ke cPanel hosting Anda, buka menu **MySQL Databases**. + - Buat database baru (contoh: `u12345_pemetaan`). + - Buat user database baru dan hubungkan user tersebut ke database dengan semua hak akses (*All Privileges*). + - Buka **phpMyAdmin** dari cPanel, pilih database baru Anda, lalu menu **Import**. + - Unggah file `database.sql` dari komputer Anda. + +2. **Upload File Web** + - Di cPanel, buka **File Manager** -> masuk ke direktori `public_html`. + - Jika Anda memiliki banyak project, buat folder baru (misal `webgis`). Jika ini aplikasi utama, biarkan di root `public_html`. + - *Zip* seluruh isi folder `01` dari PC Anda (jangan Zip folder `01`-nya, tapi isi di dalamnya: `index.html`, `dashboard.html`, folder `css`, `js`, `php`). + - Upload file *Zip* tersebut ke File Manager dan klik *Extract*. + +3. **Konfigurasi Koneksi PHP** + - Cari dan edit file `php/koneksi.php` yang sudah di-*upload*. + - Sesuaikan bagian ini dengan kredensial dari cPanel Anda: + ```php + $host = "localhost"; + $username = "u12345_userdb"; // User dari cPanel + $password = "PasswordKuat123!"; // Password user DB + $database = "u12345_pemetaan"; // Nama DB dari cPanel + ``` + +Selesai! Aplikasi WebGIS Anda sekarang sudah online. diff --git a/01/codeanalysis/codeanalyisis.md b/01/codeanalysis/codeanalyisis.md new file mode 100644 index 0000000..ff17b4c --- /dev/null +++ b/01/codeanalysis/codeanalyisis.md @@ -0,0 +1,47 @@ +# Analisis Kode: Sistem Pemetaan Kemiskinan + +Proyek ini adalah aplikasi web bernama **Sistem Pemetaan Kemiskinan** yang digunakan untuk memetakan lokasi masyarakat miskin dan rumah ibadah di suatu wilayah (secara bawaan diset ke daerah Pontianak). Aplikasi ini dibangun dengan menggunakan arsitektur *client-server* sederhana yang memisahkan sisi tampilan (frontend) dan sisi server (backend). + +## Struktur Direktori dan File + +Berikut adalah hasil analisis berdasarkan penataan folder dan file yang ada di dalam proyek ini: + +### 1. Root Direktori (`/01/`) +Direktori utama ini menyimpan file-file inti, konfigurasi, dokumentasi, dan titik masuk aplikasi (*entry point*). +- **`index.html`**: File utama antarmuka pengguna. Memuat kerangka HTML, tata letak sidebar, kontainer peta, gaya desain CSS internal, dan kerangka *form modal* untuk menambahkan data. File ini juga mengintegrasikan pustaka eksternal **Leaflet.js** untuk merender peta interaktif. +- **`config.php`**: File konfigurasi utama di sisi server. Berisi definisi konstanta penting seperti konfigurasi database MySQL, pengaturan awal tampilan peta (*latitude*, *longitude*, *zoom level*), serta lingkungan aplikasi (*development*). +- **`database.sql`**: File skrip SQL yang memuat skema struktur database, berisi tabel `masyarakat_miskin`, `rumah_ibadah`, `bantuan_riwayat`, `bpjs_record`, dan tabel `users` untuk sistem login. Terdapat juga beberapa data sampel (*dummy*) untuk keperluan testing. +- **`README.md` & `QUICK_START.md`**: Dokumentasi proyek yang menjelaskan instruksi instalasi, penggunaan aplikasi, serta fitur-fiturnya. +- **`{php,js,css,icons,docs}`**: Folder kosong yang sepertinya terbuat karena ketidaksengajaan (*typo* pada *command-line* saat membuat *multiple directories* sekaligus). + +### 2. Folder `js/` (Logika Frontend / Interaksi) +Folder ini menangani segala logika yang berjalan di sisi *browser* (klien). +- **`main.js`**: Skrip JavaScript tunggal yang mengontrol aplikasi. Bertanggung jawab atas: + - Menginisialisasi peta dari `index.html`. + - Mengambil data spasial dari backend menggunakan *Fetch API* secara asinkron (*AJAX*). + - Meletakkan *marker* (titik lokasi) untuk masyarakat miskin dan rumah ibadah di peta. + - Memproses pencarian (*search*) dan filter di bagian sidebar. + - Menangani aksi pengiriman form, tombol klik, serta memberikan *feedback* sukses/error kepada pengguna (*alert*). + +### 3. Folder `php/` (Logika Backend / API) +Berisi sekumpulan skrip PHP yang berfungsi sebagai perantara antara antarmuka pengguna dan *database*. Endpoint ini menerima input dan mengembalikan format **JSON**. +- **`koneksi.php`**: Pusat koneksi database menggunakan `mysqli`. Menangani perizinan *CORS Headers* agar API bisa diakses dari frontend dan mengatur proteksi anti-XSS melalui fungsi *sanitasi input*. +- **Endpoint Pengambilan Data (`ambil_*.php`)**: + - `ambil_data_masyarakat.php` & `ambil_rumah_ibadah.php`: Merespons permintaan dengan daftar titik-titik lokasi dari tabel terkait di database. + - `ambil_detail.php`: Menampilkan data terperinci masyarakat miskin, mencakup data BPJS dan riwayat bantuan. +- **Endpoint Penyimpanan Data (`simpan_*.php`)**: + - `simpan_masyarakat.php`, `simpan_rumah_ibadah.php`: Mengamankan data yang masuk dari POST *Request* form, memvalidasi dan memasukkannya ke database. Terdapat file lain seperti `simpan_bantuan.php` dan `simpan_bpjs.php` untuk relasi tabel sekunder. +- **`hapus_data.php`**: Endpoint untuk menghapus data berdasarkan ID. + +### 4. Folder `codeanalysis/` +- **`codeanalyisis.md`**: File dokumen *Markdown* tempat tersimpannya hasil analisis kode yang menguraikan arsitektur dan struktur proyek ini. + +### 5. Folder `docs/` +- **`PANDUAN_PHPMY_ADMIN.md`**: Dokumen petunjuk teknis sekunder terkait pengelolaan basis data menggunakan *phpMyAdmin*. + +--- + +## Kesimpulan Arsitektur Sistem +Proyek ini mengadopsi pola perancangan **API-driven (Vanilla)**. +1. **Frontend** dibuat reaktif tanpa membebani server, di mana `index.html` dan `main.js` merender visual serta mengirimkan permintaan *asinkron*. +2. **Backend (PHP)** bertindak hanya sebagai API pengelola data yang merespons dalam format JSON (bukan sebagai perender HTML). Hal ini membuat kode lebih terisolasi, bersih (*clean code*), dan mudah dirawat ke depannya. diff --git a/01/config.php b/01/config.php new file mode 100644 index 0000000..1a8caad --- /dev/null +++ b/01/config.php @@ -0,0 +1,36 @@ + diff --git a/01/dashboard.html b/01/dashboard.html new file mode 100644 index 0000000..7a8ab88 --- /dev/null +++ b/01/dashboard.html @@ -0,0 +1,865 @@ + + + + + + Sistem Pemetaan Kemiskinan + + + + + + + + + + + + + + + + +
+ + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + diff --git a/01/database.sql b/01/database.sql new file mode 100644 index 0000000..031888d --- /dev/null +++ b/01/database.sql @@ -0,0 +1,166 @@ +-- ============================================ +-- DATABASE: pemetaan_kemiskinan +-- DIBUAT UNTUK: Sistem Pemetaan Kemiskinan +-- ============================================ + +-- CREATE DATABASE +CREATE DATABASE IF NOT EXISTS `pemetaan_kemiskinan` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; +USE `pemetaan_kemiskinan`; + +-- ============================================ +-- TABLE 1: masyarakat_miskin +-- ============================================ +CREATE TABLE IF NOT EXISTS `masyarakat_miskin` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `nama` varchar(100) NOT NULL, + `tanggal_lahir` date NOT NULL, + `jenis_kelamin` enum('Laki-laki','Perempuan') NOT NULL, + `nik` varchar(20), + `alamat` text NOT NULL, + `latitude` decimal(10,8) NOT NULL, + `longitude` decimal(11,8) NOT NULL, + `status_bpjs` enum('Ya','Tidak','Proses') DEFAULT 'Tidak', + `no_hp` varchar(15), + `pekerjaan` varchar(100), + `pendapatan_bulanan` int(11), + `jumlah_tanggungan` int(11), + `status_rumah` enum('Milik Sendiri','Sewa','Menumpang') DEFAULT 'Menumpang', + `kelurahan` varchar(100), + `kecamatan` varchar(100), + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX `idx_nama` (`nama`), + INDEX `idx_status_bpjs` (`status_bpjs`), + INDEX `idx_kecamatan` (`kecamatan`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- ============================================ +-- TABLE 2: rumah_ibadah +-- ============================================ +CREATE TABLE IF NOT EXISTS `rumah_ibadah` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `nama` varchar(100) NOT NULL, + `jenis` enum('Masjid','Gereja','Vihara','Kelenteng','Sinagog','Lain') NOT NULL, + `latitude` decimal(10,8) NOT NULL, + `longitude` decimal(11,8) NOT NULL, + `alamat` text NOT NULL, + `nama_pemimpin` varchar(100), + `no_hp_pemimpin` varchar(15), + `kapasitas` int(11), + `tahun_didirikan` year, + `keterangan` text, + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX `idx_nama` (`nama`), + INDEX `idx_jenis` (`jenis`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- ============================================ +-- TABLE 3: bantuan_riwayat +-- ============================================ +CREATE TABLE IF NOT EXISTS `bantuan_riwayat` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `id_masyarakat` int(11) NOT NULL, + `jenis_bantuan` varchar(100) NOT NULL, + `tanggal_bantuan` date NOT NULL, + `nilai` int(11) NOT NULL, + `satuan` varchar(50), + `keterangan` text, + `nama_pemberi` varchar(100), + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (`id_masyarakat`) REFERENCES `masyarakat_miskin`(`id`) ON DELETE CASCADE, + INDEX `idx_id_masyarakat` (`id_masyarakat`), + INDEX `idx_tanggal` (`tanggal_bantuan`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- ============================================ +-- TABLE 4: bpjs_record +-- ============================================ +CREATE TABLE IF NOT EXISTS `bpjs_record` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `id_masyarakat` int(11) NOT NULL, + `no_peserta` varchar(20) NOT NULL UNIQUE, + `jenis_bpjs` enum('Kesehatan','Ketenagakerjaan','Jaminan Hari Tua') DEFAULT 'Kesehatan', + `tingkat` enum('Penerima Bantuan Iuran (PBI)','Pekerja Penerima Upah','Pekerja Bukan Penerima Upah','Peserta Mandiri') DEFAULT 'Penerima Bantuan Iuran (PBI)', + `tanggal_daftar` date NOT NULL, + `status_aktif` enum('Aktif','Nonaktif','Suspended') DEFAULT 'Aktif', + `faskes_tingkat_1` varchar(100), + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (`id_masyarakat`) REFERENCES `masyarakat_miskin`(`id`) ON DELETE CASCADE, + INDEX `idx_id_masyarakat` (`id_masyarakat`), + INDEX `idx_no_peserta` (`no_peserta`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- ============================================ +-- TABLE 5: users (untuk login admin) +-- ============================================ +CREATE TABLE IF NOT EXISTS `users` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `username` varchar(50) NOT NULL UNIQUE, + `password` varchar(255) NOT NULL, + `nama_lengkap` varchar(100) NOT NULL, + `role` enum('Admin','Surveyor','Viewer') DEFAULT 'Surveyor', + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- Insert default admin user (password: admin123) +INSERT INTO `users` (`username`, `password`, `nama_lengkap`, `role`) VALUES +('admin', '5f4dcc3b5aa765d61d8327deb882cf99', 'Administrator', 'Admin'); + +-- ============================================ +-- TABLE 6: fasilitas_jalan +-- ============================================ +CREATE TABLE IF NOT EXISTS `fasilitas_jalan` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `nama` varchar(150) NOT NULL, + `geojson` text NOT NULL, + `tipe` varchar(50), + `keterangan` text, + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- ============================================ +-- TABLE 7: fasilitas_polygon +-- ============================================ +CREATE TABLE IF NOT EXISTS `fasilitas_polygon` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `nama` varchar(150) NOT NULL, + `geojson` text NOT NULL, + `tipe` varchar(50), + `keterangan` text, + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- ============================================ +-- TABLE 8: fasilitas_spbu +-- ============================================ +CREATE TABLE IF NOT EXISTS `fasilitas_spbu` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `nama` varchar(150) NOT NULL, + `latitude` decimal(10,8) NOT NULL, + `longitude` decimal(11,8) NOT NULL, + `alamat` text, + `is_24_jam` enum('Ya','Tidak') DEFAULT 'Tidak', + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- ============================================ +-- SAMPLE DATA (Opsional - untuk testing) +-- ============================================ + +-- Sample Masyarakat Miskin +INSERT INTO `masyarakat_miskin` (`nama`, `tanggal_lahir`, `jenis_kelamin`, `nik`, `alamat`, `latitude`, `longitude`, `status_bpjs`, `no_hp`, `pekerjaan`, `pendapatan_bulanan`, `jumlah_tanggungan`, `status_rumah`, `kelurahan`, `kecamatan`) VALUES +('Siti Nur Azizah', '1985-03-15', 'Perempuan', '6101234567890123', 'Jl. Mahakam No. 25', -0.0612, 109.3445, 'Ya', '081234567890', 'Buruh Harian', 1500000, 4, 'Menumpang', 'Sungai Jawi', 'Pontianak Kota'); + +-- Sample Rumah Ibadah +INSERT INTO `rumah_ibadah` (`nama`, `jenis`, `latitude`, `longitude`, `alamat`, `nama_pemimpin`, `no_hp_pemimpin`, `kapasitas`, `tahun_didirikan`) VALUES +('Masjid Al-Hidayah', 'Masjid', -0.0615, 109.3450, 'Jl. Diponegoro No. 45', 'Ustaz Ahmad', '081234567890', 500, 2005), +('Gereja Hati Kudus', 'Gereja', -0.0610, 109.3440, 'Jl. Jend Sudirman No. 12', 'Pdt. Bonaventura', '081234567891', 300, 1995); + +-- ============================================ +-- SELESAI +-- ============================================ diff --git a/01/docs/PANDUAN_PHPMY_ADMIN.md b/01/docs/PANDUAN_PHPMY_ADMIN.md new file mode 100644 index 0000000..110f078 --- /dev/null +++ b/01/docs/PANDUAN_PHPMY_ADMIN.md @@ -0,0 +1,134 @@ +# 📖 Panduan Lengkap: Membuat Database di phpMyAdmin + +## STEP 1: Akses phpMyAdmin +1. Buka browser dan akses: `http://localhost/phpmyadmin` + - Username: `root` + - Password: *(kosongkan atau sesuai konfigurasi)* +2. Tekan tombol **Login** + +--- + +## STEP 2: Buat Database Baru + +### Cara Manual: +1. **Di halaman utama phpMyAdmin**, cari kolom **"Create new database"** di sebelah kiri +2. Isikan nama database: `pemetaan_kemiskinan` +3. Pilih **Collation**: `utf8mb4_general_ci` +4. Klik tombol **Create** + +### Atau menggunakan Import SQL: +1. Di menu atas, pilih tab **"Import"** +2. Klik **"Choose File"** dan pilih file `database.sql` +3. Pastikan encoding: `utf-8` +4. Klik **Import** (database akan terbuat otomatis) + +✅ Database berhasil dibuat + +--- + +## STEP 3: Verifikasi Tabel-Tabel + +Setelah import atau membuat manual, klik pada database `pemetaan_kemiskinan` di sebelah kiri. + +**Anda seharusnya melihat tabel-tabel berikut:** + +``` +✓ masyarakat_miskin +✓ rumah_ibadah +✓ bantuan_riwayat +✓ bpjs_record +``` + +--- + +## STEP 4: Struktur Tabel (REFERENSI) + +### Tabel: `masyarakat_miskin` +| Field | Type | Keterangan | +|-------|------|-----------| +| id | INT (Primary Key) | ID unik | +| nama | VARCHAR(100) | Nama lengkap | +| tanggal_lahir | DATE | Tgl lahir (YYYY-MM-DD) | +| jenis_kelamin | ENUM('Laki-laki','Perempuan') | - | +| alamat | TEXT | Alamat rumah | +| latitude | DECIMAL(10,8) | Koordinat lat | +| longitude | DECIMAL(11,8) | Koordinat lng | +| status_bpjs | ENUM('Ya','Tidak','Proses') | Status BPJS | +| no_hp | VARCHAR(15) | Nomor HP | +| created_at | TIMESTAMP | Waktu input | + +### Tabel: `rumah_ibadah` +| Field | Type | Keterangan | +|-------|------|-----------| +| id | INT (Primary Key) | ID unik | +| nama | VARCHAR(100) | Nama tempat ibadah | +| jenis | ENUM('Masjid','Gereja','Vihara','Kelenteng','Lain') | Tipe | +| latitude | DECIMAL(10,8) | Koordinat lat | +| longitude | DECIMAL(11,8) | Koordinat lng | +| alamat | TEXT | Alamat | +| keterangan | TEXT | Info tambahan | +| created_at | TIMESTAMP | Waktu input | + +### Tabel: `bantuan_riwayat` +| Field | Type | Keterangan | +|-------|------|-----------| +| id | INT (Primary Key) | ID unik | +| id_masyarakat | INT | ID masyarakat (foreign key) | +| jenis_bantuan | VARCHAR(100) | Tipe bantuan | +| tanggal_bantuan | DATE | Tanggal pemberian | +| nilai | INT | Nominal (Rp) | +| keterangan | TEXT | Catatan | + +### Tabel: `bpjs_record` +| Field | Type | Keterangan | +|-------|------|-----------| +| id | INT (Primary Key) | ID unik | +| id_masyarakat | INT | ID masyarakat | +| no_peserta | VARCHAR(20) | Nomor peserta BPJS | +| tingkat | ENUM('Keluarga','Mandiri','Penerima Bantuan Iuran') | Tipe BPJS | +| tanggal_daftar | DATE | Tgl pendaftaran | + +--- + +## STEP 5: Cek Koneksi Database (Opsional) + +Jika ingin test koneksi manual: + +1. Buat file `test_koneksi.php` di folder project +2. Isi dengan kode ini: + +```php +connect_error) { + die("Koneksi gagal: " . $conn->connect_error); +} + +echo "✅ Koneksi berhasil!"; +?> +``` + +3. Akses: `http://localhost/pemetaan-kemiskinan/test_koneksi.php` +4. Jika muncul pesan hijau = Database siap digunakan ✅ + +--- + +## TROUBLESHOOTING + +### ❌ "Access denied for user 'root'@'localhost'" +- Buka file `config/koneksi.php` +- Ubah password sesuai konfigurasi MySQL Anda +- Jika menggunakan XAMPP default, kosongkan saja password + +### ❌ "Database pemetaan_kemiskinan tidak ditemukan" +- Pastikan sudah run file `database.sql` melalui Import +- Atau buat manual: **Create new database** → nama: `pemetaan_kemiskinan` + +### ❌ File upload tidak berfungsi +- Cek folder upload di `_uploads/` sudah ada & permission 755 +- Atau buat manual: klik kanan folder → Properties → Permission → 755 + +--- + +✅ **Selesai! Database siap digunakan untuk website pemetaan kemiskinan** diff --git a/01/index.html b/01/index.html new file mode 100644 index 0000000..c05f043 --- /dev/null +++ b/01/index.html @@ -0,0 +1,280 @@ + + + + + + WebGIS Poverty Mapping + + + + + + + + + +
+
+ + +
+
+

WebGIS Pontianak

+

Pusat Integrasi Data Geospasial & Kemiskinan

+
+ +
+ +
+
+

Fasilitas & Tata Kota

+

Manajemen pemetaan jalan, fasilitas publik, batas area, dan inventarisasi tata ruang kota Pontianak.

+ Masuk Sistem → +
+ + +
+
+

Sosial Kemasyarakatan

+

Sistem informasi geografis kawasan rentan, sebaran warga miskin, dan pemantauan rumah ibadah terpadu.

+ Masuk Sistem → +
+ + +
+
+

Portal Publik

+

Akses peta interaktif secara transparan untuk masyarakat umum dan layanan pelaporan darurat.

+ Akses Warga → +
+
+
+ + + + diff --git a/01/js/main.js b/01/js/main.js new file mode 100644 index 0000000..55da330 --- /dev/null +++ b/01/js/main.js @@ -0,0 +1,912 @@ +// ======================================== +// FILE: js/main.js +// Main JavaScript untuk Pemetaan Kemiskinan +// ======================================== + +// ========== KONFIGURASI ========== +const MAP_CENTER = [-0.0612, 109.3449]; // Koordinat pusat peta (Pontianak) +const MAP_ZOOM = 12; // Tingkat perbesaran bawaan peta +const API_PATH = 'php/'; // Jalur relatif menuju berkas API PHP + +let map; +const markers = { + masyarakat: [], + ibadah: [], + spbu: [] +}; + +const layers = { + jalan: L.layerGroup(), + polygon: L.layerGroup() +}; + +let current_tab = 'masyarakat'; +const all_data = { + masyarakat: [], + ibadah: [], + jalan: [], + polygon: [], + spbu: [] +}; + +let drawnItems; + +// ========== ICON MARKER ========== +const iconMasyarakat = L.icon({ + iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png', + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png', + shadowSize: [41, 41] +}); + +const iconIbadah = L.icon({ + iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-green.png', + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png', + shadowSize: [41, 41] +}); + +// ========== UTILITAS KEAMANAN & FORMAT ========== + +/** + * Mengamankan string teks dari potensi serangan injeksi XSS. + * @param {string} str - String mentah yang akan dibersihkan. + * @returns {string} String yang aman untuk direndering ke DOM. + */ +function escapeHTML(str) { + if (str === null || str === undefined) return '-'; + return String(str) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + +/** + * Melakukan validasi dasar terhadap respons HTTP Fetch sebelum diproses menjadi JSON. + * @param {Response} response - Objek respons dari Fetch API. + * @returns {Promise} Mengembalikan Promise berupa objek JSON jika sukses. + */ +function handleFetchResponse(response) { + if (!response.ok) { + throw new Error(`Gagal memuat data dari server (Status: ${response.status})`); + } + return response.json(); +} + +// ========== INISIALISASI ========== +document.addEventListener('DOMContentLoaded', function() { + initMap(); + loadData(); + attachEventListeners(); + + // Check initial active tab from landing page + const activeTab = localStorage.getItem('activeTab'); + const accs = document.querySelectorAll('.accordion'); + + if (activeTab === 'fasilitas') { + if (accs.length > 0) { + accs[0].style.display = 'flex'; // Show Fasilitas + if (accs.length > 1) accs[1].style.display = 'none'; // Hide Sosial + if (accs.length > 2) accs[2].style.display = 'none'; // Hide Publik + + accs[0].classList.add('active'); + accs[0].nextElementSibling.style.display = 'block'; + const firstTab = accs[0].nextElementSibling.querySelector('.tab-button'); + if (firstTab) firstTab.click(); + } + } else if (activeTab === 'sosial') { + if (accs.length > 1) { + if (accs.length > 0) accs[0].style.display = 'none'; // Hide Fasilitas + accs[1].style.display = 'flex'; // Show Sosial + if (accs.length > 2) accs[2].style.display = 'none'; // Hide Publik + + accs[1].classList.add('active'); + accs[1].nextElementSibling.style.display = 'block'; + const firstTab = accs[1].nextElementSibling.querySelector('.tab-button'); + if (firstTab) firstTab.click(); + } + } else if (activeTab === 'publik') { + // Mode Publik: Sembunyikan semua tombol Add dan Form Input + document.querySelectorAll('.btn-primary').forEach(btn => { + if(btn.textContent.includes('+')) btn.style.display = 'none'; + }); + document.querySelector('.leaflet-draw').style.display = 'none'; // Sembunyikan toolbar Leaflet Draw + + // Buka Layanan Publik (Accordion 3) + if (accs.length > 0) accs[0].style.display = 'none'; + if (accs.length > 1) accs[1].style.display = 'none'; + if (accs.length > 2) { + accs[2].style.display = 'flex'; + accs[2].classList.add('active'); + accs[2].nextElementSibling.style.display = 'block'; + const firstTab = accs[2].nextElementSibling.querySelector('.tab-button'); + if (firstTab) firstTab.click(); + } + + // Tambahkan badge Portal Publik di sidebar jika belum ada + if (!document.getElementById('badge-publik')) { + const sidebar = document.getElementById('sidebar'); + const badge = document.createElement('div'); + badge.id = 'badge-publik'; + badge.innerHTML = '
Mode Akses Publik
'; + sidebar.insertBefore(badge, sidebar.children[2]); + } + } +}); + +/** + * Menginisialisasi objek peta Leaflet dan menambahkan event listener klik. + */ +function initMap() { + map = L.map('map').setView(MAP_CENTER, MAP_ZOOM); + + L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { + maxZoom: 19, + attribution: '© OpenStreetMap contributors' + }).addTo(map); + + // LEAFLET DRAW + drawnItems = new L.FeatureGroup(); + map.addLayer(drawnItems); + + const drawControl = new L.Control.Draw({ + edit: { featureGroup: drawnItems }, + draw: { + polyline: true, + polygon: true, + circle: false, + marker: false, + circlemarker: false, + rectangle: false + } + }); + map.addControl(drawControl); + + map.on(L.Draw.Event.CREATED, function (e) { + const type = e.layerType; + const layer = e.layer; + const geojson = JSON.stringify(layer.toGeoJSON()); + + if (type === 'polyline') { + openModal('modal-form-jalan'); + setTimeout(() => { document.getElementById('geojson-jalan').value = geojson; }, 100); + } else if (type === 'polygon') { + openModal('modal-form-polygon'); + setTimeout(() => { document.getElementById('geojson-polygon').value = geojson; }, 100); + } + }); + + // Klik peta untuk memunculkan pilihan tambah data + map.on('click', function(e) { + const lat = e.latlng.lat.toFixed(8); + const lng = e.latlng.lng.toFixed(8); + + document.querySelectorAll('input[name="latitude"]').forEach(el => el.value = lat); + document.querySelectorAll('input[name="longitude"]').forEach(el => el.value = lng); + + let buttonsHTML = ''; + if (current_tab === 'masyarakat') { + buttonsHTML = ``; + } else if (current_tab === 'ibadah') { + buttonsHTML = ``; + } else if (current_tab === 'spbu') { + buttonsHTML = ``; + } else { + buttonsHTML = `Silakan pilih tab yang sesuai (Warga, Ibadah, atau SPBU) di menu kiri terlebih dahulu.`; + } + + // Buat konten popup pilihan + const popupContent = ` +
+ Pilih Data untuk Ditambah + ${lat}, ${lng} +
+ ${buttonsHTML} +
+
+ `; + + L.popup() + .setLatLng(e.latlng) + .setContent(popupContent) + .openOn(map); + }); +} + +/** + * Memicu proses memuat seluruh data dari API secara paralel. + */ +function loadData() { + loadMasyarakat(); + loadRumahIbadah(); + loadJalan(); + loadPolygon(); + loadSPBU(); +} + +function loadJalan() { + fetch(API_PATH + 'ambil_fasilitas_jalan.php').then(handleFetchResponse).then(result => { + if (result.status === 'success') { + all_data.jalan = result.data || []; + tampilkanDataJalan(all_data.jalan); + } + }).catch(e => console.error(e)); +} + +function loadPolygon() { + fetch(API_PATH + 'ambil_fasilitas_polygon.php').then(handleFetchResponse).then(result => { + if (result.status === 'success') { + all_data.polygon = result.data || []; + tampilkanDataPolygon(all_data.polygon); + } + }).catch(e => console.error(e)); +} + +function loadSPBU() { + fetch(API_PATH + 'ambil_fasilitas_spbu.php').then(handleFetchResponse).then(result => { + if (result.status === 'success') { + all_data.spbu = result.data || []; + tampilkanDataSPBU(all_data.spbu); + } + }).catch(e => console.error(e)); +} + +/** + * Memuat data masyarakat miskin dari server. + */ +function loadMasyarakat() { + fetch(API_PATH + 'ambil_data_masyarakat.php') + .then(handleFetchResponse) + .then(result => { + if (result.status === 'success') { + all_data.masyarakat = result.data || []; + tampilkanDataMasyarakat(all_data.masyarakat); + } else { + console.error('Gagal memuat data masyarakat:', result.message); + } + }) + .catch(error => console.error('Error saat fetch data masyarakat:', error)); +} + +/** + * Memuat data fasilitas rumah ibadah dari server. + */ +function loadRumahIbadah() { + fetch(API_PATH + 'ambil_rumah_ibadah.php') + .then(handleFetchResponse) + .then(result => { + if (result.status === 'success') { + all_data.ibadah = result.data || []; + tampilkanDataIbadah(all_data.ibadah); + } else { + console.error('Gagal memuat data rumah ibadah:', result.message); + } + }) + .catch(error => console.error('Error saat fetch data rumah ibadah:', error)); +} + +/** + * Merender penanda peta dan elemen daftar sidebar untuk kategori masyarakat. + * @param {Array} data - Larik berisi data objek masyarakat. + */ +function tampilkanDataMasyarakat(data) { + markers.masyarakat.forEach(m => map.removeLayer(m)); + markers.masyarakat = []; + + const list = document.getElementById('list-masyarakat'); + if (!list) return; + list.innerHTML = ''; + + data.forEach(item => { + const marker = L.marker( + [parseFloat(item.latitude), parseFloat(item.longitude)], + { icon: iconMasyarakat } + ).addTo(map); + + const bpjs_class = item.status_bpjs === 'Ya' ? 'status-ya' : (item.status_bpjs === 'Proses' ? 'status-proses' : 'status-tidak'); + + // Penerapan escapeHTML untuk mencegah kerentanan XSS pada popup + marker.bindPopup(` +
+ ${escapeHTML(item.nama)}
+ ${escapeHTML(item.alamat)}
+ Status BPJS: ${escapeHTML(item.status_bpjs)}
+ +
+ `); + + markers.masyarakat.push(marker); + + const li = document.createElement('li'); + li.innerHTML = ` + ${escapeHTML(item.nama)} + ${escapeHTML(item.kecamatan)} | BPJS: ${escapeHTML(item.status_bpjs)} + `; + + li.onclick = () => { + map.setView([item.latitude, item.longitude], 16); + marker.openPopup(); + }; + + list.appendChild(li); + }); + + updateMapVisibility(); +} + +/** + * Merender penanda peta dan elemen daftar sidebar untuk kategori rumah ibadah. + * @param {Array} data - Larik berisi data objek rumah ibadah. + */ +function tampilkanDataIbadah(data) { + markers.ibadah.forEach(m => map.removeLayer(m)); + markers.ibadah = []; + + const list = document.getElementById('list-ibadah'); + if (!list) return; + list.innerHTML = ''; + + data.forEach(item => { + const marker = L.marker( + [parseFloat(item.latitude), parseFloat(item.longitude)], + { icon: iconIbadah } + ).addTo(map); + + const info_pemimpin = item.nama_pemimpin ? 'Pemimpin: ' + escapeHTML(item.nama_pemimpin) + '
' : ''; + const info_alamat = item.alamat ? '' + escapeHTML(item.alamat) + '' : ''; + + marker.bindPopup(` +
+ ${escapeHTML(item.nama)}
+ ${escapeHTML(item.jenis)}
+ ${info_pemimpin} + ${info_alamat} +
+ `); + + markers.ibadah.push(marker); + + const li = document.createElement('li'); + li.innerHTML = ` + ${escapeHTML(item.nama)} + ${escapeHTML(item.jenis)} + `; + + li.onclick = () => { + map.setView([item.latitude, item.longitude], 16); + marker.openPopup(); + }; + + list.appendChild(li); + }); + + updateMapVisibility(); +} + +function tampilkanDataJalan(data) { + if (layers.jalan) map.removeLayer(layers.jalan); + layers.jalan = L.layerGroup().addTo(map); + const list = document.getElementById('list-jalan'); + if (!list) return; + list.innerHTML = ''; + + data.forEach(item => { + try { + const geojson = JSON.parse(item.geojson); + const layer = L.geoJSON(geojson, { style: { color: 'blue', weight: 4 } }).addTo(layers.jalan); + layer.bindPopup(`${escapeHTML(item.nama)}
${escapeHTML(item.tipe)}
`); + + const li = document.createElement('li'); + li.innerHTML = `${escapeHTML(item.nama)}
${escapeHTML(item.tipe)}`; + li.onclick = () => { map.fitBounds(layer.getBounds()); layer.openPopup(); }; + list.appendChild(li); + } catch(e) { console.error('Invalid GeoJSON', e); } + }); + + updateMapVisibility(); +} + +function tampilkanDataPolygon(data) { + if (layers.polygon) map.removeLayer(layers.polygon); + layers.polygon = L.layerGroup().addTo(map); + const list = document.getElementById('list-polygon'); + if (!list) return; + list.innerHTML = ''; + + data.forEach(item => { + try { + const geojson = JSON.parse(item.geojson); + const layer = L.geoJSON(geojson, { style: { color: 'purple', fillColor: 'purple', fillOpacity: 0.4 } }).addTo(layers.polygon); + layer.bindPopup(`${escapeHTML(item.nama)}
${escapeHTML(item.tipe)}
`); + + const li = document.createElement('li'); + li.innerHTML = `${escapeHTML(item.nama)}
${escapeHTML(item.tipe)}`; + li.onclick = () => { map.fitBounds(layer.getBounds()); layer.openPopup(); }; + list.appendChild(li); + } catch(e) { console.error('Invalid GeoJSON', e); } + }); + + updateMapVisibility(); +} + +function tampilkanDataSPBU(data) { + markers.spbu.forEach(m => map.removeLayer(m)); + markers.spbu = []; + const list = document.getElementById('list-spbu'); + if (!list) return; + list.innerHTML = ''; + + data.forEach(item => { + const is24 = item.is_24_jam === 'Ya'; + // Reuse iconIbadah for green (24h) and iconMasyarakat for red (not 24h) + const iconSPBU = is24 ? iconIbadah : iconMasyarakat; + const statusText = is24 ? 'Buka 24 Jam' : 'Tidak 24 Jam'; + + const marker = L.marker([parseFloat(item.latitude), parseFloat(item.longitude)], { + icon: iconSPBU, + draggable: true + }).addTo(map); + + marker.bindPopup(`${escapeHTML(item.nama)}
${escapeHTML(item.alamat)}
${statusText}
`); + + marker.on('dragend', function(e) { + const newPos = marker.getLatLng(); + if (confirm('Apakah Anda yakin ingin memperbarui lokasi SPBU ini?')) { + const fd = new FormData(); + fd.append('id', item.id); + fd.append('latitude', newPos.lat.toFixed(8)); + fd.append('longitude', newPos.lng.toFixed(8)); + fetch(API_PATH + 'update_lokasi_spbu.php', { method: 'POST', body: fd }) + .then(handleFetchResponse) + .then(res => { + if (res.status === 'success') { + alert('Lokasi berhasil diperbarui'); + item.latitude = newPos.lat; + item.longitude = newPos.lng; + } else { + alert('Gagal: ' + res.message); + marker.setLatLng([parseFloat(item.latitude), parseFloat(item.longitude)]); + } + }).catch(err => { + alert('Error: ' + err.message); + marker.setLatLng([parseFloat(item.latitude), parseFloat(item.longitude)]); + }); + } else { + marker.setLatLng([parseFloat(item.latitude), parseFloat(item.longitude)]); + } + }); + + markers.spbu.push(marker); + + const li = document.createElement('li'); + li.innerHTML = `${escapeHTML(item.nama)}
${escapeHTML(item.alamat)}
${statusText}`; + li.onclick = () => { map.setView([item.latitude, item.longitude], 16); marker.openPopup(); }; + list.appendChild(li); + }); + updateMapVisibility(); +} + +/** + * Memuat detail data spesifik masyarakat miskin termasuk riwayat bantuan dan status BPJS. + * @param {string|number} id - ID unik entitas masyarakat miskin. + */ +function showDetail(id) { + fetch(API_PATH + 'ambil_detail.php?id=' + encodeURIComponent(id)) + .then(handleFetchResponse) + .then(result => { + if (result.status === 'success') { + const data = result.data; + const masyarakat = data.masyarakat; + const bantuan = data.bantuan || []; + const bpjs = data.bpjs; + + const bpjs_class = masyarakat.status_bpjs === 'Ya' ? 'status-ya' : (masyarakat.status_bpjs === 'Proses' ? 'status-proses' : 'status-tidak'); + + let html = ` +
+

👤 Data Pribadi

+
Nama${escapeHTML(masyarakat.nama)}
+
Tanggal Lahir${escapeHTML(masyarakat.tanggal_lahir)}
+
Jenis Kelamin${escapeHTML(masyarakat.jenis_kelamin)}
+
NIK${escapeHTML(masyarakat.nik)}
+
No. HP${escapeHTML(masyarakat.no_hp)}
+
+ +
+

🏠 Data Alamat

+
Alamat${escapeHTML(masyarakat.alamat)}
+
Kelurahan${escapeHTML(masyarakat.kelurahan)}
+
Kecamatan${escapeHTML(masyarakat.kecamatan)}
+
Status Rumah${escapeHTML(masyarakat.status_rumah)}
+
+ +
+

💼 Data Ekonomi

+
Pekerjaan${escapeHTML(masyarakat.pekerjaan)}
+
Pendapatan BulananRp. ${new Intl.NumberFormat('id-ID').format(masyarakat.pendapatan_bulanan || 0)}
+
Jumlah Tanggungan${escapeHTML(masyarakat.jumlah_tanggungan)} orang
+
+ +
+

🏥 Status BPJS

+
Status BPJS${escapeHTML(masyarakat.status_bpjs)}
+ `; + + if (bpjs) { + html += ` +
No. Peserta BPJS${escapeHTML(bpjs.no_peserta)}
+
Jenis BPJS${escapeHTML(bpjs.jenis_bpjs)}
+
Tingkat${escapeHTML(bpjs.tingkat)}
+ `; + } + + html += `
`; // Memperbaiki string penutup tag div yang sebelumnya memicu syntax error + + if (bantuan.length > 0) { + html += `

💰 Riwayat Bantuan

`; + bantuan.forEach(b => { + html += ` +
+ ${escapeHTML(b.jenis_bantuan)} (${escapeHTML(b.tanggal_bantuan)})
+ Nilai: Rp. ${new Intl.NumberFormat('id-ID').format(b.nilai)} ${escapeHTML(b.satuan)} + ${b.keterangan ? '
' + escapeHTML(b.keterangan) + '' : ''} +
+ `; + }); + html += `
`; + } + + html += ` +
+ + +
+ `; + + const modal_body = document.getElementById('modal-body'); + if (modal_body) { + modal_body.innerHTML = html; + openModal('modal-detail'); + } + } + }) + .catch(error => console.error('Error saat fetch detail data:', error)); +} + +/** + * Menghubungkan fungsi penangan kejadian (event handler) ke elemen-elemen HTML DOM. + */ +function attachEventListeners() { + // Accordion Logic + document.querySelectorAll('.accordion').forEach(acc => { + acc.addEventListener('click', function() { + // Close other accordions + document.querySelectorAll('.accordion').forEach(otherAcc => { + if (otherAcc !== this) { + otherAcc.classList.remove('active'); + if (otherAcc.nextElementSibling) { + otherAcc.nextElementSibling.style.display = "none"; + } + } + }); + + // Toggle this one + this.classList.toggle('active'); + const panel = this.nextElementSibling; + if (panel.style.display === "block") { + panel.style.display = "none"; + } else { + panel.style.display = "block"; + // Optionally auto-click the first tab in this accordion + const firstTab = panel.querySelector('.tab-button'); + if (firstTab && !firstTab.classList.contains('active')) { + firstTab.click(); + } + } + }); + }); + + document.querySelectorAll('.tab-button').forEach(btn => { + btn.addEventListener('click', function(e) { + const tab = this.dataset.tab; + switchTab(e, tab); + }); + }); + + const search_input = document.getElementById('search'); + const f_kecamatan = document.getElementById('filter-kecamatan'); + const f_bpjs = document.getElementById('filter-bpjs'); + const f_jenis = document.getElementById('filter-jenis'); + + if (search_input) search_input.addEventListener('input', filterMasyarakat); + if (f_kecamatan) f_kecamatan.addEventListener('change', filterMasyarakat); + if (f_bpjs) f_bpjs.addEventListener('change', filterMasyarakat); + if (f_jenis) f_jenis.addEventListener('change', filterIbadah); + + const form_masyarakat = document.getElementById('form-masyarakat'); + const form_ibadah = document.getElementById('form-ibadah'); + const form_jalan = document.getElementById('form-jalan'); + const form_polygon = document.getElementById('form-polygon'); + const form_spbu = document.getElementById('form-spbu'); + + if (form_masyarakat) form_masyarakat.addEventListener('submit', function(e) { e.preventDefault(); submitFormMasyarakat(); }); + if (form_ibadah) form_ibadah.addEventListener('submit', function(e) { e.preventDefault(); submitFormIbadah(); }); + if (form_jalan) form_jalan.addEventListener('submit', function(e) { e.preventDefault(); submitFormJalan(); }); + if (form_polygon) form_polygon.addEventListener('submit', function(e) { e.preventDefault(); submitFormPolygon(); }); + if (form_spbu) form_spbu.addEventListener('submit', function(e) { e.preventDefault(); submitFormSPBU(); }); + + // Shortcut keyboard untuk membuka formulir penambahan data baru + document.addEventListener('keydown', function(e) { + if (e.key === 'n' || e.key === 'N') { + const active_modal = document.querySelector('.modal.active'); + if (active_modal) return; // Cegah konflik jika modal lain sudah terbuka + + if (current_tab === 'masyarakat') openModal('modal-form-masyarakat'); + else if (current_tab === 'ibadah') openModal('modal-form-ibadah'); + } + }); +} + +/** + * Mengubah status visibilitas tab kategori aktif (Masyarakat / Rumah Ibadah). + * @param {Event} e - Objek event klik dari DOM. + * @param {string} tab - Nama tab penanda tujuan ('masyarakat' / 'ibadah'). + */ +function switchTab(e, tab) { + current_tab = tab; + + document.querySelectorAll('.tab-button').forEach(btn => { + btn.classList.remove('active'); + }); + if (e && e.target) { + e.target.classList.add('active'); + } + + document.querySelectorAll('.list-container').forEach(container => { + container.classList.remove('active'); + }); + + const target_tab = document.getElementById('tab-' + tab); + if (target_tab) target_tab.classList.add('active'); + + updateMapVisibility(); +} + +function updateMapVisibility() { + markers.masyarakat.forEach(m => map.removeLayer(m)); + markers.ibadah.forEach(m => map.removeLayer(m)); + markers.spbu.forEach(m => map.removeLayer(m)); + if (layers.jalan) map.removeLayer(layers.jalan); + if (layers.polygon) map.removeLayer(layers.polygon); + + if (current_tab === 'masyarakat' || current_tab === 'info-fasilitas') { + markers.masyarakat.forEach(m => map.addLayer(m)); + } + if (current_tab === 'ibadah' || current_tab === 'info-fasilitas') { + markers.ibadah.forEach(m => map.addLayer(m)); + } + if (current_tab === 'spbu' || current_tab === 'info-fasilitas') { + markers.spbu.forEach(m => map.addLayer(m)); + } + if (current_tab === 'jalan' || current_tab === 'info-fasilitas') { + if (layers.jalan) map.addLayer(layers.jalan); + } + if (current_tab === 'polygon' || current_tab === 'info-fasilitas') { + if (layers.polygon) map.addLayer(layers.polygon); + } +} + +/** + * Memfilter kumpulan data masyarakat berdasarkan kata kunci pencarian, kecamatan, dan status BPJS. + */ +function filterMasyarakat() { + const search_el = document.getElementById('search'); + const kec_el = document.getElementById('filter-kecamatan'); + const bpjs_el = document.getElementById('filter-bpjs'); + + const keyword = search_el ? search_el.value.toLowerCase() : ''; + const kecamatan = kec_el ? kec_el.value : ''; + const bpjs = bpjs_el ? bpjs_el.value : ''; + + const filtered = all_data.masyarakat.filter(item => { + const item_nama = item.nama ? item.nama.toLowerCase() : ''; + const item_alamat = item.alamat ? item.alamat.toLowerCase() : ''; + + const match_keyword = item_nama.includes(keyword) || item_alamat.includes(keyword); + const match_kecamatan = !kecamatan || item.kecamatan === kecamatan; + const match_bpjs = !bpjs || item.status_bpjs === bpjs; + + return match_keyword && match_kecamatan && match_bpjs; + }); + + tampilkanDataMasyarakat(filtered); +} + +/** + * Memfilter kumpulan data tempat ibadah berdasarkan jenis kategori tempat ibadah. + */ +function filterIbadah() { + const jenis_el = document.getElementById('filter-jenis'); + const jenis = jenis_el ? jenis_el.value : ''; + + const filtered = all_data.ibadah.filter(item => { + return !jenis || item.jenis === jenis; + }); + + tampilkanDataIbadah(filtered); +} + +/** + * Mengirimkan formulir data masyarakat baru ke berkas PHP pemroses menggunakan Fetch FormData. + */ +function submitFormMasyarakat() { + const form = document.getElementById('form-masyarakat'); + if (!form) return; + const form_data = new FormData(form); + + fetch(API_PATH + 'simpan_masyarakat.php', { + method: 'POST', + body: form_data + }) + .then(handleFetchResponse) + .then(result => { + if (result.status === 'success') { + showAlert('alert-form', 'Data berhasil disimpan!', 'success'); + form.reset(); + setTimeout(() => { + closeModal('modal-form-masyarakat'); + loadMasyarakat(); + }, 1500); + } else { + showAlert('alert-form', result.message || 'Gagal menyimpan data.', 'error'); + } + }) + .catch(error => { + showAlert('alert-form', 'Terjadi kesalahan sistem: ' + error.message, 'error'); + }); +} + +/** + * Mengirimkan formulir data rumah ibadah baru ke berkas PHP pemroses menggunakan Fetch FormData. + */ +function submitFormIbadah() { + const form = document.getElementById('form-ibadah'); + if (!form) return; + const form_data = new FormData(form); + + fetch(API_PATH + 'simpan_rumah_ibadah.php', { + method: 'POST', + body: form_data + }) + .then(handleFetchResponse) + .then(result => { + if (result.status === 'success') { + showAlert('alert-form-ibadah', 'Data berhasil disimpan!', 'success'); + form.reset(); + setTimeout(() => { + closeModal('modal-form-ibadah'); + loadRumahIbadah(); + }, 1500); + } else { + showAlert('alert-form-ibadah', result.message || 'Gagal menyimpan data.', 'error'); + } + }) + .catch(error => { + showAlert('alert-form-ibadah', 'Terjadi kesalahan sistem: ' + error.message, 'error'); + }); +} + +function submitFormJalan() { + const form = document.getElementById('form-jalan'); + if (!form) return; + const form_data = new FormData(form); + fetch(API_PATH + 'simpan_fasilitas_jalan.php', { method: 'POST', body: form_data }) + .then(handleFetchResponse).then(result => { + if (result.status === 'success') { + showAlert('alert-form-jalan', 'Berhasil disimpan', 'success'); form.reset(); drawnItems.clearLayers(); + setTimeout(() => { closeModal('modal-form-jalan'); loadJalan(); }, 1000); + } else showAlert('alert-form-jalan', result.message, 'error'); + }).catch(e => showAlert('alert-form-jalan', e.message, 'error')); +} + +function submitFormPolygon() { + const form = document.getElementById('form-polygon'); + if (!form) return; + const form_data = new FormData(form); + fetch(API_PATH + 'simpan_fasilitas_polygon.php', { method: 'POST', body: form_data }) + .then(handleFetchResponse).then(result => { + if (result.status === 'success') { + showAlert('alert-form-polygon', 'Berhasil disimpan', 'success'); form.reset(); drawnItems.clearLayers(); + setTimeout(() => { closeModal('modal-form-polygon'); loadPolygon(); }, 1000); + } else showAlert('alert-form-polygon', result.message, 'error'); + }).catch(e => showAlert('alert-form-polygon', e.message, 'error')); +} + +function submitFormSPBU() { + const form = document.getElementById('form-spbu'); + if (!form) return; + const form_data = new FormData(form); + fetch(API_PATH + 'simpan_fasilitas_spbu.php', { method: 'POST', body: form_data }) + .then(handleFetchResponse).then(result => { + if (result.status === 'success') { + showAlert('alert-form-spbu', 'Berhasil disimpan', 'success'); form.reset(); + setTimeout(() => { closeModal('modal-form-spbu'); loadSPBU(); }, 1000); + } else showAlert('alert-form-spbu', result.message, 'error'); + }).catch(e => showAlert('alert-form-spbu', e.message, 'error')); +} + +/** + * Mengirimkan instruksi penghapusan data spesifik (masyarakat/ibadah) ke sistem basis data backend. + * @param {string} tipe - Jenis kategori data yang akan dihapus ('masyarakat' / 'ibadah'). + * @param {string|number} id - ID baris data target. + */ +function hapusData(tipe, id) { + if (!confirm('Apakah Anda yakin ingin menghapus data ini? Tindakan ini tidak dapat dibatalkan.')) { + return; + } + + const form_data = new FormData(); + form_data.append('tipe', tipe); + form_data.append('id', id); + + fetch(API_PATH + 'hapus_data.php', { + method: 'POST', + body: form_data + }) + .then(handleFetchResponse) + .then(result => { + if (result.status === 'success') { + alert('Data berhasil dihapus'); + closeModal('modal-detail'); + if (tipe === 'masyarakat') loadMasyarakat(); + else if (tipe === 'ibadah') loadRumahIbadah(); + else if (tipe === 'jalan') loadJalan(); + else if (tipe === 'polygon') loadPolygon(); + else if (tipe === 'spbu') loadSPBU(); + } else { + alert('Gagal menghapus: ' + (result.message || 'Error tidak diketahui')); + } + }) + .catch(error => { + alert('Terjadi kesalahan jaringan atau sistem: ' + error.message); + }); +} + +function editBantuan(id) { + alert('Fitur tambah bantuan dengan ID ' + id + ' akan ditambahkan segera'); +} + +function openModal(modalId) { + const modal = document.getElementById(modalId); + if (modal) modal.classList.add('active'); +} + +function closeModal(modalId) { + const modal = document.getElementById(modalId); + if (modal) modal.classList.remove('active'); +} + +function showAlert(elementId, message, type) { + const alert_el = document.getElementById(elementId); + if (!alert_el) return; + + alert_el.textContent = message; + alert_el.className = 'alert active alert-' + type; + + setTimeout(() => { + alert_el.classList.remove('active'); + }, 5000); +} + +// Menutup jendela modal otomatis jika pengguna mengklik area luar modal (overlay) +document.addEventListener('click', function(e) { + if (e.target && e.target.classList.contains('modal')) { + e.target.classList.remove('active'); + } +}); \ No newline at end of file diff --git a/01/php/ambil_data_masyarakat.php b/01/php/ambil_data_masyarakat.php new file mode 100644 index 0000000..39104f6 --- /dev/null +++ b/01/php/ambil_data_masyarakat.php @@ -0,0 +1,67 @@ +prepare($query); + if ($stmt === false) { + sendJSON('error', 'Query prepare gagal: ' . $conn->error); + } + + if (!empty($params)) { + $stmt->bind_param($types, ...$params); + } + + if (!$stmt->execute()) { + sendJSON('error', 'Query gagal dieksekusi: ' . $stmt->error); + } + + $result = $stmt->get_result(); + + $data = []; + while ($row = $result->fetch_assoc()) { + $data[] = $row; + } + + sendJSON('success', 'Data berhasil diambil', $data); +} +?> diff --git a/01/php/ambil_detail.php b/01/php/ambil_detail.php new file mode 100644 index 0000000..c29479d --- /dev/null +++ b/01/php/ambil_detail.php @@ -0,0 +1,52 @@ +query($query_masyarakat); + + if ($result_masyarakat->num_rows === 0) { + sendJSON('error', 'Data masyarakat tidak ditemukan'); + } + + $masyarakat = $result_masyarakat->fetch_assoc(); + + // AMBIL DATA BANTUAN + $query_bantuan = "SELECT * FROM bantuan_riwayat WHERE id_masyarakat = $id ORDER BY tanggal_bantuan DESC"; + $result_bantuan = $conn->query($query_bantuan); + $bantuan_list = []; + while ($row = $result_bantuan->fetch_assoc()) { + $bantuan_list[] = $row; + } + + // AMBIL DATA BPJS + $query_bpjs = "SELECT * FROM bpjs_record WHERE id_masyarakat = $id"; + $result_bpjs = $conn->query($query_bpjs); + $bpjs = null; + if ($result_bpjs->num_rows > 0) { + $bpjs = $result_bpjs->fetch_assoc(); + } + + $data = [ + 'masyarakat' => $masyarakat, + 'bantuan' => $bantuan_list, + 'bpjs' => $bpjs + ]; + + sendJSON('success', 'Detail data berhasil diambil', $data); +} + +?> diff --git a/01/php/ambil_fasilitas_jalan.php b/01/php/ambil_fasilitas_jalan.php new file mode 100644 index 0000000..a67e845 --- /dev/null +++ b/01/php/ambil_fasilitas_jalan.php @@ -0,0 +1,16 @@ +query($query); + +$data = []; +if ($result) { + while ($row = $result->fetch_assoc()) { + $data[] = $row; + } + sendJSON('success', 'Data jalan berhasil diambil', $data); +} else { + sendJSON('error', 'Gagal mengambil data: ' . $conn->error); +} +?> diff --git a/01/php/ambil_fasilitas_polygon.php b/01/php/ambil_fasilitas_polygon.php new file mode 100644 index 0000000..7c17c95 --- /dev/null +++ b/01/php/ambil_fasilitas_polygon.php @@ -0,0 +1,16 @@ +query($query); + +$data = []; +if ($result) { + while ($row = $result->fetch_assoc()) { + $data[] = $row; + } + sendJSON('success', 'Data polygon berhasil diambil', $data); +} else { + sendJSON('error', 'Gagal mengambil data: ' . $conn->error); +} +?> diff --git a/01/php/ambil_fasilitas_spbu.php b/01/php/ambil_fasilitas_spbu.php new file mode 100644 index 0000000..3562ef4 --- /dev/null +++ b/01/php/ambil_fasilitas_spbu.php @@ -0,0 +1,16 @@ +query($query); + +$data = []; +if ($result) { + while ($row = $result->fetch_assoc()) { + $data[] = $row; + } + sendJSON('success', 'Data SPBU berhasil diambil', $data); +} else { + sendJSON('error', 'Gagal mengambil data: ' . $conn->error); +} +?> diff --git a/01/php/ambil_rumah_ibadah.php b/01/php/ambil_rumah_ibadah.php new file mode 100644 index 0000000..d9822bf --- /dev/null +++ b/01/php/ambil_rumah_ibadah.php @@ -0,0 +1,46 @@ +prepare($query); + if ($stmt === false) { + sendJSON('error', 'Query prepare gagal: ' . $conn->error); + } + + if (!empty($params)) { + $stmt->bind_param($types, ...$params); + } + + if (!$stmt->execute()) { + sendJSON('error', 'Query gagal dieksekusi: ' . $stmt->error); + } + + $result = $stmt->get_result(); + + $data = []; + while ($row = $result->fetch_assoc()) { + $data[] = $row; + } + + sendJSON('success', 'Data berhasil diambil', $data); +} +?> diff --git a/01/php/hapus_data.php b/01/php/hapus_data.php new file mode 100644 index 0000000..887a770 --- /dev/null +++ b/01/php/hapus_data.php @@ -0,0 +1,43 @@ +query($query) === TRUE) { + if ($conn->affected_rows > 0) { + sendJSON('success', 'Data berhasil dihapus'); + } else { + sendJSON('error', 'Data tidak ditemukan'); + } + } else { + sendJSON('error', 'Gagal menghapus: ' . $conn->error); + } +} + +?> diff --git a/01/php/koneksi.php b/01/php/koneksi.php new file mode 100644 index 0000000..97e4e23 --- /dev/null +++ b/01/php/koneksi.php @@ -0,0 +1,57 @@ +connect_error) { + sendJSON('error', 'Koneksi database gagal: ' . $conn->connect_error); + exit(); +} + +// SET CHARSET UTF-8 +$conn->set_charset("utf8mb4"); + +// FUNCTION UNTUK ESCAPE INPUT +function sanitize($string, $conn) { + return $conn->real_escape_string(strip_tags(trim($string))); +} + +// FUNCTION UNTUK RESPONSE JSON +function sendJSON($status, $message, $data = null) { + $response = [ + 'status' => $status, + 'message' => $message + ]; + if ($data !== null) { + $response['data'] = $data; + } + echo json_encode($response, JSON_UNESCAPED_UNICODE); + exit(); +} + +?> diff --git a/01/php/setup_db.php b/01/php/setup_db.php new file mode 100644 index 0000000..672f51e --- /dev/null +++ b/01/php/setup_db.php @@ -0,0 +1,49 @@ +connect_error) { + die("Koneksi gagal: " . $conn_init->connect_error . " (Pastikan MySQL di XAMPP sudah menyala!)"); +} + +// Buat database jika belum ada +$conn_init->query("CREATE DATABASE IF NOT EXISTS `pemetaan_kemiskinan` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"); +$conn_init->select_db("pemetaan_kemiskinan"); + +// Baca isi file database.sql +$sql_file = __DIR__ . '/../database.sql'; +if (!file_exists($sql_file)) { + die("File database.sql tidak ditemukan di $sql_file"); +} + +$sql_content = file_get_contents($sql_file); + +// Eksekusi semua query sekaligus +if ($conn_init->multi_query($sql_content)) { + do { + // Buang hasil dari setiap statement yang dieksekusi agar bisa lanjut ke statement berikutnya + if ($res = $conn_init->store_result()) { + $res->free(); + } + } while ($conn_init->more_results() && $conn_init->next_result()); + + echo "
"; + echo "

✅ Database Berhasil Diimpor Otomatis!

"; + echo "

Seluruh tabel dan titik contoh masyarakat miskin & rumah ibadah sudah dimasukkan ke MySQL.

"; + echo "Kembali ke Portal"; + echo "
"; +} else { + echo "Gagal mengimpor database: " . $conn_init->error; +} + +$conn_init->close(); +?> diff --git a/01/php/simpan_bantuan.php b/01/php/simpan_bantuan.php new file mode 100644 index 0000000..7388217 --- /dev/null +++ b/01/php/simpan_bantuan.php @@ -0,0 +1,43 @@ +query("SELECT id FROM masyarakat_miskin WHERE id = $id_masyarakat"); + if ($check->num_rows == 0) { + sendJSON('error', 'ID Masyarakat tidak ditemukan'); + } + + // QUERY INSERT + $query = "INSERT INTO bantuan_riwayat + (id_masyarakat, jenis_bantuan, tanggal_bantuan, nilai, satuan, keterangan, nama_pemberi) + VALUES + ($id_masyarakat, '$jenis_bantuan', '$tanggal_bantuan', $nilai, '$satuan', '$keterangan', '$nama_pemberi')"; + + if ($conn->query($query) === TRUE) { + sendJSON('success', 'Riwayat bantuan berhasil disimpan', ['id' => $conn->insert_id]); + } else { + sendJSON('error', 'Gagal menyimpan: ' . $conn->error); + } +} + +?> diff --git a/01/php/simpan_bpjs.php b/01/php/simpan_bpjs.php new file mode 100644 index 0000000..2c5f17b --- /dev/null +++ b/01/php/simpan_bpjs.php @@ -0,0 +1,64 @@ +query("SELECT id FROM masyarakat_miskin WHERE id = $id_masyarakat"); + if ($check->num_rows == 0) { + sendJSON('error', 'ID Masyarakat tidak ditemukan'); + } + + // CEK DUPLIKAT NO PESERTA + $cek_dup = $conn->query("SELECT id FROM bpjs_record WHERE no_peserta = '$no_peserta' AND id_masyarakat != $id_masyarakat"); + if ($cek_dup->num_rows > 0) { + sendJSON('error', 'Nomor peserta sudah terdaftar untuk masyarakat lain'); + } + + // QUERY INSERT atau UPDATE + $existing = $conn->query("SELECT id FROM bpjs_record WHERE id_masyarakat = $id_masyarakat"); + + if ($existing->num_rows > 0) { + // UPDATE + $query = "UPDATE bpjs_record SET + no_peserta = '$no_peserta', + jenis_bpjs = '$jenis_bpjs', + tingkat = '$tingkat', + tanggal_daftar = '$tanggal_daftar', + status_aktif = '$status_aktif', + faskes_tingkat_1 = '$faskes' + WHERE id_masyarakat = $id_masyarakat"; + } else { + // INSERT + $query = "INSERT INTO bpjs_record + (id_masyarakat, no_peserta, jenis_bpjs, tingkat, tanggal_daftar, status_aktif, faskes_tingkat_1) + VALUES + ($id_masyarakat, '$no_peserta', '$jenis_bpjs', '$tingkat', '$tanggal_daftar', '$status_aktif', '$faskes')"; + } + + if ($conn->query($query) === TRUE) { + sendJSON('success', 'Data BPJS berhasil disimpan'); + } else { + sendJSON('error', 'Gagal menyimpan: ' . $conn->error); + } +} + +?> diff --git a/01/php/simpan_fasilitas_jalan.php b/01/php/simpan_fasilitas_jalan.php new file mode 100644 index 0000000..a3af698 --- /dev/null +++ b/01/php/simpan_fasilitas_jalan.php @@ -0,0 +1,26 @@ +prepare("INSERT INTO fasilitas_jalan (nama, geojson, tipe, keterangan) VALUES (?, ?, ?, ?)"); +$stmt->bind_param("ssss", $nama, $geojson, $tipe, $keterangan); + +if ($stmt->execute()) { + sendJSON('success', 'Data jalan berhasil disimpan'); +} else { + sendJSON('error', 'Gagal menyimpan: ' . $stmt->error); +} +$stmt->close(); +?> diff --git a/01/php/simpan_fasilitas_polygon.php b/01/php/simpan_fasilitas_polygon.php new file mode 100644 index 0000000..4f2cd67 --- /dev/null +++ b/01/php/simpan_fasilitas_polygon.php @@ -0,0 +1,26 @@ +prepare("INSERT INTO fasilitas_polygon (nama, geojson, tipe, keterangan) VALUES (?, ?, ?, ?)"); +$stmt->bind_param("ssss", $nama, $geojson, $tipe, $keterangan); + +if ($stmt->execute()) { + sendJSON('success', 'Data polygon berhasil disimpan'); +} else { + sendJSON('error', 'Gagal menyimpan: ' . $stmt->error); +} +$stmt->close(); +?> diff --git a/01/php/simpan_fasilitas_spbu.php b/01/php/simpan_fasilitas_spbu.php new file mode 100644 index 0000000..132921c --- /dev/null +++ b/01/php/simpan_fasilitas_spbu.php @@ -0,0 +1,27 @@ +prepare("INSERT INTO fasilitas_spbu (nama, latitude, longitude, alamat, is_24_jam) VALUES (?, ?, ?, ?, ?)"); +$stmt->bind_param("sddss", $nama, $latitude, $longitude, $alamat, $is_24_jam); + +if ($stmt->execute()) { + sendJSON('success', 'Data SPBU berhasil disimpan'); +} else { + sendJSON('error', 'Gagal menyimpan: ' . $stmt->error); +} +$stmt->close(); +?> diff --git a/01/php/simpan_masyarakat.php b/01/php/simpan_masyarakat.php new file mode 100644 index 0000000..266c4ab --- /dev/null +++ b/01/php/simpan_masyarakat.php @@ -0,0 +1,75 @@ +prepare("SELECT id FROM masyarakat_miskin WHERE nik = ?"); + $stmt_cek->bind_param("s", $nik); + $stmt_cek->execute(); + $cek = $stmt_cek->get_result(); + if ($cek && $cek->num_rows > 0) { + sendJSON('error', 'NIK sudah terdaftar di sistem'); + } + $stmt_cek->close(); + } + + // QUERY INSERT + $query = "INSERT INTO masyarakat_miskin + (nama, tanggal_lahir, jenis_kelamin, nik, alamat, latitude, longitude, + status_bpjs, no_hp, pekerjaan, pendapatan_bulanan, jumlah_tanggungan, + status_rumah, kelurahan, kecamatan) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + $stmt = $conn->prepare($query); + if ($stmt === false) { + sendJSON('error', 'Gagal prepare statement: ' . $conn->error); + } + + $stmt->bind_param("sssssddsssiisss", $nama, $tanggal_lahir, $jenis_kelamin, $nik, $alamat, $latitude, $longitude, $status_bpjs, $no_hp, $pekerjaan, $pendapatan, $tanggungan, $status_rumah, $kelurahan, $kecamatan); + + if ($stmt->execute()) { + $id = $stmt->insert_id; + sendJSON('success', 'Data masyarakat berhasil disimpan', ['id' => $id]); + } else { + sendJSON('error', 'Gagal menyimpan data: ' . $stmt->error); + } + $stmt->close(); + +} else { + sendJSON('error', 'Method tidak diizinkan. Gunakan POST.'); +} +?> diff --git a/01/php/simpan_rumah_ibadah.php b/01/php/simpan_rumah_ibadah.php new file mode 100644 index 0000000..7d5838e --- /dev/null +++ b/01/php/simpan_rumah_ibadah.php @@ -0,0 +1,69 @@ +prepare($query); + if ($stmt === false) { + sendJSON('error', 'Gagal prepare statement: ' . $conn->error); + } + + $stmt->bind_param("ssddsssiss", $nama, $jenis, $latitude, $longitude, $alamat, $nama_pemimpin, $no_hp_pemimpin, $kapasitas, $tahun_sql, $keterangan); + + if ($stmt->execute()) { + $id = $stmt->insert_id; + sendJSON('success', 'Data rumah ibadah berhasil disimpan', ['id' => $id]); + } else { + sendJSON('error', 'Gagal menyimpan data: ' . $stmt->error); + } + $stmt->close(); + +} else { + sendJSON('error', 'Method tidak diizinkan. Gunakan POST.'); +} +?> diff --git a/01/php/test.php b/01/php/test.php new file mode 100644 index 0000000..9523b1e --- /dev/null +++ b/01/php/test.php @@ -0,0 +1,14 @@ +query("SELECT COUNT(*) FROM $table"); + if ($res) { + echo "$table count: " . $res->fetch_row()[0] . "\n"; + } else { + echo "$table error: " . $conn->error . "\n"; + } +} +?> diff --git a/01/php/update_lokasi_spbu.php b/01/php/update_lokasi_spbu.php new file mode 100644 index 0000000..4a2ebd8 --- /dev/null +++ b/01/php/update_lokasi_spbu.php @@ -0,0 +1,25 @@ +prepare("UPDATE fasilitas_spbu SET latitude = ?, longitude = ? WHERE id = ?"); +$stmt->bind_param("ddi", $latitude, $longitude, $id); + +if ($stmt->execute()) { + sendJSON('success', 'Lokasi SPBU berhasil diperbarui'); +} else { + sendJSON('error', 'Gagal memperbarui lokasi: ' . $stmt->error); +} +$stmt->close(); +?>