147 lines
7.4 KiB
JavaScript
147 lines
7.4 KiB
JavaScript
function renderRumahIbadahPanel(pb) {
|
||
return Promise.all([callAPI('rumah_ibadah.php'), callAPI('penduduk_miskin.php')]).then(([riRes, pmRes]) => {
|
||
const ri = riRes.data || [];
|
||
const pm = pmRes.data || [];
|
||
|
||
pb.innerHTML = `
|
||
<div class="layer-section">
|
||
<div class="layer-section-title">Visibilitas Layer</div>
|
||
${mkLayerItem('rumahIbadah', '#f59e0b', 'Rumah Ibadah', ri.length)}
|
||
${mkLayerItem('ibadahRadius', '#fbbf24', 'Radius Jangkauan', ri.length, true)}
|
||
${mkLayerItem('pendudukMiskin', '#16a34a', 'Penduduk Miskin', pm.length)}
|
||
</div>
|
||
<div class="layer-section">
|
||
<div class="layer-section-title">Tambah Data</div>
|
||
<button class="btn-add admin-only" id="btn-add-ri" onclick="startAdd('ri')">+ Tambah Rumah Ibadah</button>
|
||
</div>
|
||
<div class="layer-section">
|
||
<div class="layer-section-title">Rumah Ibadah (${ri.length})</div>
|
||
<div class="data-list">
|
||
${ri.length ? ri.map(r => `
|
||
<div class="data-item" onclick="map.flyTo([${r.latitude},${r.longitude}],17)">
|
||
<div class="item-icon">⛪</div>
|
||
<div class="item-info">
|
||
<div class="item-name">${esc(r.nama)}</div>
|
||
<div class="item-sub">${r.jenis} · R=${r.radius_meter}m</div>
|
||
</div>
|
||
<div style="display:flex;gap:4px">
|
||
${(window.currentUser && (window.currentUser.role === 'admin' || (window.currentUser.role === 'petugas_lapangan' && String(window.currentUser.rumah_ibadah_id) === String(r.id)))) ? `<button class="btn btn-ghost btn-sm" onclick="event.stopPropagation();editRI(${r.id})">✏</button>` : ''}
|
||
${(window.currentUser && window.currentUser.role === 'admin') ? `<button class="btn btn-danger btn-sm" onclick="event.stopPropagation();deleteRI(${r.id})">✕</button>` : ''}
|
||
</div>
|
||
</div>`).join('') : '<div class="loading">Belum ada data</div>'}
|
||
</div>
|
||
</div>`;
|
||
|
||
loadRILayer(ri);
|
||
loadPMLayer(pm);
|
||
registerSearchEntries('ri', ri.map(r => ({
|
||
key: `ri:${r.id}`,
|
||
label: r.nama,
|
||
subtitle: `Rumah Ibadah · ${r.jenis}${r.alamat ? ` · ${r.alamat}` : ''}`,
|
||
typeLabel: 'Rumah Ibadah',
|
||
icon: '⛪',
|
||
searchText: normalizeSearchText(`${r.nama} ${r.jenis} rumah ibadah`),
|
||
focus: () => focusMarkerById('rumahIbadah', r.id)
|
||
})));
|
||
registerSearchEntries('pm', pm.map(p => ({
|
||
key: `pm:${p.id}`,
|
||
label: p.nama,
|
||
subtitle: `Penduduk Miskin · ${p.jumlah_anggota} jiwa${p.alamat ? ` · ${p.alamat}` : ''}`,
|
||
typeLabel: 'Penduduk Miskin',
|
||
icon: '👤',
|
||
searchText: normalizeSearchText(`${p.nama} ${p.nik || ''} penduduk miskin`),
|
||
focus: () => focusMarkerById('pendudukMiskin', p.id)
|
||
})));
|
||
updateStatusCount();
|
||
});
|
||
}
|
||
|
||
function renderPendudukMiskinPanel(pb) {
|
||
return Promise.all([callAPI('rumah_ibadah.php'), callAPI('penduduk_miskin.php')]).then(([riRes, pmRes]) => {
|
||
const ri = riRes.data || [];
|
||
const pm = pmRes.data || [];
|
||
|
||
// Filter Penduduk Miskin for petugas_lapangan to only show those in their radius
|
||
let filteredPm = pm;
|
||
if (window.currentUser && window.currentUser.role === 'petugas_lapangan') {
|
||
const userRiId = String(window.currentUser.rumah_ibadah_id);
|
||
filteredPm = pm.filter(p => p.status_proximity === 'dalam_radius' && String(p.rumah_ibadah_id) === userRiId);
|
||
}
|
||
|
||
pb.innerHTML = `
|
||
<div class="layer-section">
|
||
<div class="layer-section-title">Visibilitas Layer</div>
|
||
${mkLayerItem('rumahIbadah', '#f59e0b', 'Rumah Ibadah', ri.length)}
|
||
${mkLayerItem('ibadahRadius', '#fbbf24', 'Radius Jangkauan', ri.length, true)}
|
||
${mkLayerItem('pendudukMiskin', '#16a34a', 'Penduduk Miskin', pm.length)}
|
||
</div>
|
||
<div class="layer-section">
|
||
<div class="layer-section-title">Tambah Data</div>
|
||
<button class="btn-add write-only" id="btn-add-pm" onclick="startAdd('pm')">+ Tambah Penduduk Miskin</button>
|
||
</div>
|
||
<div class="layer-section">
|
||
<div class="layer-section-title">Penduduk Miskin (${filteredPm.length})</div>
|
||
<div class="data-list">
|
||
${filteredPm.length ? filteredPm.map(p => `
|
||
<div class="data-item" onclick="map.flyTo([${p.latitude},${p.longitude}],17)">
|
||
<div class="item-icon">${pmEmoji(p)}</div>
|
||
<div class="item-info">
|
||
<div class="item-name">${esc(p.nama)}</div>
|
||
<div class="item-sub">${p.total_bantuan} bantuan · ${p.jumlah_anggota} jiwa</div>
|
||
</div>
|
||
<div style="display:flex; align-items:center; gap:4px">
|
||
<div class="item-badge ${p.status_proximity === 'dalam_radius' ? 'badge-green' : 'badge-red'}" style="margin-right:4px">
|
||
${p.status_proximity === 'dalam_radius' ? 'DALAM' : 'LUAR'}
|
||
</div>
|
||
${(window.currentUser && (window.currentUser.role === 'admin' || (window.currentUser.role === 'petugas_lapangan' && p.status_proximity === 'dalam_radius' && String(p.rumah_ibadah_id) === String(window.currentUser.rumah_ibadah_id)))) ? `
|
||
<button class="btn btn-primary btn-sm" onclick="event.stopPropagation();openLogBantuan(${p.id},'${esc(p.nama)}',${p.latitude},${p.longitude})">📋</button>
|
||
<button class="btn btn-ghost btn-sm" onclick="event.stopPropagation();editPM(${p.id})">✏</button>
|
||
` : ''}
|
||
${(window.currentUser && window.currentUser.role === 'admin') ? `<button class="btn btn-danger btn-sm" onclick="event.stopPropagation();deletePM(${p.id})">✕</button>` : ''}
|
||
</div>
|
||
</div>`).join('') : '<div class="loading">Belum ada data</div>'}
|
||
</div>
|
||
</div>`;
|
||
|
||
loadRILayer(ri);
|
||
loadPMLayer(pm);
|
||
registerSearchEntries('ri', ri.map(r => ({
|
||
key: `ri:${r.id}`,
|
||
label: r.nama,
|
||
subtitle: `Rumah Ibadah · ${r.jenis}${r.alamat ? ` · ${r.alamat}` : ''}`,
|
||
typeLabel: 'Rumah Ibadah',
|
||
icon: '⛪',
|
||
searchText: normalizeSearchText(`${r.nama} ${r.jenis} rumah ibadah`),
|
||
focus: () => focusMarkerById('rumahIbadah', r.id)
|
||
})));
|
||
registerSearchEntries('pm', pm.map(p => ({
|
||
key: `pm:${p.id}`,
|
||
label: p.nama,
|
||
subtitle: `Penduduk Miskin · ${p.jumlah_anggota} jiwa${p.alamat ? ` · ${p.alamat}` : ''}`,
|
||
typeLabel: 'Penduduk Miskin',
|
||
icon: '👤',
|
||
searchText: normalizeSearchText(`${p.nama} ${p.nik || ''} penduduk miskin`),
|
||
focus: () => focusMarkerById('pendudukMiskin', p.id)
|
||
})));
|
||
updateStatusCount();
|
||
});
|
||
}
|
||
|
||
function mkLayerItem(key, color, label, count, isRing = false) {
|
||
const dot = isRing
|
||
? `<div class="layer-dot" style="background:transparent;border:2px solid ${color}"></div>`
|
||
: `<div class="layer-dot" style="background:${color}"></div>`;
|
||
return `<div class="layer-item ${layerVisible[key] ? 'checked' : ''}" onclick="toggleLayer('${key}',this)">
|
||
<div class="layer-check">${layerVisible[key] ? '✓' : ''}</div>${dot}
|
||
<div class="layer-label">${label}</div>
|
||
<div class="layer-count">${count}</div>
|
||
</div>`;
|
||
}
|
||
|
||
function pmEmoji(p) {
|
||
if (p.bantuan_pemberdayaan > 0 && p.bantuan_konsumtif > 0) return '🔗';
|
||
if (p.bantuan_pemberdayaan > 0) return '📚';
|
||
if (p.bantuan_konsumtif > 0) return '🛍';
|
||
return '👤';
|
||
}
|
||
|