function startAdd(type) { cancelMapClick(); const btnId = type === 'ri' ? 'btn-add-ri' : 'btn-add-pm'; const label = type === 'ri' ? 'lokasi Rumah Ibadah' : 'lokasi Penduduk Miskin'; document.getElementById(btnId).classList.add('active'); showInstruction(`Klik di peta untuk menentukan ${label}`); onceMapClick((lat, lng) => { document.getElementById(btnId).classList.remove('active'); hideInstruction(); if (type === 'ri') openRIForm(null, lat, lng); else openPMForm(null, lat, lng); }); } function openRIForm(data, lat, lng) { const isEdit = !!data; const fLat = isEdit ? data.latitude : lat; const fLng = isEdit ? data.longitude : lng; const isAdmin = window.currentUser && window.currentUser.role === 'admin'; const accountFieldsHTML = isAdmin ? `
Akun Rumah Ibadah
` : ''; openModal(isEdit ? 'Edit Rumah Ibadah' : 'Tambah Rumah Ibadah', `
📍 Koordinat: ${fLat.toFixed(7)}, ${fLng.toFixed(7)}
${accountFieldsHTML}`, ` `); // Attach dynamic username locking listener if (isAdmin) { const namaEl = document.getElementById('ri-nama'); const usernameEl = document.getElementById('ri-username'); if (namaEl && usernameEl) { namaEl.addEventListener('input', () => { usernameEl.value = namaEl.value .toLowerCase() .replace(/[^a-z0-9]/g, '_') .replace(/_+/g, '_') .replace(/^_+|_+$/g, ''); }); } } // Geocode address asynchronously if (!isEdit) { getAddressFromCoords(fLat, fLng).then(addr => { const el = document.getElementById('ri-alamat'); if (el && el.value === 'Memuat alamat otomatis...') { el.value = addr || ''; } }); } } async function saveRI(id, lat, lng) { const usernameEl = document.getElementById('ri-username'); const passwordEl = document.getElementById('ri-password'); const body = { nama: document.getElementById('ri-nama').value.trim(), jenis: document.getElementById('ri-jenis').value, alamat: document.getElementById('ri-alamat').value.trim(), no_wa: document.getElementById('ri-nowa').value.trim(), latitude: lat, longitude: lng, radius_meter: parseInt(document.getElementById('ri-radius').value), username: usernameEl ? usernameEl.value.trim() : '', password: passwordEl ? passwordEl.value : '' }; if (!body.nama) return toast('Nama wajib diisi', 'error'); // Validate account password for new Rumah Ibadah const isAdmin = window.currentUser && window.currentUser.role === 'admin'; if (isAdmin && !id) { if (!body.username) return toast('Username Rumah Ibadah wajib terisi', 'error'); if (!body.password) return toast('Password Rumah Ibadah wajib diisi', 'error'); } const res = await callAPI(id ? `rumah_ibadah.php?id=${id}` : 'rumah_ibadah.php', id ? 'PUT' : 'POST', body); if (res.status === 'success') { toast(res.message, 'success'); closeModal(); await recalcAllProximity(); switchTab('rumah_ibadah'); } else { toast(res.message, 'error'); } } function openPMForm(data, lat, lng) { const isEdit = !!data; const fLat = isEdit ? data.latitude : lat; const fLng = isEdit ? data.longitude : lng; openModal(isEdit ? 'Edit Penduduk Miskin' : 'Tambah Penduduk Miskin', `
📍 Koordinat: ${fLat.toFixed(7)}, ${fLng.toFixed(7)}
`, ` `); // Geocode address asynchronously if (!isEdit) { getAddressFromCoords(fLat, fLng).then(addr => { const el = document.getElementById('pm-alamat'); if (el && el.value === 'Memuat alamat otomatis...') { el.value = addr || ''; } }); } } async function savePM(id, lat, lng) { const body = { nama: document.getElementById('pm-nama').value.trim(), no_wa: document.getElementById('pm-nowa').value.trim(), nik: document.getElementById('pm-nik').value.trim(), alamat: document.getElementById('pm-alamat').value.trim(), jumlah_anggota: parseInt(document.getElementById('pm-jml').value) || 1, latitude: lat, longitude: lng }; if (!body.nama) return toast('Nama wajib diisi', 'error'); const res = await callAPI(id ? `penduduk_miskin.php?id=${id}` : 'penduduk_miskin.php', id ? 'PUT' : 'POST', body); if (res.status === 'success') { toast(res.message, 'success'); closeModal(); switchTab('penduduk_miskin'); } else { toast(res.message, 'error'); } } async function editRI(id) { map.closePopup(); const res = await callAPI(`rumah_ibadah.php?id=${id}`); if (res.data) openRIForm(res.data, res.data.latitude, res.data.longitude); } async function deleteRI(id) { if (!confirm('Hapus rumah ibadah ini?')) return; const res = await callAPI(`rumah_ibadah.php?id=${id}`, 'DELETE'); if (res.status === 'success') { toast('Dihapus', 'success'); map.closePopup(); await recalcAllProximity(); switchTab('rumah_ibadah'); } } async function editPM(id) { map.closePopup(); const res = await callAPI(`penduduk_miskin.php?id=${id}`); if (res.data) openPMForm(res.data, res.data.latitude, res.data.longitude); } async function deletePM(id) { if (!confirm('Hapus data ini?')) return; const res = await callAPI(`penduduk_miskin.php?id=${id}`, 'DELETE'); if (res.status === 'success') { toast('Dihapus', 'success'); map.closePopup(); await recalcAllProximity(); switchTab('penduduk_miskin'); } } // Haversine formula — returns distance in meters between two lat/lng points