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:
@@ -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 };
|
||||
|
||||
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user