diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cc91f52 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ + +# Coolify Local Debugger config +.env +.coolify-local.json +Dockerfile.coolify diff --git a/01/.gitignore b/01/.gitignore index 03966d8..57f0d99 100644 --- a/01/.gitignore +++ b/01/.gitignore @@ -15,3 +15,8 @@ access_log # OS generated files .DS_Store Thumbs.db + +# Coolify Local Debugger config +.env +.coolify-local.json +Dockerfile.coolify diff --git a/01/Dockerfile b/01/Dockerfile index dcdc8f5..292e8c6 100644 --- a/01/Dockerfile +++ b/01/Dockerfile @@ -5,8 +5,7 @@ FROM php:8.1-apache WORKDIR /var/www/html # Install system dependencies -RUN apt-get update && apt-get install -y \ - mysql-client \ +RUN apt-get update && (apt-get install -y mysql-client || apt-get install -y default-mysql-client) && apt-get install -y \ git \ curl \ zip \ diff --git a/01/dashboard.html b/01/dashboard.html index 7a8ab88..f1800b2 100644 --- a/01/dashboard.html +++ b/01/dashboard.html @@ -611,7 +611,7 @@
| Nama Tabel | +Status Keberadaan | +Jumlah Baris Data | +Tindakan Sistem | +
|---|---|---|---|
| + | + + Tersedia + + Tidak Ditemukan + + | +baris | ++ + + + | +
diff --git a/01/docker-compose.yml b/01/docker-compose.yml index a7a135d..6855ccc 100644 --- a/01/docker-compose.yml +++ b/01/docker-compose.yml @@ -11,6 +11,11 @@ services: - .:/var/www/html environment: - APP_ENV=development + - DB_HOST=mysql + - DB_USER=root + - DB_PASSWORD=root_password + - DB_DATABASE=pemetaan_kemiskinan + - DB_PORT=3306 depends_on: - mysql networks: diff --git a/01/js/main.js b/01/js/main.js index 55da330..390b71a 100644 --- a/01/js/main.js +++ b/01/js/main.js @@ -634,12 +634,31 @@ function attachEventListeners() { const form_jalan = document.getElementById('form-jalan'); const form_polygon = document.getElementById('form-polygon'); const form_spbu = document.getElementById('form-spbu'); + const form_bantuan = document.getElementById('form-bantuan'); 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(); }); + if (form_bantuan) form_bantuan.addEventListener('submit', function(e) { e.preventDefault(); submitFormBantuan(); }); + + // BPJS Fields Toggle + const bpjs_status_select = document.getElementById('form-status-bpjs'); + const bpjs_detail_fields = document.getElementById('bpjs-detail-fields'); + if (bpjs_status_select && bpjs_detail_fields) { + bpjs_status_select.addEventListener('change', function() { + if (this.value === 'Ya') { + bpjs_detail_fields.style.display = 'block'; + const dateInput = bpjs_detail_fields.querySelector('input[type="date"]'); + if (dateInput && !dateInput.value) { + dateInput.value = new Date().toISOString().substring(0, 10); + } + } else { + bpjs_detail_fields.style.display = 'none'; + } + }); + } // Shortcut keyboard untuk membuka formulir penambahan data baru document.addEventListener('keydown', function(e) { @@ -757,8 +776,30 @@ function submitFormMasyarakat() { .then(handleFetchResponse) .then(result => { if (result.status === 'success') { + // Tambahkan detail BPJS jika status_bpjs adalah Ya + const status_bpjs = form_data.get('status_bpjs'); + if (status_bpjs === 'Ya') { + const bpjs_data = new FormData(); + bpjs_data.append('id_masyarakat', result.data.id); + bpjs_data.append('no_peserta', form_data.get('bpjs_no_peserta')); + bpjs_data.append('jenis_bpjs', form_data.get('bpjs_jenis_bpjs')); + bpjs_data.append('tingkat', form_data.get('bpjs_tingkat')); + bpjs_data.append('status_aktif', form_data.get('bpjs_status_aktif')); + bpjs_data.append('tanggal_daftar', form_data.get('bpjs_tanggal_daftar')); + bpjs_data.append('faskes_tingkat_1', form_data.get('bpjs_faskes_tingkat_1')); + + fetch(API_PATH + 'simpan_bpjs.php', { + method: 'POST', + body: bpjs_data + }) + .then(handleFetchResponse) + .catch(err => console.error("Gagal menyimpan detail BPJS:", err)); + } + showAlert('alert-form', 'Data berhasil disimpan!', 'success'); form.reset(); + const bpjs_detail_fields = document.getElementById('bpjs-detail-fields'); + if (bpjs_detail_fields) bpjs_detail_fields.style.display = 'none'; setTimeout(() => { closeModal('modal-form-masyarakat'); loadMasyarakat(); @@ -879,7 +920,45 @@ function hapusData(tipe, id) { } function editBantuan(id) { - alert('Fitur tambah bantuan dengan ID ' + id + ' akan ditambahkan segera'); + const form = document.getElementById('form-bantuan'); + if (form) form.reset(); + + const idInput = document.getElementById('bantuan-id-masyarakat'); + if (idInput) idInput.value = id; + + const dateInput = document.querySelector('#form-bantuan input[name="tanggal_bantuan"]'); + if (dateInput) dateInput.value = new Date().toISOString().substring(0, 10); + + openModal('modal-form-bantuan'); +} + +function submitFormBantuan() { + const form = document.getElementById('form-bantuan'); + if (!form) return; + const form_data = new FormData(form); + + fetch(API_PATH + 'simpan_bantuan.php', { + method: 'POST', + body: form_data + }) + .then(handleFetchResponse) + .then(result => { + if (result.status === 'success') { + showAlert('alert-form-bantuan', 'Riwayat bantuan berhasil disimpan!', 'success'); + form.reset(); + const citizenId = form_data.get('id_masyarakat'); + setTimeout(() => { + closeModal('modal-form-bantuan'); + // Refresh detail modal + showDetail(citizenId); + }, 1000); + } else { + showAlert('alert-form-bantuan', result.message || 'Gagal menyimpan riwayat bantuan.', 'error'); + } + }) + .catch(error => { + showAlert('alert-form-bantuan', 'Terjadi kesalahan sistem: ' + error.message, 'error'); + }); } function openModal(modalId) { diff --git a/01/php/db_check.php b/01/php/db_check.php new file mode 100644 index 0000000..f2d5424 --- /dev/null +++ b/01/php/db_check.php @@ -0,0 +1,402 @@ +connect_error) { + $errors[] = "Koneksi database gagal: " . $conn->connect_error; +} else { + $success_logs[] = "Koneksi ke database `{$database}` berhasil!"; +} + +// 2. Baca file database.sql untuk mengambil DDL jika tabel perlu dibuat +$sql_content = ''; +$sql_file = __DIR__ . '/../database.sql'; +if (file_exists($sql_file)) { + $sql_content = file_get_contents($sql_file); + $success_logs[] = "File `database.sql` ditemukan dan berhasil dibaca."; +} else { + $errors[] = "File `database.sql` tidak ditemukan di {$sql_file}. Skrip akan menggunakan DDL cadangan."; +} + +// Helper untuk eksekusi query pembuatan tabel cadangan jika database.sql tidak ada +$fallback_ddl = [ + '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 + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;", + + '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 + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;", + + '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 + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;", + + '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 + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;", + + 'users' => "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;", + + '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;", + + '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;", + + '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;" +]; + +// Cek dan buat tabel jika belum ada +foreach ($required_tables as $table) { + $check_table = $conn->query("SHOW TABLES LIKE '{$table}'"); + if ($check_table && $check_table->num_rows > 0) { + // Tabel ada, cek jumlah baris + $count_res = $conn->query("SELECT COUNT(*) as total FROM `{$table}`"); + $count = $count_res ? $count_res->fetch_assoc()['total'] : 0; + $table_status[$table] = [ + 'exists' => true, + 'count' => $count, + 'action' => 'No action needed' + ]; + } else { + // Tabel tidak ada, coba buat dari file SQL + $created = false; + if (!empty($sql_content)) { + // parsing DDL dari sql_content secara sederhana (karena multi_query bisa lambat / error untuk tabel spesifik) + // Sebagai alternatif, jalankan DDL cadangan agar 100% aman dan presisi + $ddl = $fallback_ddl[$table] ?? ''; + if ($ddl && $conn->query($ddl)) { + $created = true; + } + } else { + $ddl = $fallback_ddl[$table] ?? ''; + if ($ddl && $conn->query($ddl)) { + $created = true; + } + } + + if ($created) { + $table_status[$table] = [ + 'exists' => true, + 'count' => 0, + 'action' => 'Table created successfully' + ]; + $success_logs[] = "Tabel `{$table}` berhasil dibuat karena tidak ditemukan."; + } else { + $table_status[$table] = [ + 'exists' => false, + 'count' => 0, + 'action' => 'Failed to create: ' . $conn->error + ]; + $errors[] = "Gagal membuat tabel `{$table}`: " . $conn->error; + } + } +} + +// 3. Cek Default Admin User +if (isset($table_status['users']) && $table_status['users']['exists']) { + $check_admin = $conn->query("SELECT id FROM users WHERE username = 'admin'"); + if ($check_admin && $check_admin->num_rows === 0) { + $insert_admin = $conn->query("INSERT INTO `users` (`username`, `password`, `nama_lengkap`, `role`) VALUES + ('admin', '5f4dcc3b5aa765d61d8327deb882cf99', 'Administrator', 'Admin')"); + if ($insert_admin) { + $success_logs[] = "Akun default admin berhasil ditambahkan."; + $table_status['users']['count'] += 1; + } else { + $errors[] = "Gagal menambahkan akun default admin: " . $conn->error; + } + } +} + +// 4. Masukkan Data Sampel jika tabel kosong +if (isset($table_status['masyarakat_miskin']) && $table_status['masyarakat_miskin']['exists'] && $table_status['masyarakat_miskin']['count'] == 0) { + $insert_sampel = $conn->query("INSERT INTO `masyarakat_miskin` + (`id`, `nama`, `tanggal_lahir`, `jenis_kelamin`, `nik`, `alamat`, `latitude`, `longitude`, `status_bpjs`, `no_hp`, `pekerjaan`, `pendapatan_bulanan`, `jumlah_tanggungan`, `status_rumah`, `kelurahan`, `kecamatan`) VALUES + (1, 'Siti Nur Azizah', '1985-03-15', 'Perempuan', '6101234567890123', 'Jl. Mahakam No. 25', -0.06120000, 109.34450000, 'Ya', '081234567890', 'Buruh Harian', 1500000, 4, 'Menumpang', 'Sungai Jawi', 'Pontianak Kota')"); + if ($insert_sampel) { + $success_logs[] = "Data sampel warga `Siti Nur Azizah` berhasil ditambahkan."; + $table_status['masyarakat_miskin']['count'] = 1; + + // Tambahkan juga riwayat bantuan dan BPJS record yang cocok + $conn->query("INSERT INTO `bpjs_record` (`id_masyarakat`, `no_peserta`, `jenis_bpjs`, `tingkat`, `tanggal_daftar`, `status_aktif`, `faskes_tingkat_1`) VALUES + (1, '0001234567890', 'Kesehatan', 'Penerima Bantuan Iuran (PBI)', '2020-01-15', 'Aktif', 'Puskesmas Pontianak Kota')"); + + $conn->query("INSERT INTO `bantuan_riwayat` (`id_masyarakat`, `jenis_bantuan`, `tanggal_bantuan`, `nilai`, `satuan`, `keterangan`, `nama_pemberi`) VALUES + (1, 'Bantuan Pangan Non Tunai (BPNT)', '2026-05-10', 200000, 'Rupiah/Bulan', 'Bantuan Sembako tahap V', 'Dinas Sosial')"); + + $success_logs[] = "Data sampel BPJS & Riwayat Bantuan berhasil dihubungkan ke warga."; + } +} + +if (isset($table_status['rumah_ibadah']) && $table_status['rumah_ibadah']['exists'] && $table_status['rumah_ibadah']['count'] == 0) { + $insert_sampel_ibadah = $conn->query("INSERT INTO `rumah_ibadah` (`nama`, `jenis`, `latitude`, `longitude`, `alamat`, `nama_pemimpin`, `no_hp_pemimpin`, `kapasitas`, `tahun_didirikan`) VALUES + ('Masjid Al-Hidayah', 'Masjid', -0.06150000, 109.34500000, 'Jl. Diponegoro No. 45', 'Ustaz Ahmad', '081234567890', 500, 2005), + ('Gereja Hati Kudus', 'Gereja', -0.06100000, 109.34400000, 'Jl. Jend Sudirman No. 12', 'Pdt. Bonaventura', '081234567891', 300, 1995)"); + if ($insert_sampel_ibadah) { + $success_logs[] = "Data sampel rumah ibadah (Masjid & Gereja) berhasil ditambahkan."; + $table_status['rumah_ibadah']['count'] = 2; + } +} + +// Bersihkan buffer output +ob_end_clean(); + +// Tampilkan halaman Laporan Diagnostik +?> + + +
+ + +
+ + + +
+