mengubah sistem menjadi lebih terfokus ke poverty
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
document.addEventListener('auth-ready', function (e) {
|
||||
const user = e.detail;
|
||||
document.body.classList.add('auth-loaded');
|
||||
|
||||
// Update User Profile in Sidebar
|
||||
document.getElementById('user-display-name').textContent = user.username;
|
||||
|
||||
// Format role name nicely
|
||||
const roleMap = {
|
||||
'admin': 'Admin',
|
||||
'petugas_lapangan': 'Rumah Ibadah',
|
||||
'guest': 'Guest'
|
||||
};
|
||||
document.getElementById('user-display-role').textContent = roleMap[user.role] || user.role;
|
||||
|
||||
// Show admin-only nav items
|
||||
if (user.role === 'admin') {
|
||||
document.getElementById('nav-akun').style.display = 'flex';
|
||||
}
|
||||
|
||||
// Update Greeting
|
||||
document.getElementById('greeting-title').textContent = `Selamat Datang, ${user.username}!`;
|
||||
|
||||
// Load stats data
|
||||
loadDashboardStats();
|
||||
});
|
||||
|
||||
// Format current date nicely in Indonesian
|
||||
const dateOpts = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
|
||||
document.getElementById('current-date').textContent = new Date().toLocaleDateString('id-ID', dateOpts);
|
||||
|
||||
async function handleLogout() {
|
||||
if (!confirm('Apakah Anda yakin ingin keluar?')) return;
|
||||
try {
|
||||
const response = await fetch('api/logout.php');
|
||||
const data = await response.json();
|
||||
if (data.status === 'success') {
|
||||
window.location.href = '?page=login';
|
||||
}
|
||||
} catch (err) {
|
||||
alert('Gagal melakukan logout.');
|
||||
}
|
||||
}
|
||||
|
||||
async function loadDashboardStats() {
|
||||
try {
|
||||
const response = await fetch('api/dashboard_stats.php');
|
||||
const result = await response.json();
|
||||
|
||||
if (result.status === 'success') {
|
||||
const stats = result.data;
|
||||
renderStatsCards(stats);
|
||||
renderProximityChart(stats.proximity);
|
||||
renderBantuanChart(stats.tipe_bantuan);
|
||||
renderBantuanTable(stats.bantuan_terbaru);
|
||||
renderRiTable(stats.ri_teraktif);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Gagal memuat statistik dashboard:', err);
|
||||
}
|
||||
}
|
||||
|
||||
function renderStatsCards(stats) {
|
||||
// 1. Penduduk Miskin
|
||||
document.getElementById('pm-total-kk').textContent = `${stats.penduduk_miskin.total_kk} KK`;
|
||||
document.getElementById('pm-total-jiwa').textContent = `${stats.penduduk_miskin.total_jiwa} Jiwa terdata`;
|
||||
|
||||
// 2. Rumah Ibadah
|
||||
document.getElementById('ri-total').textContent = stats.rumah_ibadah.total;
|
||||
|
||||
|
||||
// 5. Log Bantuan
|
||||
document.getElementById('lb-total-count').textContent = `${stats.log_bantuan.total_count} kali`;
|
||||
const rpBantuan = new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', maximumFractionDigits: 0 }).format(stats.log_bantuan.total_nilai || 0);
|
||||
document.getElementById('lb-total-nilai').textContent = `Total ${rpBantuan}`;
|
||||
}
|
||||
|
||||
let proximityChart = null;
|
||||
function renderProximityChart(proximity) {
|
||||
const ctx = document.getElementById('chart-proximity').getContext('2d');
|
||||
if (proximityChart) proximityChart.destroy();
|
||||
|
||||
proximityChart = new Chart(ctx, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: ['Dalam Radius (Dalam Jangkauan)', 'Luar Radius (Di Luar Jangkauan)'],
|
||||
datasets: [{
|
||||
data: [proximity.dalam_radius, proximity.luar_radius],
|
||||
backgroundColor: ['#10b981', '#f43f5e'],
|
||||
borderWidth: 4,
|
||||
borderColor: '#ffffff',
|
||||
hoverOffset: 4
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
labels: {
|
||||
boxWidth: 12,
|
||||
font: { family: 'Inter', size: 11, weight: '600' },
|
||||
color: '#475569'
|
||||
}
|
||||
}
|
||||
},
|
||||
cutout: '70%'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let bantuanChart = null;
|
||||
function renderBantuanChart(tipeBantuan) {
|
||||
const ctx = document.getElementById('chart-bantuan-tipe').getContext('2d');
|
||||
if (bantuanChart) bantuanChart.destroy();
|
||||
|
||||
bantuanChart = new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: ['📚 Pemberdayaan (Pelatihan)', '🛍️ Konsumtif (Makan/Barang)'],
|
||||
datasets: [{
|
||||
label: 'Penyaluran Bantuan',
|
||||
data: [tipeBantuan.Pemberdayaan, tipeBantuan.Konsumtif],
|
||||
backgroundColor: ['#2563eb', '#f59e0b'],
|
||||
borderRadius: 8,
|
||||
barThickness: 36
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: { stepSize: 1, color: '#64748b', font: { family: 'Inter' } },
|
||||
grid: { color: '#f1f5f9' }
|
||||
},
|
||||
x: {
|
||||
ticks: { color: '#475569', font: { family: 'Inter', weight: '600' } },
|
||||
grid: { display: false }
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function renderBantuanTable(bantuanList) {
|
||||
const tbody = document.getElementById('table-bantuan-body');
|
||||
if (!bantuanList || bantuanList.length === 0) {
|
||||
tbody.innerHTML = '<tr><td colspan="6" class="loading">Belum ada riwayat bantuan</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
tbody.innerHTML = bantuanList.map(b => {
|
||||
const rp = b.nilai_bantuan ? new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', maximumFractionDigits: 0 }).format(b.nilai_bantuan) : '—';
|
||||
const badgeClass = b.tipe_bantuan === 'Pemberdayaan' ? 'pemberdayaan' : 'konsumtif';
|
||||
return `
|
||||
<tr>
|
||||
<td><strong>${b.tanggal_bantuan}</strong></td>
|
||||
<td>${escapeHTML(b.nama_penduduk)}</td>
|
||||
<td><span class="db-badge ${badgeClass}">${b.tipe_bantuan}</span></td>
|
||||
<td>${escapeHTML(b.sub_kategori || '—')}</td>
|
||||
<td><strong>${rp}</strong></td>
|
||||
<td>${escapeHTML(b.nama_rumah_ibadah)}</td>
|
||||
</tr>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function renderRiTable(riList) {
|
||||
const tbody = document.getElementById('table-ri-body');
|
||||
if (!riList || riList.length === 0) {
|
||||
tbody.innerHTML = '<tr><td colspan="3" class="loading">Belum ada data penyaluran</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
tbody.innerHTML = riList.map(r => {
|
||||
const rp = new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', maximumFractionDigits: 0 }).format(r.nilai);
|
||||
return `
|
||||
<tr>
|
||||
<td><strong>${escapeHTML(r.nama)}</strong></td>
|
||||
<td>${r.count} kali</td>
|
||||
<td><strong>${rp}</strong></td>
|
||||
</tr>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function escapeHTML(str) {
|
||||
if (str == null) return '';
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
Reference in New Issue
Block a user