133 lines
7.5 KiB
JavaScript
133 lines
7.5 KiB
JavaScript
const Bantuan = (() => {
|
|
let jenisList = [];
|
|
|
|
const DEMO_JENIS = [
|
|
{ id:1, nama_bantuan:'Sembako Ramadan', kategori:'sembako', sumber:'Zakat Masjid', satuan:'paket', aktif:1 },
|
|
{ id:2, nama_bantuan:'PKH (Prog. Keluarga Harapan)', kategori:'ekonomi', sumber:'APBN', satuan:'Rp', aktif:1 },
|
|
{ id:3, nama_bantuan:'BPNT / Kartu Sembako', kategori:'sembako', sumber:'APBN', satuan:'bulan', aktif:1 },
|
|
{ id:4, nama_bantuan:'Beasiswa Pendidikan', kategori:'pendidikan', sumber:'CSR Perusahaan', satuan:'paket/tahun',aktif:1 },
|
|
{ id:5, nama_bantuan:'BPJS Kesehatan PBI', kategori:'kesehatan', sumber:'APBD', satuan:'bulan', aktif:1 },
|
|
{ id:6, nama_bantuan:'Bantuan Sembako Gereja', kategori:'sembako', sumber:'Kolekte Gereja', satuan:'paket', aktif:1 },
|
|
{ id:7, nama_bantuan:'Bantuan Vihara (Kwan Im)',kategori:'sembako', sumber:'Dana Sosial Vihara',satuan:'paket', aktif:1 },
|
|
{ id:8, nama_bantuan:'Raskin / Beras Miskin', kategori:'sembako', sumber:'Bulog', satuan:'kg', aktif:1 },
|
|
];
|
|
|
|
const DEMO_HISTORI = [
|
|
{ id:1, nama_lengkap:'Ahmad Suryana', nama_bantuan:'Sembako Ramadan', tanggal:'2025-03-15', jumlah:1, satuan:'paket', nama_ri:"Masjid Jami'", status_penyaluran:'disalurkan' },
|
|
{ id:2, nama_lengkap:'Ahmad Suryana', nama_bantuan:'BPNT', tanggal:'2025-01-10', jumlah:1, satuan:'bulan', nama_ri:"Masjid Jami'", status_penyaluran:'disalurkan' },
|
|
{ id:3, nama_lengkap:'Maria Magdalena', nama_bantuan:'Bantuan Sembako Gereja', tanggal:'2025-02-20', jumlah:1, satuan:'paket', nama_ri:'Katedral', status_penyaluran:'disalurkan' },
|
|
{ id:4, nama_lengkap:'Lim Ah Kow', nama_bantuan:'Bantuan Vihara', tanggal:'2025-04-01', jumlah:1, satuan:'paket', nama_ri:'Vihara', status_penyaluran:'disalurkan' },
|
|
{ id:5, nama_lengkap:'Tan Eng Huat', nama_bantuan:'Raskin', tanggal:'2025-03-05', jumlah:10, satuan:'kg', nama_ri:'Klenteng', status_penyaluran:'disalurkan' },
|
|
];
|
|
|
|
const KAT_COLOR = { sembako:'#06d6a0', ekonomi:'#4361ee', pendidikan:'#4cc9f0', kesehatan:'#ffd166', lainnya:'#6b7a99' };
|
|
const KAT_ICON = { sembako:'🛒', ekonomi:'💰', pendidikan:'📚', kesehatan:'🏥', lainnya:'📦' };
|
|
|
|
async function load() {
|
|
try { jenisList = await Api.get('/bantuan'); } catch { jenisList = DEMO_JENIS; }
|
|
renderJenis();
|
|
loadHistori();
|
|
}
|
|
|
|
function renderJenis() {
|
|
const el = ge('bantuan-jenis-list');
|
|
el.innerHTML = jenisList.map(b => `
|
|
<div style="display:flex;align-items:center;gap:10px;padding:10px 12px;background:var(--bg4);border:1px solid var(--border);border-radius:8px;margin-bottom:6px;border-left:3px solid ${KAT_COLOR[b.kategori]||'#888'}">
|
|
<span style="font-size:20px">${KAT_ICON[b.kategori]||'📦'}</span>
|
|
<div style="flex:1;min-width:0">
|
|
<div style="font-weight:700;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${b.nama_bantuan}</div>
|
|
<div style="font-size:11px;color:var(--muted)">${b.kategori} · ${b.sumber||'—'} · per ${b.satuan||'unit'}</div>
|
|
</div>
|
|
${App.canEdit() ? `<button class="btn btn-danger btn-xs" onclick="Bantuan.hapusJenis(${b.id})">🗑</button>` : ''}
|
|
</div>`).join('') || '<p style="color:var(--muted);font-size:12px;padding:12px">Belum ada data bantuan</p>';
|
|
}
|
|
|
|
async function loadHistori() {
|
|
let data;
|
|
try { data = await Api.get('/histori?status=disalurkan'); } catch { data = DEMO_HISTORI; }
|
|
ge('bantuan-histori-list').innerHTML = data.map(h => `
|
|
<div style="padding:10px 12px;background:var(--bg4);border:1px solid var(--border);border-radius:8px;margin-bottom:6px">
|
|
<div style="display:flex;justify-content:space-between;align-items:flex-start">
|
|
<strong style="font-size:12.5px">${h.nama_lengkap}</strong>
|
|
<span class="bdg bdg-${h.status_penyaluran||'disalurkan'}" style="font-size:9px">${h.status_penyaluran}</span>
|
|
</div>
|
|
<div style="font-size:11px;color:var(--muted2);margin-top:3px">${h.nama_bantuan} · ${h.jumlah} ${h.satuan||''}</div>
|
|
<div style="font-size:10px;color:var(--muted);margin-top:2px">🕌 ${h.nama_ri||'—'} · 📅 ${h.tanggal?.substring(0,10)||'—'}</div>
|
|
</div>`).join('') || '<p style="color:var(--muted);font-size:12px;padding:12px">Belum ada riwayat</p>';
|
|
}
|
|
|
|
function showFormJenis() {
|
|
['fjb-nama','fjb-satuan','fjb-sumber','fjb-deskripsi'].forEach(id => sv(id,''));
|
|
sv('fjb-kategori','sembako');
|
|
App.showModal('modal-jenis-bantuan');
|
|
}
|
|
|
|
async function saveJenis() {
|
|
const nama = gv('fjb-nama');
|
|
if (!nama) { App.toast('Nama bantuan wajib diisi','error'); return; }
|
|
const body = { nama_bantuan: nama, kategori: gv('fjb-kategori'), sumber: gv('fjb-sumber'), satuan: gv('fjb-satuan'), deskripsi: gv('fjb-deskripsi') };
|
|
try {
|
|
await Api.post('/bantuan', body);
|
|
App.toast('Jenis bantuan ditambahkan ✅','success');
|
|
App.closeModal('modal-jenis-bantuan');
|
|
load();
|
|
} catch(e) { App.toast(e.message,'error'); }
|
|
}
|
|
|
|
async function hapusJenis(id) {
|
|
if (!confirm('Hapus jenis bantuan ini?')) return;
|
|
try { await Api.delete(`/bantuan/${id}`); App.toast('Dihapus','success'); load(); }
|
|
catch(e) { App.toast(e.message,'error'); }
|
|
}
|
|
|
|
async function showFormSalur(nikPrefill = '', namaPrefill = '') {
|
|
sv('fs-bantuan', '');
|
|
sv('fs-nik', nikPrefill);
|
|
sv('fs-jumlah', '1');
|
|
sv('fs-ket', '');
|
|
ge('fs-nik-info').classList.add('hidden');
|
|
ge('fs-tgl').value = new Date().toISOString().substring(0,10);
|
|
// Isi dropdown jenis bantuan
|
|
if (!jenisList.length) { try { jenisList = await Api.get('/bantuan'); } catch { jenisList = DEMO_JENIS; } }
|
|
ge('fs-bantuan').innerHTML = jenisList.map(b => `<option value="${b.id}">${KAT_ICON[b.kategori]||'📦'} ${b.nama_bantuan}</option>`).join('');
|
|
App.showModal('modal-salur');
|
|
if (nikPrefill) { setTimeout(() => cekPenerima(nikPrefill), 200); }
|
|
}
|
|
|
|
function quickSalur(nik, nama) { showFormSalur(nik, nama); }
|
|
|
|
async function cekPenerima(nik) {
|
|
if (nik.length < 16) { ge('fs-nik-info').classList.add('hidden'); return; }
|
|
try {
|
|
const info = await Api.get(`/histori/${nik}/cek`);
|
|
const box = ge('fs-nik-info');
|
|
if (info.total > 0) {
|
|
box.innerHTML = `✅ Sudah dibantu <strong>${info.total}x</strong> · ${info.jenis_bantuan||'—'} · Terakhir: ${info.terakhir_dibantu?.substring(0,10)||'—'}`;
|
|
box.className = 'alert-ok';
|
|
} else {
|
|
box.innerHTML = `⚠️ Belum pernah menerima bantuan`;
|
|
box.className = 'alert-warn';
|
|
}
|
|
box.classList.remove('hidden');
|
|
} catch {
|
|
ge('fs-nik-info').classList.add('hidden');
|
|
}
|
|
}
|
|
|
|
async function salurkan() {
|
|
const nik = gv('fs-nik');
|
|
if (!nik || nik.length !== 16) { App.toast('NIK penerima harus 16 digit','error'); return; }
|
|
if (!gv('fs-bantuan')) { App.toast('Pilih jenis bantuan','error'); return; }
|
|
if (!gv('fs-tgl')) { App.toast('Tanggal wajib diisi','error'); return; }
|
|
const body = { nik, id_bantuan: gv('fs-bantuan'), tanggal: gv('fs-tgl'), jumlah: gv('fs-jumlah'), keterangan: gv('fs-ket') };
|
|
try {
|
|
await Api.post('/histori', body);
|
|
App.toast('Bantuan berhasil dicatat ✅','success');
|
|
App.closeModal('modal-salur');
|
|
load();
|
|
} catch(e) { App.toast(e.message,'error'); }
|
|
}
|
|
|
|
return { load, showFormJenis, saveJenis, hapusJenis, showFormSalur, quickSalur, cekPenerima, salurkan };
|
|
})();
|