feat: Plan 2 — Form Edit Rumah Ibadah & Keluarga Miskin + Ownership

- Add user_id FK (nullable) to rumah_ibadah for ownership tracking
- IbadahController: set user_id on store; enforce ownership on update/destroy
- Add edit modals to map and data views (ibadah + miskin)
- Popup and table row Edit buttons with per-record ownership check
- 7 new tests covering ownership and full-field updates
- Fix ExampleTest for auth-protected routes
- Fix UserFactory missing email_verified_at column
- Mark Plan 2 complete in missing_features.md; update README

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
GuavaPopper
2026-06-02 20:29:36 +07:00
parent 15294a5d2f
commit 2e2b42f96b
11 changed files with 744 additions and 28 deletions
+229 -5
View File
@@ -157,6 +157,120 @@
</div>
</main>
<!-- Modal: Edit Rumah Ibadah -->
<dialog id="modal_edit_ibadah" class="modal">
<div class="modal-box w-11/12 max-w-lg">
<h3 class="font-bold text-lg mb-4">
<i class="fa-solid fa-mosque mr-2 text-success"></i>Edit Rumah Ibadah
</h3>
<input type="hidden" id="edit_ib_id">
<div class="grid grid-cols-2 gap-3">
<div class="form-control col-span-2">
<label class="label"><span class="label-text font-bold">Nama *</span></label>
<input id="edit_ib_nama" type="text" class="input input-bordered w-full" placeholder="Nama rumah ibadah">
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Jenis</span></label>
<select id="edit_ib_jenis" class="select select-bordered w-full">
<option value="">Pilih Jenis</option>
<option value="masjid">Masjid</option>
<option value="gereja">Gereja</option>
<option value="pura">Pura</option>
<option value="klenteng">Klenteng</option>
<option value="vihara">Vihara</option>
</select>
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Radius Analisis (m)</span></label>
<input id="edit_ib_radius" type="number" class="input input-bordered w-full" value="500" min="50" max="2000">
</div>
<div class="form-control col-span-2">
<label class="label"><span class="label-text font-bold">Alamat</span></label>
<textarea id="edit_ib_alamat" class="textarea textarea-bordered w-full" rows="2" placeholder="Alamat lengkap"></textarea>
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Pengurus</span></label>
<input id="edit_ib_pengurus" type="text" class="input input-bordered w-full" placeholder="Nama pengurus">
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Telepon</span></label>
<input id="edit_ib_telepon" type="text" class="input input-bordered w-full" placeholder="No. telepon">
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Jumlah Jemaah</span></label>
<input id="edit_ib_jemaah" type="number" class="input input-bordered w-full" value="0" min="0">
</div>
<div class="form-control col-span-2">
<label class="label"><span class="label-text font-bold">Keterangan</span></label>
<textarea id="edit_ib_ket" class="textarea textarea-bordered w-full" rows="2" placeholder="Keterangan tambahan"></textarea>
</div>
</div>
<div class="modal-action">
<button onclick="document.getElementById('modal_edit_ibadah').close()" class="btn btn-ghost">Batal</button>
<button onclick="saveEditIbadah()" class="btn btn-success">
<i class="fa-solid fa-floppy-disk mr-1"></i>Simpan Perubahan
</button>
</div>
</div>
<form method="dialog" class="modal-backdrop"><button>close</button></form>
</dialog>
<!-- Modal: Edit Keluarga Miskin -->
<dialog id="modal_edit_miskin" class="modal">
<div class="modal-box w-11/12 max-w-lg">
<h3 class="font-bold text-lg mb-4">
<i class="fa-solid fa-house mr-2 text-error"></i>Edit Keluarga Miskin
</h3>
<input type="hidden" id="edit_rm_id">
<div class="grid grid-cols-2 gap-3">
<div class="form-control col-span-2">
<label class="label"><span class="label-text font-bold">Nama Kepala Keluarga</span></label>
<input id="edit_rm_nama_kk" type="text" class="input input-bordered w-full" placeholder="Nama KK">
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Jumlah KK</span></label>
<input id="edit_rm_kk" type="number" class="input input-bordered w-full" value="1" min="1">
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Jumlah Jiwa</span></label>
<input id="edit_rm_jiwa" type="number" class="input input-bordered w-full" value="4" min="1">
</div>
<div class="form-control col-span-2">
<label class="label"><span class="label-text font-bold">Alamat</span></label>
<textarea id="edit_rm_alamat" class="textarea textarea-bordered w-full" rows="2" placeholder="Alamat lengkap"></textarea>
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Pekerjaan</span></label>
<input id="edit_rm_kerja" type="text" class="input input-bordered w-full" placeholder="Pekerjaan KK">
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Pendapatan (Rp)</span></label>
<input id="edit_rm_duit" type="number" class="input input-bordered w-full" value="0" min="0">
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Kondisi Rumah</span></label>
<select id="edit_rm_kondisi" class="select select-bordered w-full">
<option value="">Pilih Kondisi</option>
<option value="sedang">Sedang</option>
<option value="buruk">Buruk</option>
<option value="sangat_buruk">Sangat Buruk</option>
</select>
</div>
<div class="form-control col-span-2">
<label class="label"><span class="label-text font-bold">Keterangan</span></label>
<textarea id="edit_rm_ket" class="textarea textarea-bordered w-full" rows="2" placeholder="Keterangan tambahan"></textarea>
</div>
</div>
<div class="modal-action">
<button onclick="document.getElementById('modal_edit_miskin').close()" class="btn btn-ghost">Batal</button>
<button onclick="saveEditMiskin()" class="btn btn-error">
<i class="fa-solid fa-floppy-disk mr-1"></i>Simpan Perubahan
</button>
</div>
</div>
<form method="dialog" class="modal-backdrop"><button>close</button></form>
</dialog>
<!-- Modal: Confirm Delete -->
<dialog id="deleteModal" class="modal">
<div class="modal-box max-w-sm text-center">
@@ -175,6 +289,7 @@
<script>
const authUserRole = '{{ auth()->user()->getRoleNames()->first() ?? '' }}';
const authUserId = {{ auth()->id() }};
const canEditIbadah = ['administrator', 'pengurus_ibadah'].includes(authUserRole);
const canEditMiskin = ['administrator', 'petugas_pendataan'].includes(authUserRole);
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
@@ -206,7 +321,9 @@
// Ibadah Table
const bodyI = document.getElementById('bodyIbadah');
bodyI.innerHTML = dataI.length ? dataI.map((item, i) => `
bodyI.innerHTML = dataI.length ? dataI.map((item, i) => {
const canEditThis = canEditIbadah && (authUserRole === 'administrator' || item.user_id === authUserId);
return `
<tr>
<td class="text-xs font-bold opacity-30">${i + 1}</td>
<td>
@@ -221,10 +338,13 @@
<td><span class="badge badge-outline badge-sm">${item.radius}m</span></td>
<td class="font-mono text-[10px]">${parseFloat(item.latitude).toFixed(4)}, ${parseFloat(item.longitude).toFixed(4)}</td>
<td class="text-center">
${canEditIbadah ? `<button class="btn btn-xs btn-error btn-outline" onclick="prepDelete('ibadah', ${item.id})"><i class="fa-solid fa-trash"></i></button>` : ''}
<div class="flex gap-1 justify-center">
${canEditThis ? `<button class="btn btn-xs btn-warning btn-outline" onclick="openEditIbadahById(${item.id})"><i class="fa-solid fa-pen"></i></button>` : ''}
${canEditThis ? `<button class="btn btn-xs btn-error btn-outline" onclick="prepDelete('ibadah', ${item.id})"><i class="fa-solid fa-trash"></i></button>` : ''}
</div>
</td>
</tr>
`).join('') : '<tr><td colspan="7" class="text-center py-10 opacity-30 italic">Belum ada data</td></tr>';
</tr>`;
}).join('') : '<tr><td colspan="7" class="text-center py-10 opacity-30 italic">Belum ada data</td></tr>';
// Miskin Table
const bodyM = document.getElementById('bodyMiskin');
@@ -243,7 +363,10 @@
<td class="capitalize text-xs">${item.kondisi_rumah || '-'}</td>
<td class="font-mono text-[10px]">${parseFloat(item.latitude).toFixed(4)}, ${parseFloat(item.longitude).toFixed(4)}</td>
<td class="text-center">
${canEditMiskin ? `<button class="btn btn-xs btn-error btn-outline" onclick="prepDelete('miskin', '${item.id_rumah}')"><i class="fa-solid fa-trash"></i></button>` : ''}
<div class="flex gap-1 justify-center">
${canEditMiskin ? `<button class="btn btn-xs btn-warning btn-outline" onclick="openEditMiskinById('${item.id_rumah}')"><i class="fa-solid fa-pen"></i></button>` : ''}
${canEditMiskin ? `<button class="btn btn-xs btn-error btn-outline" onclick="prepDelete('miskin', '${item.id_rumah}')"><i class="fa-solid fa-trash"></i></button>` : ''}
</div>
</td>
</tr>
`).join('') : '<tr><td colspan="7" class="text-center py-10 opacity-30 italic">Belum ada data</td></tr>';
@@ -293,6 +416,107 @@
document.body.removeChild(link);
}
// ── EDIT FORMS ──────────────────────────────────────────────
function openEditIbadahById(id) {
const item = ibadahData.find(i => i.id === id);
if (!item) return;
document.getElementById('edit_ib_id').value = item.id;
document.getElementById('edit_ib_nama').value = item.nama || '';
document.getElementById('edit_ib_jenis').value = item.jenis || '';
document.getElementById('edit_ib_alamat').value = item.alamat || '';
document.getElementById('edit_ib_pengurus').value = item.pengurus || '';
document.getElementById('edit_ib_telepon').value = item.telepon || '';
document.getElementById('edit_ib_jemaah').value = item.jumlah_jemaah || 0;
document.getElementById('edit_ib_radius').value = item.radius || 500;
document.getElementById('edit_ib_ket').value = item.keterangan || '';
document.getElementById('modal_edit_ibadah').showModal();
}
async function saveEditIbadah() {
const id = document.getElementById('edit_ib_id').value;
const item = ibadahData.find(i => i.id == id);
if (!item) return;
const body = {
nama: document.getElementById('edit_ib_nama').value,
jenis: document.getElementById('edit_ib_jenis').value,
alamat: document.getElementById('edit_ib_alamat').value,
pengurus: document.getElementById('edit_ib_pengurus').value,
telepon: document.getElementById('edit_ib_telepon').value,
jumlah_jemaah: parseInt(document.getElementById('edit_ib_jemaah').value) || 0,
radius: parseInt(document.getElementById('edit_ib_radius').value) || 500,
keterangan: document.getElementById('edit_ib_ket').value,
latitude: item.latitude,
longitude: item.longitude,
};
const res = await fetch(`{{ url('/api/ibadah') }}/${id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken },
body: JSON.stringify(body),
});
const resJson = await res.json();
if (resJson.success) {
document.getElementById('modal_edit_ibadah').close();
showToast('Data berhasil diperbarui', 'success');
await loadAllData();
} else if (res.status === 403) {
showToast(resJson.message || 'Tidak diizinkan mengubah data ini', 'error');
} else {
showToast('Gagal memperbarui data', 'error');
}
}
function openEditMiskinById(idRumah) {
const item = miskinData.find(i => i.id_rumah === idRumah);
if (!item) return;
document.getElementById('edit_rm_id').value = item.id_rumah;
document.getElementById('edit_rm_nama_kk').value = item.nama_kk || '';
document.getElementById('edit_rm_kk').value = item.jumlah_kk || 1;
document.getElementById('edit_rm_jiwa').value = item.jumlah_orang || 4;
document.getElementById('edit_rm_alamat').value = item.alamat || '';
document.getElementById('edit_rm_kerja').value = item.pekerjaan || '';
document.getElementById('edit_rm_duit').value = item.pendapatan || 0;
document.getElementById('edit_rm_kondisi').value = item.kondisi_rumah || '';
document.getElementById('edit_rm_ket').value = item.keterangan || '';
document.getElementById('modal_edit_miskin').showModal();
}
async function saveEditMiskin() {
const idRumah = document.getElementById('edit_rm_id').value;
const item = miskinData.find(i => i.id_rumah === idRumah);
if (!item) return;
const body = {
nama_kk: document.getElementById('edit_rm_nama_kk').value,
jumlah_kk: parseInt(document.getElementById('edit_rm_kk').value) || 1,
jumlah_orang: parseInt(document.getElementById('edit_rm_jiwa').value) || 1,
alamat: document.getElementById('edit_rm_alamat').value,
pekerjaan: document.getElementById('edit_rm_kerja').value,
pendapatan: parseInt(document.getElementById('edit_rm_duit').value) || 0,
kondisi_rumah: document.getElementById('edit_rm_kondisi').value,
keterangan: document.getElementById('edit_rm_ket').value,
latitude: item.latitude,
longitude: item.longitude,
};
const res = await fetch(`{{ url('/api/miskin') }}/${idRumah}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken },
body: JSON.stringify(body),
});
const resJson = await res.json();
if (resJson.success) {
document.getElementById('modal_edit_miskin').close();
showToast('Data berhasil diperbarui', 'success');
await loadAllData();
} else {
showToast('Gagal memperbarui data', 'error');
}
}
let deleteTarget = null;
function prepDelete(type, id) {
deleteTarget = { type, id };
+220 -1
View File
@@ -256,6 +256,64 @@
</div>
</dialog>
<!-- Modal: Edit Rumah Ibadah -->
<dialog id="modal_edit_ibadah" class="modal">
<div class="modal-box w-11/12 max-w-lg">
<h3 class="font-bold text-lg mb-4">
<i class="fa-solid fa-mosque mr-2 text-success"></i>Edit Rumah Ibadah
</h3>
<input type="hidden" id="edit_ib_id">
<div class="grid grid-cols-2 gap-3">
<div class="form-control col-span-2">
<label class="label"><span class="label-text font-bold">Nama *</span></label>
<input id="edit_ib_nama" type="text" class="input input-bordered w-full" placeholder="Nama rumah ibadah">
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Jenis</span></label>
<select id="edit_ib_jenis" class="select select-bordered w-full">
<option value="">Pilih Jenis</option>
<option value="masjid">Masjid</option>
<option value="gereja">Gereja</option>
<option value="pura">Pura</option>
<option value="klenteng">Klenteng</option>
<option value="vihara">Vihara</option>
</select>
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Radius Analisis (m)</span></label>
<input id="edit_ib_radius" type="number" class="input input-bordered w-full" value="500" min="50" max="2000">
</div>
<div class="form-control col-span-2">
<label class="label"><span class="label-text font-bold">Alamat</span></label>
<textarea id="edit_ib_alamat" class="textarea textarea-bordered w-full" rows="2" placeholder="Alamat lengkap"></textarea>
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Pengurus</span></label>
<input id="edit_ib_pengurus" type="text" class="input input-bordered w-full" placeholder="Nama pengurus">
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Telepon</span></label>
<input id="edit_ib_telepon" type="text" class="input input-bordered w-full" placeholder="No. telepon">
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Jumlah Jemaah</span></label>
<input id="edit_ib_jemaah" type="number" class="input input-bordered w-full" value="0" min="0">
</div>
<div class="form-control col-span-2">
<label class="label"><span class="label-text font-bold">Keterangan</span></label>
<textarea id="edit_ib_ket" class="textarea textarea-bordered w-full" rows="2" placeholder="Keterangan tambahan"></textarea>
</div>
</div>
<div class="modal-action">
<button onclick="document.getElementById('modal_edit_ibadah').close()" class="btn btn-ghost">Batal</button>
<button onclick="saveEditIbadah()" class="btn btn-success">
<i class="fa-solid fa-floppy-disk mr-1"></i>Simpan Perubahan
</button>
</div>
</div>
<form method="dialog" class="modal-backdrop"><button>close</button></form>
</dialog>
<!-- Modal: Input Miskin -->
<dialog id="modalMiskin" class="modal">
<div class="modal-box">
@@ -318,6 +376,62 @@
</div>
</dialog>
<!-- Modal: Edit Keluarga Miskin -->
<dialog id="modal_edit_miskin" class="modal">
<div class="modal-box w-11/12 max-w-lg">
<h3 class="font-bold text-lg mb-4">
<i class="fa-solid fa-house mr-2 text-error"></i>Edit Keluarga Miskin
</h3>
<input type="hidden" id="edit_rm_id">
<div class="grid grid-cols-2 gap-3">
<div class="form-control col-span-2">
<label class="label"><span class="label-text font-bold">Nama Kepala Keluarga</span></label>
<input id="edit_rm_nama_kk" type="text" class="input input-bordered w-full" placeholder="Nama KK">
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Jumlah KK</span></label>
<input id="edit_rm_kk" type="number" class="input input-bordered w-full" value="1" min="1">
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Jumlah Jiwa</span></label>
<input id="edit_rm_jiwa" type="number" class="input input-bordered w-full" value="4" min="1">
</div>
<div class="form-control col-span-2">
<label class="label"><span class="label-text font-bold">Alamat</span></label>
<textarea id="edit_rm_alamat" class="textarea textarea-bordered w-full" rows="2" placeholder="Alamat lengkap"></textarea>
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Pekerjaan</span></label>
<input id="edit_rm_kerja" type="text" class="input input-bordered w-full" placeholder="Pekerjaan KK">
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Pendapatan (Rp)</span></label>
<input id="edit_rm_duit" type="number" class="input input-bordered w-full" value="0" min="0">
</div>
<div class="form-control">
<label class="label"><span class="label-text font-bold">Kondisi Rumah</span></label>
<select id="edit_rm_kondisi" class="select select-bordered w-full">
<option value="">Pilih Kondisi</option>
<option value="sedang">Sedang</option>
<option value="buruk">Buruk</option>
<option value="sangat_buruk">Sangat Buruk</option>
</select>
</div>
<div class="form-control col-span-2">
<label class="label"><span class="label-text font-bold">Keterangan</span></label>
<textarea id="edit_rm_ket" class="textarea textarea-bordered w-full" rows="2" placeholder="Keterangan tambahan"></textarea>
</div>
</div>
<div class="modal-action">
<button onclick="document.getElementById('modal_edit_miskin').close()" class="btn btn-ghost">Batal</button>
<button onclick="saveEditMiskin()" class="btn btn-error">
<i class="fa-solid fa-floppy-disk mr-1"></i>Simpan Perubahan
</button>
</div>
</div>
<form method="dialog" class="modal-backdrop"><button>close</button></form>
</dialog>
<!-- Modal: Confirm Delete -->
<dialog id="deleteModal" class="modal">
<div class="modal-box max-w-sm text-center">
@@ -337,6 +451,7 @@
<!-- ═══ JAVASCRIPT ════════════════════════════════════════════════════════ -->
<script>
const authUserRole = '{{ auth()->user()->getRoleNames()->first() ?? '' }}';
const authUserId = {{ auth()->id() }};
const canEditIbadah = ['administrator', 'pengurus_ibadah'].includes(authUserRole);
const canEditMiskin = ['administrator', 'petugas_pendataan'].includes(authUserRole);
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
@@ -633,6 +748,7 @@
// ── POPUPS ──────────────────────────────────────────────────────────
function buildPopupIbadah(item) {
const canEditThis = canEditIbadah && (authUserRole === 'administrator' || item.user_id === authUserId);
return `<div class="p-2 min-w-[200px]">
<div class="font-bold text-base text-primary">🕌 ${item.nama}</div>
<div class="badge badge-sm badge-outline mb-2 capitalize">${item.jenis || 'Ibadah'}</div>
@@ -642,7 +758,8 @@
<div><strong>Jemaah:</strong><br>${item.jumlah_jemaah || 0}</div>
</div>
<div class="flex gap-1 border-t pt-2 mt-1">
${canEditIbadah ? `<button class="btn btn-xs btn-error btn-outline" onclick="prepDelete('ibadah', ${item.id})">Hapus</button>` : ''}
${canEditThis ? `<button class="btn btn-xs btn-warning btn-outline" onclick="openEditIbadahById(${item.id})"><i class="fa-solid fa-pen mr-1"></i>Edit</button>` : ''}
${canEditThis ? `<button class="btn btn-xs btn-error btn-outline" onclick="prepDelete('ibadah', ${item.id})">Hapus</button>` : ''}
</div>
</div>`;
}
@@ -657,6 +774,7 @@
<div><strong>Kondisi:</strong><br><span class="capitalize">${item.kondisi_rumah || '-'}</span></div>
</div>
<div class="flex gap-1 border-t pt-2 mt-1">
${canEditMiskin ? `<button class="btn btn-xs btn-warning btn-outline" onclick="openEditMiskinById('${item.id_rumah}')"><i class="fa-solid fa-pen mr-1"></i>Edit</button>` : ''}
${canEditMiskin ? `<button class="btn btn-xs btn-error btn-outline" onclick="prepDelete('miskin', '${item.id_rumah}')">Hapus</button>` : ''}
</div>
</div>`;
@@ -771,6 +889,107 @@
} else showToast('Gagal menghapus', 'error');
};
// ── EDIT FORMS ─────────────────────────────────────────────
function openEditIbadahById(id) {
const item = ibadahData.find(i => i.id === id);
if (!item) return;
document.getElementById('edit_ib_id').value = item.id;
document.getElementById('edit_ib_nama').value = item.nama || '';
document.getElementById('edit_ib_jenis').value = item.jenis || '';
document.getElementById('edit_ib_alamat').value = item.alamat || '';
document.getElementById('edit_ib_pengurus').value = item.pengurus || '';
document.getElementById('edit_ib_telepon').value = item.telepon || '';
document.getElementById('edit_ib_jemaah').value = item.jumlah_jemaah || 0;
document.getElementById('edit_ib_radius').value = item.radius || 500;
document.getElementById('edit_ib_ket').value = item.keterangan || '';
document.getElementById('modal_edit_ibadah').showModal();
}
async function saveEditIbadah() {
const id = document.getElementById('edit_ib_id').value;
const item = ibadahData.find(i => i.id == id);
if (!item) return;
const body = {
nama: document.getElementById('edit_ib_nama').value,
jenis: document.getElementById('edit_ib_jenis').value,
alamat: document.getElementById('edit_ib_alamat').value,
pengurus: document.getElementById('edit_ib_pengurus').value,
telepon: document.getElementById('edit_ib_telepon').value,
jumlah_jemaah: parseInt(document.getElementById('edit_ib_jemaah').value) || 0,
radius: parseInt(document.getElementById('edit_ib_radius').value) || 500,
keterangan: document.getElementById('edit_ib_ket').value,
latitude: item.latitude,
longitude: item.longitude,
};
const res = await fetch(`{{ url('/api/ibadah') }}/${id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken },
body: JSON.stringify(body),
});
const resJson = await res.json();
if (resJson.success) {
document.getElementById('modal_edit_ibadah').close();
showToast('Data berhasil diperbarui', 'success');
await loadData();
} else if (res.status === 403) {
showToast(resJson.message || 'Tidak diizinkan mengubah data ini', 'error');
} else {
showToast('Gagal memperbarui data', 'error');
}
}
function openEditMiskinById(idRumah) {
const item = miskinData.find(i => i.id_rumah === idRumah);
if (!item) return;
document.getElementById('edit_rm_id').value = item.id_rumah;
document.getElementById('edit_rm_nama_kk').value = item.nama_kk || '';
document.getElementById('edit_rm_kk').value = item.jumlah_kk || 1;
document.getElementById('edit_rm_jiwa').value = item.jumlah_orang || 4;
document.getElementById('edit_rm_alamat').value = item.alamat || '';
document.getElementById('edit_rm_kerja').value = item.pekerjaan || '';
document.getElementById('edit_rm_duit').value = item.pendapatan || 0;
document.getElementById('edit_rm_kondisi').value = item.kondisi_rumah || '';
document.getElementById('edit_rm_ket').value = item.keterangan || '';
document.getElementById('modal_edit_miskin').showModal();
}
async function saveEditMiskin() {
const idRumah = document.getElementById('edit_rm_id').value;
const item = miskinData.find(i => i.id_rumah === idRumah);
if (!item) return;
const body = {
nama_kk: document.getElementById('edit_rm_nama_kk').value,
jumlah_kk: parseInt(document.getElementById('edit_rm_kk').value) || 1,
jumlah_orang: parseInt(document.getElementById('edit_rm_jiwa').value) || 1,
alamat: document.getElementById('edit_rm_alamat').value,
pekerjaan: document.getElementById('edit_rm_kerja').value,
pendapatan: parseInt(document.getElementById('edit_rm_duit').value) || 0,
kondisi_rumah: document.getElementById('edit_rm_kondisi').value,
keterangan: document.getElementById('edit_rm_ket').value,
latitude: item.latitude,
longitude: item.longitude,
};
const res = await fetch(`{{ url('/api/miskin') }}/${idRumah}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken },
body: JSON.stringify(body),
});
const resJson = await res.json();
if (resJson.success) {
document.getElementById('modal_edit_miskin').close();
showToast('Data berhasil diperbarui', 'success');
await loadData();
} else {
showToast('Gagal memperbarui data', 'error');
}
}
// ── TOAST ──────────────────────────────────────────────────────────
function showToast(msg, type = 'info') {
const t = document.createElement('div');