128 lines
6.8 KiB
JavaScript
128 lines
6.8 KiB
JavaScript
const Keluarga = (() => {
|
|
let all = [], editId = null;
|
|
|
|
const DEMO = [
|
|
{ id:1, no_kk:'6171010101010001', nama_kepala:'Ahmad Suryana', kecamatan:'Pontianak Timur', kelurahan:'Dalam Bugis', jumlah_anggota:3, total_penghasilan:900000, nama_ri:"Masjid Jami'", status_ekonomi:'miskin', total_bantuan:2 },
|
|
{ id:2, no_kk:'6171010101010002', nama_kepala:'Samsul Bahri', kecamatan:'Pontianak Kota', kelurahan:'Sungai Bangkong',jumlah_anggota:2,total_penghasilan:1700000, nama_ri:"Masjid Jami'", status_ekonomi:'rentan', total_bantuan:0 },
|
|
{ id:3, no_kk:'6171010101010003', nama_kepala:'Maria Magdalena', kecamatan:'Pontianak Selatan', kelurahan:'Akcaya', jumlah_anggota:3, total_penghasilan:800000, nama_ri:'Katedral', status_ekonomi:'miskin', total_bantuan:1 },
|
|
{ id:4, no_kk:'6171010101010004', nama_kepala:'Hendra Wijaya', kecamatan:'Pontianak Selatan', kelurahan:'Parit Tokaya', jumlah_anggota:2, total_penghasilan:1500000, nama_ri:'Mujahidin', status_ekonomi:'rentan', total_bantuan:0 },
|
|
{ id:5, no_kk:'6171010101010005', nama_kepala:'Lim Ah Kow', kecamatan:'Pontianak Kota', kelurahan:'Darat Sekip', jumlah_anggota:2, total_penghasilan:700000, nama_ri:'Vihara', status_ekonomi:'miskin', total_bantuan:1 },
|
|
{ id:6, no_kk:'6171010101010006', nama_kepala:'Mulyadi', kecamatan:'Pontianak Timur', kelurahan:'Dalam Bugis', jumlah_anggota:2, total_penghasilan:4500000, nama_ri:"Masjid Jami'", status_ekonomi:'mampu', total_bantuan:0 },
|
|
{ id:7, no_kk:'6171010101010007', nama_kepala:'Yohanes Kristian',kecamatan:'Pontianak Selatan', kelurahan:'Akcaya', jumlah_anggota:2, total_penghasilan:1100000, nama_ri:'Katedral', status_ekonomi:'rentan', total_bantuan:0 },
|
|
{ id:8, no_kk:'6171010101010008', nama_kepala:'Tan Eng Huat', kecamatan:'Pontianak Kota', kelurahan:'Pontianak Kota',jumlah_anggota:1,total_penghasilan:600000, nama_ri:'Klenteng', status_ekonomi:'miskin', total_bantuan:1 },
|
|
];
|
|
|
|
async function load() {
|
|
try { all = await Api.get('/keluarga'); } catch { all = DEMO; }
|
|
applyFilter();
|
|
}
|
|
|
|
function search(q) { applyFilter(); }
|
|
|
|
function applyFilter() {
|
|
const q = gv('kf-search');
|
|
const ek = gv('kf-ekonomi');
|
|
const data = all.filter(k =>
|
|
(!q || k.nama_kepala?.toLowerCase().includes(q.toLowerCase()) || k.no_kk?.includes(q)) &&
|
|
(!ek || k.status_ekonomi === ek)
|
|
);
|
|
render(data);
|
|
}
|
|
|
|
function render(data) {
|
|
const tb = ge('tbody-keluarga');
|
|
if (!data.length) { tb.innerHTML = '<tr><td colspan="9"><div class="empty-state"><div class="es-icon">🏠</div><h3>Tidak ada data</h3></div></td></tr>'; return; }
|
|
tb.innerHTML = data.map(k => `
|
|
<tr class="row-${k.status_ekonomi}">
|
|
<td class="mono">${k.no_kk}</td>
|
|
<td><strong>${k.nama_kepala}</strong><div style="font-size:10px;color:var(--muted)">${k.kelurahan||''}</div></td>
|
|
<td>${k.kecamatan||'—'}</td>
|
|
<td style="text-align:center;font-weight:700;font-size:15px">${k.jumlah_anggota||0}</td>
|
|
<td class="mono" style="font-size:11px">${rp(k.total_penghasilan)}</td>
|
|
<td>${k.nama_ri||'—'}</td>
|
|
<td>${bdg(k.status_ekonomi,'')}</td>
|
|
<td style="text-align:center">
|
|
${k.total_bantuan > 0
|
|
? `<span class="bdg bdg-sehat">✅ ${k.total_bantuan}x</span>`
|
|
: `<span class="bdg bdg-darurat">❌ Belum</span>`}
|
|
</td>
|
|
<td>
|
|
<div style="display:flex;gap:4px">
|
|
<button class="btn btn-secondary btn-xs" onclick="Keluarga.showAnggota(${k.id})" title="Lihat anggota">👥</button>
|
|
${App.canEdit() ? `
|
|
<button class="btn btn-secondary btn-xs" onclick="Keluarga.showForm(${k.id})" title="Edit">✏️</button>
|
|
<button class="btn btn-danger btn-xs" onclick="Keluarga.hapus(${k.id})" title="Hapus">🗑</button>` : ''}
|
|
</div>
|
|
</td>
|
|
</tr>`).join('');
|
|
}
|
|
|
|
async function showForm(id = null) {
|
|
editId = id;
|
|
ge('mk-title').textContent = id ? '✏️ Edit Data Keluarga' : '🏠 Tambah Kartu Keluarga';
|
|
ge('fk-nokk').readOnly = !!id;
|
|
// Load RI dropdown
|
|
try {
|
|
const riList = await Api.get('/rumah-ibadah');
|
|
ge('fk-ri').innerHTML = '<option value="">— Pilih Rumah Ibadah —</option>' +
|
|
riList.map(r => `<option value="${r.id}">${r.nama}</option>`).join('');
|
|
} catch {
|
|
ge('fk-ri').innerHTML = '<option value="1">Masjid Jami\' Pontianak</option>';
|
|
}
|
|
if (id) {
|
|
const k = all.find(x => x.id == id) || {};
|
|
sv('fk-nokk', k.no_kk); sv('fk-kepala', k.nama_kepala);
|
|
sv('fk-alamat', k.alamat); sv('fk-kecamatan', k.kecamatan);
|
|
sv('fk-kelurahan', k.kelurahan); sv('fk-ekonomi', k.status_ekonomi || 'rentan');
|
|
sv('fk-lat', k.lat); sv('fk-lng', k.lng);
|
|
if (k.id_rumah_ibadah) sv('fk-ri', k.id_rumah_ibadah);
|
|
} else {
|
|
['fk-nokk','fk-kepala','fk-alamat','fk-kecamatan','fk-kelurahan','fk-lat','fk-lng'].forEach(i => sv(i,''));
|
|
sv('fk-ekonomi','rentan');
|
|
}
|
|
App.showModal('modal-keluarga');
|
|
}
|
|
|
|
async function save() {
|
|
const nokk = gv('fk-nokk');
|
|
if (!nokk || nokk.length !== 16) { App.toast('No. KK harus 16 digit','error'); return; }
|
|
if (!gv('fk-kepala')) { App.toast('Nama kepala wajib diisi','error'); return; }
|
|
const body = {
|
|
no_kk: nokk, nama_kepala: gv('fk-kepala'),
|
|
id_rumah_ibadah: gv('fk-ri') || null,
|
|
alamat: gv('fk-alamat'), kecamatan: gv('fk-kecamatan'),
|
|
kelurahan: gv('fk-kelurahan'), status_ekonomi: gv('fk-ekonomi'),
|
|
lat: gv('fk-lat') || null, lng: gv('fk-lng') || null,
|
|
};
|
|
try {
|
|
if (editId) { await Api.put(`/keluarga/${editId}`, body); App.toast('Data KK diperbarui ✅','success'); }
|
|
else { await Api.post('/keluarga', body); App.toast('KK ditambahkan ✅','success'); }
|
|
App.closeModal('modal-keluarga');
|
|
load();
|
|
} catch(e) { App.toast(e.message,'error'); }
|
|
}
|
|
|
|
async function hapus(id) {
|
|
if (!confirm('Hapus data keluarga ini?\nPastikan semua anggota sudah dipindah atau dihapus.')) return;
|
|
try { await Api.delete(`/keluarga/${id}`); App.toast('Data KK dihapus','success'); load(); }
|
|
catch(e) { App.toast(e.message,'error'); }
|
|
}
|
|
|
|
async function showAnggota(id) {
|
|
const k = all.find(x => x.id == id);
|
|
let anggota = [];
|
|
try {
|
|
const detail = await Api.get(`/keluarga/${id}`);
|
|
anggota = detail.anggota || [];
|
|
} catch {
|
|
anggota = [];
|
|
}
|
|
if (!anggota.length) { App.toast('Tidak ada data anggota (atau belum terhubung ke API)','info'); return; }
|
|
// Tampilkan dalam alert atau panel detail
|
|
const info = anggota.map(a => `• ${a.nama_lengkap} (${a.umur}th) — ${cap(a.status_keluarga)} — ${a.status_ekonomi}`).join('\n');
|
|
alert(`Anggota KK: ${k?.nama_kepala}\n\n${info}`);
|
|
}
|
|
|
|
return { load, search, applyFilter, showForm, save, hapus, showAnggota };
|
|
})();
|