331 lines
15 KiB
JavaScript
331 lines
15 KiB
JavaScript
/* ============================================================
|
|
js/laporan.js — Sistem pelaporan warga v2.2
|
|
============================================================ */
|
|
|
|
window.labelKategoriLaporan = {
|
|
sakit:'Sakit / Butuh Bantuan Medis', kematian:'Kematian',
|
|
kelahiran:'Kelahiran Bayi Baru', pernikahan:'Pernikahan',
|
|
pindah:'Pindah Tempat', darurat_ekonomi:'Darurat Ekonomi', lainnya:'Lainnya'
|
|
};
|
|
window.labelStatusLaporan = {
|
|
menunggu:'Menunggu', diproses:'Diproses', selesai:'Selesai', ditolak:'Ditolak'
|
|
};
|
|
|
|
var _kategoriEmoji = {
|
|
sakit:'🤒', kematian:'💔', kelahiran:'👶', pernikahan:'💍',
|
|
pindah:'📦', darurat_ekonomi:'🆘', lainnya:'📣'
|
|
};
|
|
|
|
/* ─────────────────────────────────────────────────────
|
|
Floating detail box
|
|
───────────────────────────────────────────────────── */
|
|
window.openLaporanDetail = function (laporan) {
|
|
var fl = document.getElementById('laporan-detail-float');
|
|
if (!fl) return;
|
|
|
|
var status = laporan.status_laporan || 'menunggu';
|
|
var emoji = _kategoriEmoji[laporan.kategori] || '📣';
|
|
var label = window.labelKategoriLaporan[laporan.kategori] || laporan.kategori;
|
|
var statusLabel = window.labelStatusLaporan[status] || status;
|
|
|
|
/* Status bar colour */
|
|
var bar = document.getElementById('ldf-status-bar');
|
|
bar.className = 'ldf-status-bar ' + status;
|
|
|
|
/* Icon */
|
|
var icon = document.getElementById('ldf-icon');
|
|
icon.textContent = emoji;
|
|
icon.className = 'ldf-icon ' + status;
|
|
|
|
/* Title / subtitle */
|
|
document.getElementById('ldf-title').textContent = label;
|
|
document.getElementById('ldf-subtitle').textContent = '● ' + statusLabel;
|
|
document.getElementById('ldf-subtitle').style.color = {
|
|
menunggu: 'var(--amber)', diproses: 'var(--blue)',
|
|
selesai: 'var(--green)', ditolak: 'var(--text-muted)'
|
|
}[status] || 'var(--text-muted)';
|
|
|
|
/* Deskripsi */
|
|
document.getElementById('ldf-deskripsi').textContent = laporan.deskripsi || '(tidak ada deskripsi)';
|
|
|
|
/* KK terkait */
|
|
var sectionKK = document.getElementById('ldf-section-kk');
|
|
var badgeKK = document.getElementById('ldf-kk-badge');
|
|
if (laporan.nama_kepala_keluarga) {
|
|
badgeKK.innerHTML = '<i class="fa-solid fa-location-dot"></i> ' + laporan.nama_kepala_keluarga;
|
|
sectionKK.style.display = '';
|
|
} else {
|
|
sectionKK.style.display = 'none';
|
|
}
|
|
|
|
/* Info rows */
|
|
document.getElementById('ldf-pelapor').textContent = laporan.nama_pelapor || '-';
|
|
|
|
var rowWA = document.getElementById('ldf-row-wa');
|
|
if (laporan.nomor_wa) {
|
|
document.getElementById('ldf-wa').textContent = laporan.nomor_wa;
|
|
rowWA.style.display = '';
|
|
} else {
|
|
rowWA.style.display = 'none';
|
|
}
|
|
|
|
document.getElementById('ldf-waktu').textContent = laporan.created_fmt || '-';
|
|
|
|
var rowDitangani = document.getElementById('ldf-row-ditangani');
|
|
if (laporan.ditangani_oleh) {
|
|
document.getElementById('ldf-ditangani').textContent = laporan.ditangani_oleh;
|
|
rowDitangani.style.display = '';
|
|
} else {
|
|
rowDitangani.style.display = 'none';
|
|
}
|
|
|
|
/* Action buttons (pengurus only) */
|
|
var footer = document.getElementById('ldf-footer');
|
|
footer.innerHTML = '';
|
|
if (window.appAuth && window.appAuth.role === 'pengurus_masjid' && status !== 'selesai' && status !== 'ditolak') {
|
|
footer.style.display = '';
|
|
var statuses = [
|
|
{ val: 'diproses', label: '<i class="fa-solid fa-rotate"></i> Proses', cls: 'btn-proses' },
|
|
{ val: 'selesai', label: '<i class="fa-solid fa-check"></i> Selesai', cls: 'btn-selesai' },
|
|
{ val: 'ditolak', label: '<i class="fa-solid fa-xmark"></i> Tolak', cls: 'btn-tolak' }
|
|
];
|
|
statuses.forEach(function (s) {
|
|
if (s.val === status) return;
|
|
var btn = document.createElement('button');
|
|
btn.className = 'btn ' + s.cls;
|
|
btn.innerHTML = s.label;
|
|
btn.onclick = (function (lid, sv) {
|
|
return async function () {
|
|
btn.disabled = true;
|
|
try {
|
|
await window.postForm('php/update_laporan_status.php', {
|
|
id: lid, status_laporan: sv, ditangani_oleh: window.appAuth.nama
|
|
});
|
|
window.showToast('Status diperbarui ke: ' + window.labelStatusLaporan[sv], 'success');
|
|
window.closeLaporanDetail();
|
|
window.loadLaporan(document.getElementById('laporan-filter-status').value);
|
|
} catch (e) {
|
|
window.showToast('Gagal: ' + e.message, 'error');
|
|
btn.disabled = false;
|
|
}
|
|
};
|
|
})(laporan.id, s.val);
|
|
footer.appendChild(btn);
|
|
});
|
|
} else {
|
|
footer.style.display = 'none';
|
|
}
|
|
|
|
/* Close button */
|
|
document.getElementById('ldf-close').onclick = window.closeLaporanDetail;
|
|
|
|
/* Show with animation */
|
|
fl.style.display = 'flex';
|
|
};
|
|
|
|
window.closeLaporanDetail = function () {
|
|
var fl = document.getElementById('laporan-detail-float');
|
|
if (fl) fl.style.display = 'none';
|
|
};
|
|
|
|
/* ── Form laporan publik ── */
|
|
window.openLaporanPublikModal = function (kemiskinanId, namaKK) {
|
|
var modal = document.getElementById('modal-laporan-publik');
|
|
document.getElementById('laporan-kem-id').value = kemiskinanId || '';
|
|
document.getElementById('laporan-nama-pelapor').value = '';
|
|
document.getElementById('laporan-nomor-wa').value = '';
|
|
document.getElementById('laporan-kategori').value = 'lainnya';
|
|
document.getElementById('laporan-deskripsi').value = '';
|
|
document.getElementById('laporan-judul-kkname').textContent = namaKK
|
|
? 'Laporkan Kondisi: ' + namaKK
|
|
: 'Laporkan Kondisi Warga';
|
|
modal.style.display = 'flex';
|
|
document.getElementById('laporan-nama-pelapor').focus();
|
|
modal.onclick = function (e) { if (e.target === this) this.style.display = 'none'; };
|
|
};
|
|
|
|
/* ── Tombol submit laporan dipanggil dari inline HTML ── */
|
|
window._submitLaporanBtn = async function () {
|
|
var btn = document.getElementById('btn-submit-laporan');
|
|
var nama = document.getElementById('laporan-nama-pelapor').value.trim();
|
|
var desc = document.getElementById('laporan-deskripsi').value.trim();
|
|
if (!nama || !desc) { window.showToast('Nama dan deskripsi wajib diisi.', 'error'); return; }
|
|
|
|
btn.disabled = true; btn.textContent = 'Mengirim...';
|
|
var payload = {
|
|
kemiskinan_id: document.getElementById('laporan-kem-id').value,
|
|
nama_pelapor: nama,
|
|
nomor_wa: document.getElementById('laporan-nomor-wa').value.trim(),
|
|
kategori: document.getElementById('laporan-kategori').value,
|
|
deskripsi: desc
|
|
};
|
|
try {
|
|
var res = await fetch('php/create_laporan.php', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
body: new URLSearchParams(payload)
|
|
});
|
|
var text = (await res.text()).trim();
|
|
if (text === 'success') {
|
|
document.getElementById('modal-laporan-publik').style.display = 'none';
|
|
if (window.Swal) {
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: 'Laporan Terkirim',
|
|
text: 'Laporan berhasil dikirim. Terima kasih atas informasi Anda!',
|
|
confirmButtonText: 'Tutup'
|
|
});
|
|
} else {
|
|
window.showToast('Laporan berhasil dikirim. Terima kasih!', 'success');
|
|
}
|
|
} else {
|
|
window.showToast('Gagal: ' + text, 'error');
|
|
}
|
|
} catch (err) { window.showToast('Gagal: ' + err.message, 'error'); }
|
|
finally { btn.disabled = false; btn.textContent = 'Kirim Laporan'; }
|
|
};
|
|
|
|
/* ── Panel manajemen (pengurus) ── */
|
|
window.openLaporanPanel = async function () {
|
|
var panel = document.getElementById('panel-laporan');
|
|
if (panel) {
|
|
var sidebar = document.getElementById('sidebar');
|
|
if (sidebar) sidebar.style.display = 'none';
|
|
var pes = document.getElementById('panel-pesan');
|
|
if (pes) pes.style.display = 'none';
|
|
|
|
panel.style.display = 'flex';
|
|
document.getElementById('laporan-filter-status').value = 'menunggu';
|
|
window.loadLaporan('menunggu');
|
|
}
|
|
};
|
|
window.closeLaporanPanel = function () {
|
|
var p = document.getElementById('panel-laporan');
|
|
if (p) p.style.display = 'none';
|
|
window.closeLaporanDetail();
|
|
|
|
// Auto-open sidebar
|
|
var sidebar = document.getElementById('sidebar');
|
|
if (sidebar) sidebar.style.display = 'flex';
|
|
};
|
|
|
|
window.loadLaporan = async function (statusFilter) {
|
|
var container = document.getElementById('laporan-list-container');
|
|
if (!container) return;
|
|
container.innerHTML = '<div class="loading">Memuat laporan...</div>';
|
|
|
|
var url = 'php/read_laporan.php' + (statusFilter ? '?status=' + statusFilter : '');
|
|
var data = await window.fetchJson(url, []);
|
|
container.innerHTML = '';
|
|
|
|
if (!data.length) {
|
|
container.innerHTML = '<div class="empty">Tidak ada laporan.</div>'; return;
|
|
}
|
|
|
|
data.forEach(function (l) {
|
|
var chipColors = { menunggu:'chip-amber', diproses:'chip-blue', selesai:'chip-green', ditolak:'chip-gray' };
|
|
var emoji = _kategoriEmoji[l.kategori] || '📣';
|
|
|
|
var card = document.createElement('div');
|
|
card.className = 'l-card ' + l.status_laporan;
|
|
card.title = 'Klik untuk detail lengkap';
|
|
|
|
var badgeCls = { menunggu:'chip-amber', diproses:'chip-blue', selesai:'chip-green', ditolak:'chip-gray' }[l.status_laporan] || 'chip-gray';
|
|
var kkHtml = l.nama_kepala_keluarga
|
|
? '<div class="l-kk"><i class="fa-solid fa-location-dot"></i> KK: ' + window.escapeHtml(l.nama_kepala_keluarga) + '</div>' : '';
|
|
|
|
card.innerHTML =
|
|
'<div class="l-head">' +
|
|
'<span class="l-cat">' + emoji + ' ' + (window.labelKategoriLaporan[l.kategori] || l.kategori) + '</span>' +
|
|
'<span class="chip ' + badgeCls + '">' + window.escapeHtml(window.labelStatusLaporan[l.status_laporan] || l.status_laporan) + '</span>' +
|
|
'</div>' +
|
|
kkHtml +
|
|
'<div class="l-desc">' + window.escapeHtml(l.deskripsi) + '</div>' +
|
|
'<div class="l-meta"><i class="fa-solid fa-user"></i> ' + window.escapeHtml(l.nama_pelapor) +
|
|
(l.nomor_wa ? ' · <i class="fa-solid fa-mobile-screen"></i> ' + window.escapeHtml(l.nomor_wa) : '') +
|
|
' · <i class="fa-regular fa-clock"></i> ' + l.created_fmt + '</div>' +
|
|
(l.ditangani_oleh ? '<div class="l-meta"><i class="fa-solid fa-check"></i> Ditangani: ' + window.escapeHtml(l.ditangani_oleh) + '</div>' : '');
|
|
|
|
/* Klik kartu → buka floating detail */
|
|
card.addEventListener('click', function (e) {
|
|
/* Jangan trigger jika yang diklik tombol aksi */
|
|
if (e.target.closest('button')) return;
|
|
window.openLaporanDetail(l);
|
|
});
|
|
|
|
if (window.appAuth.role === 'pengurus_masjid' && l.status_laporan !== 'selesai' && l.status_laporan !== 'ditolak') {
|
|
var acts = document.createElement('div');
|
|
acts.className = 'l-acts';
|
|
var statuses = [
|
|
{ val: 'diproses', label: 'Proses', cls: 'btn-proses' },
|
|
{ val: 'selesai', label: 'Selesai', cls: 'btn-selesai' },
|
|
{ val: 'ditolak', label: 'Tolak', cls: 'btn-tolak' }
|
|
];
|
|
statuses.forEach(function (s) {
|
|
if (s.val === l.status_laporan) return;
|
|
var btn = document.createElement('button');
|
|
btn.className = 'btn ' + s.cls; btn.textContent = s.label;
|
|
btn.onclick = (function(lid, sv){ return async function(){
|
|
try {
|
|
await window.postForm('php/update_laporan_status.php', {
|
|
id: lid, status_laporan: sv, ditangani_oleh: window.appAuth.nama
|
|
});
|
|
window.showToast('Status diperbarui.', 'success');
|
|
window.closeLaporanDetail();
|
|
window.loadLaporan(document.getElementById('laporan-filter-status').value);
|
|
} catch(e){ window.showToast('Gagal: ' + e.message, 'error'); }
|
|
}; })(l.id, s.val);
|
|
acts.appendChild(btn);
|
|
});
|
|
card.appendChild(acts);
|
|
}
|
|
container.appendChild(card);
|
|
});
|
|
};
|
|
|
|
/* Polling for Laporan Notification */
|
|
window.pollLaporanNotification = async function() {
|
|
if (!window.appAuth || window.appAuth.role !== 'pengurus_masjid') {
|
|
var np = document.getElementById('notif-panel');
|
|
if (np) np.style.display = 'none';
|
|
return;
|
|
}
|
|
try {
|
|
var res = await fetch('php/read_laporan.php');
|
|
var text = await res.text();
|
|
var data = JSON.parse(text);
|
|
if(Array.isArray(data)) {
|
|
var pendingCount = data.filter(function(l) { return l.status_laporan === 'menunggu'; }).length;
|
|
|
|
var badge = document.getElementById('nav-badge-laporan');
|
|
if(badge) {
|
|
if(pendingCount > 0) {
|
|
badge.style.display = 'inline-flex';
|
|
badge.textContent = pendingCount;
|
|
} else {
|
|
badge.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
var np = document.getElementById('notif-panel');
|
|
var nb = document.getElementById('notif-body');
|
|
if (np && nb) {
|
|
if(pendingCount > 0) {
|
|
var isPanelOpen = document.getElementById('panel-laporan') && document.getElementById('panel-laporan').style.display === 'flex';
|
|
if(!isPanelOpen && (!window._notifDismissedForCount || window._notifDismissedForCount < pendingCount)) {
|
|
np.style.display = 'block';
|
|
nb.innerHTML = 'Terdapat <b>' + pendingCount + ' laporan baru</b> dari warga yang belum diproses.<br>Harap segera ditindaklanjuti!';
|
|
window._notifDismissedForCount = pendingCount;
|
|
}
|
|
} else {
|
|
np.style.display = 'none';
|
|
window._notifDismissedForCount = 0;
|
|
}
|
|
}
|
|
}
|
|
} catch(e) {}
|
|
};
|
|
|
|
// Start polling every 10 seconds
|
|
setInterval(window.pollLaporanNotification, 10000);
|