Initial commit: WebGIS Kemiskinan Pontianak
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
DB_HOST=localhost
|
||||
DB_USER=root
|
||||
DB_PASS=
|
||||
DB_NAME=webgis_pontianak
|
||||
@@ -0,0 +1 @@
|
||||
.env
|
||||
@@ -0,0 +1,521 @@
|
||||
# 🌏 WebGIS Kemiskinan & Jangkauan Bantuan
|
||||
|
||||
Sistem Informasi Geospasial interaktif untuk memetakan penduduk miskin dan menganalisis jangkauan bantuan dari rumah ibadah di Kota Pontianak, Kalimantan Barat.
|
||||
|
||||
---
|
||||
|
||||
## ✍️ Author
|
||||
Nama: Ferdyan Handoko
|
||||
NIM: D1041231039
|
||||
Kelas: SIG B
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Live Demo
|
||||
Sistem ini telah di-hosting dan dapat diakses langsung melalui tautan berikut:
|
||||
|
||||
Halaman Tautan
|
||||
🗺️ Halaman Publik https://pontianak-poverty-webgis.freedev.app/
|
||||
🔐 Halaman Login Admin https://pontianak-poverty-webgis.freedev.app/login.php
|
||||
|
||||
Kredensial Demo Admin:
|
||||
|
||||
Username: admin
|
||||
Password: admin123
|
||||
|
||||
⚠️ Catatan: Kredensial di atas hanya untuk keperluan demo. Ganti password setelah instalasi di server produksi.
|
||||
|
||||
---
|
||||
|
||||
## 📑 Daftar Isi
|
||||
|
||||
- [Deskripsi](#-deskripsi)
|
||||
- [Fitur Utama](#-fitur-utama)
|
||||
- [Teknologi yang Digunakan](#-teknologi-yang-digunakan)
|
||||
- [Persyaratan Sistem](#-persyaratan-sistem)
|
||||
- [Instalasi (dari Gitea)](#-instalasi-dari-gitea)
|
||||
- [Struktur Proyek](#-struktur-proyek)
|
||||
- [Konfigurasi .env](#-konfigurasi-env)
|
||||
- [Login Admin](#-login-admin)
|
||||
- [Cara Menggunakan](#-cara-menggunakan)
|
||||
- [Database Schema](#-database-schema)
|
||||
- [Data GeoJSON](#-data-geojson)
|
||||
- [Troubleshooting](#-troubleshooting)
|
||||
- [Keamanan](#-keamanan)
|
||||
- [Pengembangan Lebih Lanjut](#-pengembangan-lebih-lanjut)
|
||||
- [Kontribusi](#-kontribusi)
|
||||
- [Kontak & Support](#-kontak--support)
|
||||
- [Catatan Versi](#-catatan-versi)
|
||||
|
||||
---
|
||||
|
||||
## 📘 Deskripsi
|
||||
|
||||
Sistem ini dibangun untuk membantu pemangku kepentingan di Kota Pontianak dalam mengidentifikasi sebaran penduduk miskin yang belum terjangkau bantuan dari rumah ibadah. Dengan pendekatan WebGIS, pengguna dapat menjelajahi peta interaktif, melihat klasifikasi titik miskin (terjangkau / tidak), serta kerapatan penduduk per kecamatan.
|
||||
|
||||
Admin dapat mengelola data penduduk miskin langsung dari peta melalui antarmuka *sidebar*, sedangkan pengguna umum dapat melihat seluruh informasi tanpa bisa mengubah data.
|
||||
|
||||
---
|
||||
|
||||
## ✨ Fitur Utama
|
||||
|
||||
- **Peta Interaktif** berbasis OpenStreetMap dengan navigasi zoom, pan, dan tombol kontrol.
|
||||
- **6 Layer Geospasial:** Batas Kecamatan, Kerapatan Penduduk Belum Terjangkau, Zona Buffer, Titik Miskin, Fasilitas Umum, Jaringan Jalan, Rumah Ibadah.
|
||||
- **Klasifikasi Titik Miskin:** Hijau (terjangkau) dan Merah (belum terjangkau).
|
||||
- **Zona Jangkauan (Buffer Union):** Gabungan buffer dari seluruh rumah ibadah, radius dapat diubah secara dinamis.
|
||||
- **Dashboard Ringkasan:** Total titik miskin, jumlah keluarga, rata‑rata penghasilan, distribusi per kecamatan.
|
||||
- **Tabel Data Lengkap:** Dapat diurutkan (sort) dan diakses melalui modal.
|
||||
- **Manajemen Data Admin:** Tambah, edit, hapus titik penduduk miskin langsung dari peta atau tabel.
|
||||
- **Validasi Formulir & Konfirmasi Aksi:** Mencegah kesalahan input dan perubahan tidak disengaja.
|
||||
- **Loading Overlay** untuk umpan balik saat data dimuat.
|
||||
- **Toast Notification** untuk notifikasi sukses/gagal.
|
||||
- **Sidebar** dengan tab navigasi, kontrol layer, legenda, dan analisis.
|
||||
- **Login Admin** dengan password terenkripsi (hash).
|
||||
- **Keamanan Dasar:** Escape HTML (XSS), session PHP, prepared statements untuk query SQL.
|
||||
- **Responsif** (mobile‑friendly) melalui *drawer sidebar*.
|
||||
|
||||
---
|
||||
|
||||
## 🛠 Teknologi yang Digunakan
|
||||
|
||||
| Komponen | Teknologi |
|
||||
|------------------------|--------------------------------------------------------|
|
||||
| Frontend | HTML5, CSS3, JavaScript (ES6+), Leaflet JS, Turf.js |
|
||||
| Backend | PHP 7.4+ (prosedural) |
|
||||
| Database | MySQL / MariaDB |
|
||||
| Sumber Data Geospasial | File GeoJSON dari Overpass Turbo (data OpenStreetMap) |
|
||||
| Tile Peta | OpenStreetMap (gratis) |
|
||||
| Font | Inter (Google Fonts) |
|
||||
| Ikon | Emoji & SVG |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Persyaratan Sistem
|
||||
|
||||
- Server lokal: XAMPP, Laragon, atau sejenisnya dengan PHP 7.4+ dan MySQL 5.7+
|
||||
- Web browser modern: Google Chrome, Mozilla Firefox, Microsoft Edge
|
||||
- Koneksi internet (untuk memuat tile peta dan font)
|
||||
- Git (untuk clone repository)
|
||||
|
||||
---
|
||||
|
||||
## 📥 Instalasi (dari Gitea)
|
||||
|
||||
### 1. Clone Repository
|
||||
|
||||
```bash
|
||||
git clone https://your-gitea-instance.com/username/Web-SIG-Kemiskinan.git
|
||||
cd Web-SIG-Kemiskinan
|
||||
```
|
||||
|
||||
### 2. Persiapan Database
|
||||
|
||||
1. Buka phpMyAdmin atau client MySQL favorit Anda
|
||||
2. Jalankan script `schema.sql`:
|
||||
```sql
|
||||
source schema.sql;
|
||||
```
|
||||
Atau copy-paste isi file `schema.sql` dan jalankan di MySQL client
|
||||
3. Tabel berikut akan terbuat otomatis:
|
||||
- `admins` (username: admin, password sudah di-hash)
|
||||
- `poor_residents` (data penduduk miskin)
|
||||
- `settings` (pengaturan aplikasi seperti buffer_radius)
|
||||
|
||||
### 3. Konfigurasi Environment (.env)
|
||||
|
||||
1. Buat file `.env` di root project:
|
||||
```bash
|
||||
cp .env.example .env # atau buat file baru jika tidak ada .env.example
|
||||
```
|
||||
|
||||
2. Edit `.env` dengan kredensial database Anda:
|
||||
```
|
||||
DB_HOST=localhost
|
||||
DB_USER=root
|
||||
DB_PASS=
|
||||
DB_NAME=webgis_pontianak
|
||||
```
|
||||
|
||||
3. Sesuaikan nilai sesuai konfigurasi MySQL Anda
|
||||
|
||||
### 4. Setup Web Server
|
||||
|
||||
#### Menggunakan Laragon:
|
||||
- Copy folder `Web-SIG-Kemiskinan` ke folder `C:\laragon\www\`
|
||||
- Akses melalui `http://webgis-kemiskinan.test` (atau sesuai konfigurasi)
|
||||
|
||||
#### Menggunakan XAMPP:
|
||||
- Copy folder ke `C:\xampp\htdocs\Web-SIG-Kemiskinan\`
|
||||
- Akses melalui `http://localhost/Web-SIG-Kemiskinan`
|
||||
|
||||
### 5. Verifikasi Instalasi
|
||||
|
||||
- Buka browser dan akses aplikasi
|
||||
- Jika berhasil, Anda akan melihat **peta interaktif** dengan semua layer
|
||||
- Untuk login sebagai admin: **[Login Admin](#-login-admin)**
|
||||
|
||||
---
|
||||
|
||||
## 📂 Struktur Proyek
|
||||
|
||||
```
|
||||
Web-SIG-Kemiskinan/
|
||||
├── config.php # Konfigurasi database (pembaca file .env)
|
||||
├── index.php # Halaman utama peta interaktif
|
||||
├── login.php # Halaman login admin
|
||||
├── logout.php # Script logout
|
||||
├── save_poor.php # API: Tambah data penduduk miskin
|
||||
├── edit_poor.php # API: Edit data penduduk miskin
|
||||
├── delete_poor.php # API: Hapus data penduduk miskin
|
||||
├── update_settings.php # API: Update pengaturan (buffer radius)
|
||||
├── schema.sql # Script pembuatan database
|
||||
├── .env # File konfigurasi environment (tidak di-commit)
|
||||
├── README.md # Dokumentasi proyek
|
||||
└── json/ # Data GeoJSON (sumber data peta)
|
||||
├── Kecamatan_Pontianak.json
|
||||
├── Jalan_Pontianak.json
|
||||
├── Fasilitas_Pontianak.json
|
||||
├── Ibadah_Pontianak.json
|
||||
└── ...
|
||||
```
|
||||
|
||||
### Penjelasan File Utama
|
||||
|
||||
| File | Fungsi |
|
||||
|------|--------|
|
||||
| `config.php` | Koneksi database dan pembaca file `.env` |
|
||||
| `index.php` | Frontend utama dengan peta Leaflet dan logika JavaScript |
|
||||
| `login.php` | Form login dengan autentikasi password hash |
|
||||
| `save_poor.php` | AJAX endpoint untuk tambah data (admin only) |
|
||||
| `edit_poor.php` | AJAX endpoint untuk edit data (admin only) |
|
||||
| `delete_poor.php` | AJAX endpoint untuk hapus data (admin only) |
|
||||
| `update_settings.php` | AJAX endpoint untuk update buffer radius |
|
||||
| `schema.sql` | SQL script untuk setup database otomatis |
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Konfigurasi .env
|
||||
|
||||
Buat file `.env` di root project dengan isi berikut:
|
||||
|
||||
```env
|
||||
# Database Configuration
|
||||
DB_HOST=localhost
|
||||
DB_USER=root
|
||||
DB_PASS=
|
||||
DB_NAME=webgis_pontianak
|
||||
```
|
||||
|
||||
**Penjelasan:**
|
||||
- `DB_HOST`: Host database (biasanya localhost untuk lokal)
|
||||
- `DB_USER`: Username MySQL
|
||||
- `DB_PASS`: Password MySQL (kosong jika tidak ada)
|
||||
- `DB_NAME`: Nama database yang sudah dibuat
|
||||
|
||||
**Catatan Penting:**
|
||||
- File `.env` TIDAK boleh di-commit ke Git (tambahkan ke `.gitignore`)
|
||||
- Setiap developer harus membuat `.env` mereka sendiri dengan kredensial lokal
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Login Admin
|
||||
|
||||
### Kredensial Default
|
||||
|
||||
```
|
||||
Username: admin
|
||||
Password: admin
|
||||
```
|
||||
|
||||
**Catatan Keamanan:**
|
||||
- Password di-hash menggunakan `password_hash()` dengan algoritma bcrypt
|
||||
- Ubah password default setelah instalasi pertama kali
|
||||
- Password disimpan di tabel `admins` dengan hash, bukan plaintext
|
||||
|
||||
### Mengubah Password Admin
|
||||
|
||||
1. Login ke server database
|
||||
2. Update tabel `admins`:
|
||||
```sql
|
||||
UPDATE admins SET password = '$2y$10$NEW_HASH_HERE' WHERE username = 'admin';
|
||||
```
|
||||
|
||||
Untuk generate hash baru, gunakan script PHP:
|
||||
```php
|
||||
<?php
|
||||
$password = 'password_baru_anda';
|
||||
echo password_hash($password, PASSWORD_BCRYPT);
|
||||
?>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 Cara Menggunakan
|
||||
|
||||
### 1. Akses Aplikasi
|
||||
- Buka browser dan akses URL aplikasi (sesuai setup Anda)
|
||||
- Peta interaktif akan langsung terlihat
|
||||
|
||||
### 2. Navigasi Peta
|
||||
- **Zoom**: Gunakan scroll mouse atau tombol +/- di peta
|
||||
- **Pan**: Klik dan drag peta
|
||||
- **Tombol Kontrol**: Zoom in/out, fullscreen, lokasi saat ini
|
||||
|
||||
### 3. Menampilkan/Menyembunyikan Layer
|
||||
|
||||
**Menggunakan Tombol Top Bar:**
|
||||
- 🟣 **Buffer**: Zona jangkauan bantuan dari rumah ibadah
|
||||
- 🟢 **Density**: Kerapatan penduduk belum terjangkau
|
||||
- 🏥 **Fasilitas**: Fasilitas umum (puskesmas, sekolah, dll)
|
||||
- 🛣️ **Jalan**: Jaringan jalan
|
||||
- 🕌 **Ibadah**: Lokasi rumah ibadah
|
||||
- 🟧 **Kecamatan**: Batas-batas kecamatan
|
||||
|
||||
**Menggunakan Sidebar:**
|
||||
- Klik tab 🗂️ **Layer** untuk melihat daftar semua layer
|
||||
- Aktifkan/matikan layer dengan toggle switch
|
||||
|
||||
### 4. Melihat Legenda
|
||||
- Klik tab 📋 **Legenda** di sidebar
|
||||
- Legenda menjelaskan warna dan simbol di peta
|
||||
|
||||
### 5. Analisis Data
|
||||
- Klik tab 📊 **Analisis** di sidebar
|
||||
- Lihat statistik:
|
||||
- Total penduduk miskin
|
||||
- Total keluarga
|
||||
- Rata-rata penghasilan
|
||||
- Distribusi per kecamatan
|
||||
|
||||
### 6. Tabel Data Lengkap
|
||||
- Klik tab 📋 **Data** di sidebar atau tombol **Tabel** di top bar
|
||||
- Lihat daftar lengkap semua penduduk miskin
|
||||
- Tabel dapat diurutkan berdasarkan kolom (asc/desc)
|
||||
- **Admin**: Klik pada baris untuk edit/hapus
|
||||
|
||||
### 7. Mengelola Data (Admin Only)
|
||||
|
||||
#### Tambah Data Baru
|
||||
1. Klik tombol **+ Tambah Data** (hanya muncul jika login)
|
||||
2. Isi form modal:
|
||||
- Nama (wajib)
|
||||
- NIK
|
||||
- Jumlah Keluarga
|
||||
- Penghasilan (Rp)
|
||||
- RT/RW
|
||||
- Koordinat (lat/lng)
|
||||
3. Klik **Simpan**
|
||||
|
||||
#### Menambah Data via Klik Peta (Admin)
|
||||
1. Pastikan sudah login
|
||||
2. Aktifkan mode "Add Mode" (jika ada) atau klik kanan di peta
|
||||
3. Sistem akan membuka form dengan koordinat otomatis terisi
|
||||
4. Isi data lainnya dan simpan
|
||||
|
||||
#### Edit Data
|
||||
1. Klik pada titik di peta atau baris di tabel
|
||||
2. Ubah data di form modal
|
||||
3. Klik **Update**
|
||||
|
||||
#### Hapus Data
|
||||
1. Klik pada titik di peta atau baris di tabel
|
||||
2. Klik tombol **Hapus** atau **Delete**
|
||||
3. Konfirmasi penghapusan
|
||||
|
||||
### 8. Mengubah Buffer Radius
|
||||
1. Login sebagai admin
|
||||
2. Klik tab ⚙️ **Pengaturan** di sidebar
|
||||
3. Ubah nilai **Buffer Radius** (dalam meter)
|
||||
4. Klik **Simpan**
|
||||
5. Peta akan refresh dengan zona buffer yang baru
|
||||
|
||||
### 9. Logout
|
||||
- Klik tombol **Logout** di sidebar
|
||||
- Atau tutup sesi browser
|
||||
|
||||
---
|
||||
|
||||
## �📊 Database Schema
|
||||
|
||||
### Tabel: `admins`
|
||||
```sql
|
||||
CREATE TABLE admins (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
username VARCHAR(50) NOT NULL UNIQUE,
|
||||
password VARCHAR(255) NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
### Tabel: `poor_residents`
|
||||
```sql
|
||||
CREATE TABLE poor_residents (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
nik VARCHAR(16),
|
||||
family_size INT DEFAULT 1,
|
||||
income INT DEFAULT 0,
|
||||
rt_rw VARCHAR(20),
|
||||
lat DOUBLE NOT NULL,
|
||||
lng DOUBLE NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
```
|
||||
|
||||
### Tabel: `settings`
|
||||
```sql
|
||||
CREATE TABLE settings (
|
||||
setting_key VARCHAR(50) PRIMARY KEY,
|
||||
setting_value TEXT NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 Data GeoJSON
|
||||
|
||||
Data geospasial disimpan dalam folder `json/`:
|
||||
|
||||
| File | Keterangan |
|
||||
|------|-----------|
|
||||
| `Kecamatan_Pontianak.json` | Batas-batas wilayah kecamatan |
|
||||
| `Jalan_Pontianak.json` | Jaringan jalan di Pontianak |
|
||||
| `Fasilitas_Pontianak.json` | Fasilitas umum (puskesmas, sekolah, dll) |
|
||||
| `Ibadah_Pontianak.json` | Lokasi rumah ibadah |
|
||||
|
||||
Semua file GeoJSON berasal dari **Overpass Turbo** (query OpenStreetMap):
|
||||
- Format: GeoJSON standar dengan geometri dan properties
|
||||
- Proyeksi: WGS84 (EPSG:4326)
|
||||
- Digunakan untuk rendering layer di Leaflet
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Masalah: Peta tidak muncul
|
||||
- **Solusi**: Periksa koneksi internet, pastikan CDN Leaflet dapat diakses
|
||||
- **Alternatif**: Gunakan Leaflet offline atau host sendiri
|
||||
|
||||
### Masalah: Data tidak muncul di database
|
||||
- **Solusi**: Pastikan file `.env` benar dan database sudah dibuat via `schema.sql`
|
||||
- Cek koneksi database di phpMyAdmin
|
||||
|
||||
### Masalah: Login gagal
|
||||
- **Solusi**: Pastikan username `admin` ada di tabel `admins`
|
||||
- Gunakan password default: `admin`
|
||||
- Jika lupa, reset password via database
|
||||
|
||||
### Masalah: Layer GeoJSON tidak muncul
|
||||
- **Solusi**: Periksa file GeoJSON di folder `json/` ada lengkap
|
||||
- Buka browser console (F12) cek error messages
|
||||
- Pastikan path file GeoJSON benar di file `index.php`
|
||||
|
||||
### Masalah: Sidebar tidak merespons
|
||||
- **Solusi**: Clear cache browser (Ctrl+Shift+Delete)
|
||||
- Reload halaman (Ctrl+R atau F5)
|
||||
- Cek browser console untuk JavaScript error
|
||||
|
||||
---
|
||||
|
||||
## 🔒 Keamanan
|
||||
|
||||
Fitur keamanan yang diimplementasikan:
|
||||
|
||||
1. **Authentication**: Login dengan session PHP
|
||||
2. **Authorization**: Admin-only endpoints mengecek `$_SESSION['admin']`
|
||||
3. **Input Validation**: Prepared statements untuk mencegah SQL injection
|
||||
4. **Password Hashing**: Menggunakan `password_hash()` dengan bcrypt
|
||||
5. **Output Escaping**: Data divalidasi saat output ke HTML
|
||||
6. **CORS**: GET endpoint untuk GeoJSON dapat diakses publik
|
||||
7. **Session Management**: Logout menghapus session
|
||||
|
||||
**Catatan untuk Production:**
|
||||
- Gunakan HTTPS
|
||||
- Set cookie HttpOnly dan Secure
|
||||
- Implementasi CSRF protection
|
||||
- Rate limiting untuk login
|
||||
- Update PHP dan MySQL secara berkala
|
||||
- Backup database reguler
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Pengembangan Lebih Lanjut
|
||||
|
||||
### Fitur yang Bisa Ditambahkan
|
||||
- Export data (CSV, Excel, PDF)
|
||||
- Import data dari file bulk
|
||||
- Visualisasi grafik statistik
|
||||
- Filter data berdasarkan kriteria (RT/RW, range penghasilan, dll)
|
||||
- Heatmap real-time dengan WebSocket
|
||||
- Mobile app native (React Native, Flutter)
|
||||
- Multi-language support
|
||||
- Dark mode
|
||||
- API REST yang lebih lengkap
|
||||
|
||||
### Setup Development Environment
|
||||
|
||||
```bash
|
||||
# Install dependencies (jika menggunakan npm/composer)
|
||||
composer install # untuk PHP dependencies
|
||||
|
||||
# Setup local server dengan PHP built-in
|
||||
cd Web-SIG-Kemiskinan
|
||||
php -S localhost:8000
|
||||
|
||||
# Atau gunakan Laragon/XAMPP untuk development
|
||||
```
|
||||
|
||||
### Git Workflow
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://git.ifuntanhub.dev/FH/pontianak-poverty-webgis.git
|
||||
|
||||
# Buat branch baru untuk feature
|
||||
git checkout -b feature/nama-fitur
|
||||
|
||||
# Commit changes
|
||||
git add .
|
||||
git commit -m "feat: tambah fitur baru"
|
||||
|
||||
# Push ke remote
|
||||
git push origin feature/nama-fitur
|
||||
|
||||
# Buat Pull Request di Gitea
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 👥 Kontribusi
|
||||
|
||||
Kontribusi sangat diterima! Silahkan:
|
||||
|
||||
1. Fork repository
|
||||
2. Buat branch untuk feature/bugfix
|
||||
3. Commit dan push
|
||||
4. Buat Pull Request
|
||||
|
||||
---
|
||||
|
||||
## 📞 Kontak & Support
|
||||
|
||||
Untuk pertanyaan, laporan bug, atau saran:
|
||||
|
||||
- **Email**: [d1041231039@student.untan.ac.id](mailto:d1041231039@student.untan.ac.id)
|
||||
|
||||
---
|
||||
|
||||
## 📝 Catatan Versi
|
||||
|
||||
### v1.0 (Current)
|
||||
- ✅ Peta interaktif dengan 7 layer geospasial
|
||||
- ✅ Dashboard dan statistik
|
||||
- ✅ CRUD data penduduk miskin
|
||||
- ✅ Login admin dengan password hash
|
||||
- ✅ Buffer radius dinamis
|
||||
- ✅ Responsif mobile
|
||||
- ✅ Validasi form dan data
|
||||
|
||||
---
|
||||
|
||||
*Last Updated: June 3, 2026*
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
function loadEnv($path) {
|
||||
if (!file_exists($path)) return;
|
||||
$lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
foreach ($lines as $line) {
|
||||
if (strpos(trim($line), '#') === 0) continue;
|
||||
$parts = explode('=', $line, 2);
|
||||
if (count($parts) === 2) {
|
||||
$_ENV[trim($parts[0])] = trim($parts[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loadEnv(__DIR__ . '/.env');
|
||||
|
||||
$host = $_ENV['DB_HOST'] ?? 'localhost';
|
||||
$user = $_ENV['DB_USER'] ?? 'root';
|
||||
$pass = $_ENV['DB_PASS'] ?? '';
|
||||
$db = $_ENV['DB_NAME'] ?? 'webgis_pontianak';
|
||||
|
||||
$conn = mysqli_connect($host, $user, $pass, $db);
|
||||
if (!$conn) {
|
||||
die('Koneksi gagal: ' . mysqli_connect_error());
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (!isset($_SESSION['admin'])) die('Unauthorized');
|
||||
require 'config.php';
|
||||
|
||||
$id = $_POST['id'] ?? 0;
|
||||
$stmt = $conn->prepare("DELETE FROM poor_residents WHERE id = ?");
|
||||
$stmt->bind_param("i", $id);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
echo json_encode(['success' => true, 'message' => 'Data berhasil dihapus']);
|
||||
} else {
|
||||
http_response_code(500);
|
||||
echo json_encode(['success' => false, 'message' => 'Gagal menghapus data: ' . $stmt->error]);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (!isset($_SESSION['admin'])) die('Unauthorized');
|
||||
require 'config.php';
|
||||
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
$name = trim($_POST['name'] ?? '');
|
||||
$nik = trim($_POST['nik'] ?? '');
|
||||
$family = (int)($_POST['family_size'] ?? 1);
|
||||
$income = (int)($_POST['income'] ?? 0);
|
||||
$rt_rw = trim($_POST['rt_rw'] ?? '-');
|
||||
$lat = (float)($_POST['lat'] ?? 0);
|
||||
$lng = (float)($_POST['lng'] ?? 0);
|
||||
|
||||
if ($id === 0 || $name === '') die('Data tidak lengkap');
|
||||
|
||||
$stmt = $conn->prepare("UPDATE poor_residents SET name=?, nik=?, family_size=?, income=?, rt_rw=?, lat=?, lng=? WHERE id=?");
|
||||
$stmt->bind_param("ssiisddi", $name, $nik, $family, $income, $rt_rw, $lat, $lng, $id);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
echo json_encode(['success' => true, 'message' => 'Data berhasil diupdate']);
|
||||
} else {
|
||||
http_response_code(500);
|
||||
echo json_encode(['success' => false, 'message' => 'Gagal mengupdate data: ' . $stmt->error]);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+428095
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
session_start();
|
||||
require 'config.php';
|
||||
|
||||
if (isset($_SESSION['admin'])) {
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$error = '';
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$username = $_POST['username'] ?? '';
|
||||
$password = $_POST['password'] ?? '';
|
||||
|
||||
$stmt = $conn->prepare("SELECT id, password FROM admins WHERE username = ?");
|
||||
$stmt->bind_param("s", $username);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($row = $result->fetch_assoc()) {
|
||||
if (password_verify($password, $row['password'])) {
|
||||
$_SESSION['admin'] = $row['id'];
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
} else {
|
||||
$error = 'Password salah!';
|
||||
}
|
||||
} else {
|
||||
$error = 'Username tidak ditemukan!';
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="id">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Login Admin - WebGIS Pontianak</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap');
|
||||
* { margin:0; padding:0; box-sizing:border-box; }
|
||||
body {
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: linear-gradient(135deg, #0f172a 0%, #1e1b4b 40%, #312e81 100%);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
height: 100vh;
|
||||
}
|
||||
.login-container {
|
||||
background: rgba(255,255,255,0.97); border-radius: 28px;
|
||||
padding: 48px 40px; width: 440px; max-width: 92vw;
|
||||
box-shadow: 0 32px 100px rgba(0,0,0,0.35);
|
||||
animation: slideUp 0.7s ease;
|
||||
}
|
||||
@keyframes slideUp {
|
||||
from { opacity:0; transform: translateY(50px) scale(0.97); }
|
||||
to { opacity:1; transform: translateY(0) scale(1); }
|
||||
}
|
||||
.login-logo { text-align:center; margin-bottom:36px; }
|
||||
.logo-ring {
|
||||
width:80px; height:80px; border-radius:24px; margin:0 auto 16px;
|
||||
background: linear-gradient(135deg,#6366f1,#8b5cf6);
|
||||
display:flex; align-items:center; justify-content:center;
|
||||
box-shadow: 0 8px 32px rgba(99,102,241,0.4);
|
||||
}
|
||||
.logo-ring svg { width:40px; height:40px; fill:white; }
|
||||
.login-logo h1 { font-size:24px; font-weight:800; color:#1e293b; }
|
||||
.login-logo p { font-size:13px; color:#64748b; margin-top:6px; }
|
||||
.form-group { margin-bottom:18px; }
|
||||
.form-group label {
|
||||
display:block; font-size:12px; font-weight:600;
|
||||
color:#64748b; margin-bottom:6px; text-transform:uppercase;
|
||||
}
|
||||
.form-group input {
|
||||
width:100%; padding:12px 16px; border:2px solid #e2e8f0;
|
||||
border-radius:8px; font-size:14px; font-family:inherit;
|
||||
background:#f1f5f9; outline:none; transition:all 0.2s;
|
||||
}
|
||||
.form-group input:focus {
|
||||
border-color:#6366f1; background:white;
|
||||
box-shadow:0 0 0 4px rgba(99,102,241,0.1);
|
||||
}
|
||||
.login-btn {
|
||||
width:100%; padding:14px; background:linear-gradient(135deg,#6366f1,#8b5cf6);
|
||||
color:white; border:none; border-radius:8px; font-size:15px;
|
||||
font-weight:700; cursor:pointer; font-family:inherit;
|
||||
box-shadow:0 4px 16px rgba(99,102,241,0.3); transition:all 0.3s;
|
||||
}
|
||||
.login-btn:hover { transform:translateY(-2px); box-shadow:0 8px 24px rgba(99,102,241,0.4); }
|
||||
.error { color:#ef4444; text-align:center; margin-bottom:10px; font-size:13px; }
|
||||
.back-link { display:block; text-align:center; margin-top:20px; color:#64748b; text-decoration:none; font-size:13px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="login-container">
|
||||
<div class="login-logo">
|
||||
<div class="logo-ring">
|
||||
<svg viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/></svg>
|
||||
</div>
|
||||
<h1>WebGIS Kemiskinan</h1>
|
||||
<p>Kota Pontianak, Kalimantan Barat</p>
|
||||
</div>
|
||||
<?php if ($error): ?>
|
||||
<p class="error"><?= htmlspecialchars($error) ?></p>
|
||||
<?php endif; ?>
|
||||
<form method="POST">
|
||||
<div class="form-group">
|
||||
<label>Username</label>
|
||||
<input type="text" name="username" placeholder="Masukkan username" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Password</label>
|
||||
<input type="password" name="password" placeholder="Masukkan password" required>
|
||||
</div>
|
||||
<button type="submit" class="login-btn">🔐 Masuk ke Panel Admin</button>
|
||||
</form>
|
||||
<a href="index.php" class="back-link">← Kembali ke Peta Publik</a>
|
||||
<p style="text-align:center;margin-top:12px;font-size:11px;color:#94a3b8;">Demo: username <b>admin</b>, password <b>admin123</b></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
session_start();
|
||||
session_destroy();
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (!isset($_SESSION['admin'])) die('Unauthorized');
|
||||
require 'config.php';
|
||||
|
||||
$name = trim($_POST['name'] ?? '');
|
||||
$nik = trim($_POST['nik'] ?? '');
|
||||
$family = (int)($_POST['family_size'] ?? 1);
|
||||
$income = (int)($_POST['income'] ?? 0);
|
||||
$rt_rw = trim($_POST['rt_rw'] ?? '-');
|
||||
$lat = (float)($_POST['lat'] ?? 0);
|
||||
$lng = (float)($_POST['lng'] ?? 0);
|
||||
|
||||
if ($name === '') {
|
||||
http_response_code(400);
|
||||
echo json_encode(['success' => false, 'message' => 'Nama wajib diisi']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("INSERT INTO poor_residents (name, nik, family_size, income, rt_rw, lat, lng) VALUES (?, ?, ?, ?, ?, ?, ?)");
|
||||
$stmt->bind_param("ssiisdd", $name, $nik, $family, $income, $rt_rw, $lat, $lng);
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if ($stmt->execute()) {
|
||||
echo json_encode(['success' => true, 'message' => 'Data berhasil disimpan']);
|
||||
} else {
|
||||
http_response_code(500);
|
||||
echo json_encode(['success' => false, 'message' => 'Gagal menyimpan: ' . $stmt->error]);
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
CREATE DATABASE IF NOT EXISTS webgis_pontianak;
|
||||
USE webgis_pontianak;
|
||||
|
||||
CREATE TABLE admins (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
username VARCHAR(50) NOT NULL UNIQUE,
|
||||
password VARCHAR(255) NOT NULL
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
INSERT INTO admins (username, password) VALUES
|
||||
('admin', '$2y$10$g356t75x6pjEidqWWu3yaOR7H3eBUaZJ5QY47DAP61EHzJvnJBT8a');
|
||||
|
||||
CREATE TABLE poor_residents (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
nik VARCHAR(16) DEFAULT NULL,
|
||||
family_size INT NOT NULL DEFAULT 1,
|
||||
income INT NOT NULL DEFAULT 0,
|
||||
rt_rw VARCHAR(20) DEFAULT NULL,
|
||||
lat DOUBLE NOT NULL,
|
||||
lng DOUBLE NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
INSERT INTO poor_residents (name, nik, family_size, income, rt_rw, lat, lng) VALUES
|
||||
('Rahmat Hidayat', '6171012345670001', 4, 750000, '002/003', -0.048, 109.325),
|
||||
('Siti Maryam', '6171012345670002', 5, 600000, '001/002', -0.055, 109.332),
|
||||
('Budi Gunawan', '6171012345670003', 3, 900000, '004/001', -0.042, 109.345),
|
||||
('Dewi Sartika', '6171012345670004', 6, 480000, '003/005', -0.048, 109.355),
|
||||
('Eko Widodo', '6171012345670005', 4, 820000, '005/002', -0.040, 109.310),
|
||||
('Fitriani', '6171012345670006', 3, 1100000, '002/004', -0.058, 109.338),
|
||||
('Gunadi', '6171012345670007', 7, 350000, '001/001', -0.052, 109.360),
|
||||
('Hesti Nuraini', '6171012345670008', 2, 1200000, '006/003', -0.035, 109.318);
|
||||
|
||||
-- Tabel pengaturan
|
||||
CREATE TABLE settings (
|
||||
setting_key VARCHAR(50) PRIMARY KEY,
|
||||
setting_value TEXT NOT NULL
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
INSERT INTO settings (setting_key, setting_value) VALUES ('buffer_radius', '500');
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (!isset($_SESSION['admin'])) {
|
||||
http_response_code(403);
|
||||
echo 'Unauthorized';
|
||||
exit;
|
||||
}
|
||||
require 'config.php';
|
||||
$key = $_POST['key'] ?? '';
|
||||
$value = $_POST['value'] ?? '';
|
||||
if ($key === '' || $value === '') {
|
||||
http_response_code(400);
|
||||
echo 'Missing key or value';
|
||||
exit;
|
||||
}
|
||||
$stmt = $conn->prepare("REPLACE INTO settings (setting_key, setting_value) VALUES (?, ?)");
|
||||
$stmt->bind_param("ss", $key, $value);
|
||||
$stmt->execute();
|
||||
echo 'ok';
|
||||
Reference in New Issue
Block a user