Files
2026-06-15 21:53:17 +07:00

301 lines
18 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
session_start();
if(!isset($_SESSION['user'])) { header('Location: login.php'); exit; }
if($_SESSION['role']!=='superadmin') { header('Location: index.php'); exit; }
require_once 'config.php';
$total_penduduk = $conn->query("SELECT COUNT(*) c FROM penduduk_miskin")->fetch_assoc()['c'];
$total_anggota = $conn->query("SELECT SUM(jumlah_anggota) c FROM penduduk_miskin")->fetch_assoc()['c'] ?? 0;
$total_ibadah = $conn->query("SELECT COUNT(*) c FROM rumah_ibadah")->fetch_assoc()['c'];
$terdaftar = $conn->query("SELECT COUNT(*) c FROM penduduk_miskin WHERE rumah_ibadah_id IS NOT NULL")->fetch_assoc()['c'];
$belum = $total_penduduk - $terdaftar;
$per_ibadah = $conn->query("SELECT ri.nama, COUNT(pm.id) AS jumlah FROM rumah_ibadah ri LEFT JOIN penduduk_miskin pm ON pm.rumah_ibadah_id=ri.id GROUP BY ri.id ORDER BY jumlah DESC");
$jenis_ibadah= $conn->query("SELECT jenis, COUNT(*) c FROM rumah_ibadah GROUP BY jenis ORDER BY c DESC");
$jenis_colors= ['Masjid'=>'blue','Gereja'=>'violet','Pura'=>'amber','Vihara'=>'green','Kelenteng'=>'cyan','Lainnya'=>'gray'];
$rows_ibadah=[]; $max=1;
while($r=$per_ibadah->fetch_assoc()){ $rows_ibadah[]=$r; if($r['jumlah']>$max) $max=$r['jumlah']; }
$rows_jenis=[];
while($r=$jenis_ibadah->fetch_assoc()) $rows_jenis[]=$r;
// Pagination logic for latest assistance distributions
$limit = 15;
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
$offset = ($page - 1) * $limit;
// Count total records
$total_bantuan = $conn->query("SELECT COUNT(*) c FROM riwayat_bantuan")->fetch_assoc()['c'];
$total_pages = ceil($total_bantuan / $limit);
$recent_bantuan = $conn->query("
SELECT rb.*, pm.nama_kk, ri.nama as nama_ibadah, ri2.nama as ibadah_terdaftar
FROM riwayat_bantuan rb
JOIN penduduk_miskin pm ON rb.penduduk_id = pm.id
LEFT JOIN rumah_ibadah ri ON rb.rumah_ibadah_id = ri.id
LEFT JOIN rumah_ibadah ri2 ON pm.rumah_ibadah_id = ri2.id
ORDER BY rb.tanggal_pemberian DESC, rb.id DESC
LIMIT $limit OFFSET $offset
");
$current = basename($_SERVER['PHP_SELF']);
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Dashboard — Pemetaan Kemiskinan Terpadu</title>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root{--bg:#f0f4f8;--white:#fff;--border:#e2e8f0;--text:#1e293b;--text2:#64748b;--text3:#94a3b8;--blue:#2563eb;--blue-lt:#dbeafe;--green:#16a34a;--green-lt:#dcfce7;--red:#dc2626;--red-lt:#fee2e2;--amber:#d97706;--amber-lt:#fef3c7;--violet:#7c3aed;--violet-lt:#ede9fe;--cyan:#0891b2;--cyan-lt:#cffafe;--sidebar:240px;--radius:12px;--shadow:0 1px 3px rgba(0,0,0,.08),0 4px 16px rgba(0,0,0,.06)}
*{box-sizing:border-box;margin:0;padding:0}body{font-family:'DM Sans',sans-serif;background:var(--bg);color:var(--text);min-height:100vh;display:flex}
#sidebar{width:var(--sidebar);min-width:var(--sidebar);background:var(--white);border-right:1px solid var(--border);display:flex;flex-direction:column;position:fixed;top:0;left:0;height:100vh;box-shadow:2px 0 8px rgba(0,0,0,.05);z-index:100}
.sb-brand{padding:20px 16px 16px;border-bottom:1px solid var(--border)}.sb-brand-logo{width:40px;height:40px;border-radius:10px;background:linear-gradient(135deg,#7c3aed,#2563eb);display:flex;align-items:center;justify-content:center;font-size:18px;margin-bottom:10px}.sb-brand h1{font-size:13px;font-weight:700;color:var(--text);line-height:1.3}.sb-brand p{font-size:10px;color:var(--text3);margin-top:2px}
.sb-nav{flex:1;overflow-y:auto;padding:10px 8px}.sb-lbl{font-size:9px;font-weight:700;color:var(--text3);text-transform:uppercase;letter-spacing:.8px;padding:10px 8px 4px}
.sb-item{display:flex;align-items:center;gap:9px;padding:9px 10px;border-radius:8px;cursor:pointer;font-size:13px;font-weight:500;color:var(--text2);transition:all .15s;text-decoration:none;margin-bottom:2px;border:1px solid transparent}.sb-item:hover{background:var(--bg);color:var(--text)}.sb-item.active{background:var(--violet-lt);color:var(--violet);border-color:#ddd6fe;font-weight:600}.sb-item .ico{font-size:15px;width:20px;text-align:center}
.sb-footer{padding:10px;border-top:1px solid var(--border)}
.btn-logout{width:100%;padding:8px;background:var(--red-lt);border:1px solid #fca5a5;border-radius:8px;font-size:12px;color:var(--red);cursor:pointer;font-family:inherit;font-weight:600;display:flex;align-items:center;justify-content:center;gap:6px;text-decoration:none;transition:all .15s}.btn-logout:hover{background:var(--red);color:#fff}
#main{margin-left:var(--sidebar);flex:1;display:flex;flex-direction:column;min-height:100vh}
.topbar{
height:56px;background:var(--white);border-bottom:1px solid var(--border);
display:flex;align-items:center;padding:0 28px;position:sticky;top:0;z-index:50;
}
.topbar h2{font-size:16px;font-weight:700;flex:1}
.topbar span{font-size:12px;color:var(--text3)}
.content{padding:28px;flex:1}
.stats-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:14px;margin-bottom:24px}
.stat-card{
background:var(--white);border:1px solid var(--border);border-radius:12px;
padding:18px 18px 16px;
}
.stat-label{font-size:11px;font-weight:600;color:var(--text3);text-transform:uppercase;letter-spacing:.04em;margin-bottom:10px}
.stat-n{font-size:30px;font-weight:700;font-family:'DM Mono',monospace;line-height:1}
.stat-n.blue{color:var(--blue)}.stat-n.green{color:var(--green)}.stat-n.violet{color:var(--violet)}
.stat-n.amber{color:var(--amber)}.stat-n.red{color:var(--red)}
.stat-sub{font-size:12px;color:var(--text2);margin-top:6px}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:20px}
@media(max-width:900px){.grid2{grid-template-columns:1fr}}
.card{background:var(--white);border:1px solid var(--border);border-radius:12px;overflow:hidden}
.card-head{padding:16px 18px;border-bottom:1px solid var(--border)}
.card-head h3{font-size:14px;font-weight:700}
.card-head p{font-size:12px;color:var(--text3);margin-top:3px}
.card-body{padding:16px 18px}
.bar-row{display:flex;align-items:center;gap:10px;margin-bottom:10px;font-size:12px}
.bar-lbl{width:130px;flex-shrink:0;color:var(--text2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bar-track{flex:1;background:var(--bg);border-radius:4px;height:7px;overflow:hidden}
.bar-fill{height:100%;border-radius:4px;background:var(--blue)}
.bar-val{width:24px;text-align:right;font-weight:700;font-family:'DM Mono',monospace;font-size:12px;flex-shrink:0}
.jenis-row{display:flex;align-items:center;justify-content:space-between;padding:9px 0;border-bottom:1px solid var(--border)}
.jenis-row:last-child{border-bottom:none}
.badge{display:inline-flex;padding:3px 10px;border-radius:6px;font-size:11px;font-weight:600}
.badge-blue{background:var(--blue-lt);color:var(--blue)}
.badge-green{background:var(--green-lt);color:var(--green)}
.badge-violet{background:var(--violet-lt);color:var(--violet)}
.badge-amber{background:var(--amber-lt);color:var(--amber)}
.badge-cyan{background:var(--cyan-lt);color:var(--cyan)}
.badge-gray{background:var(--bg);color:var(--text2)}
.jenis-count{font-size:13px;font-weight:600;font-family:'DM Mono',monospace}
.shortcut-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
@media(max-width:700px){.shortcut-grid{grid-template-columns:1fr}}
.shortcut{
background:var(--white);border:1px solid var(--border);border-radius:12px;
padding:16px 18px;text-decoration:none;display:flex;align-items:flex-start;gap:12px;
transition:border-color .15s,box-shadow .15s;
}
.shortcut:hover{border-color:#93c5fd;box-shadow:0 4px 14px rgba(29,78,216,.08)}
.shortcut-icon{
width:36px;height:36px;border-radius:9px;background:var(--bg);
display:flex;align-items:center;justify-content:center;flex-shrink:0;
border:1px solid var(--border);
}
.shortcut-icon svg{width:18px;height:18px;color:var(--blue)}
.shortcut-lbl{font-size:13px;font-weight:700;color:var(--text)}
.shortcut-sub{font-size:11px;color:var(--text3);margin-top:3px}
.pagination { display: flex; align-items: center; justify-content: center; gap: 6px; padding: 16px; border-top: 1px solid var(--border); }
.pagination a {
padding: 6px 12px; border: 1px solid var(--border); border-radius: 6px;
background: var(--white); color: var(--text2); font-size: 12px; font-weight: 600;
text-decoration: none; transition: all .15s;
}
.pagination a:hover { border-color: var(--blue); color: var(--blue); background: var(--blue-lt); }
.pagination span { font-size: 12px; color: var(--text3); font-weight: 500; }
</style>
</head>
<body>
<aside id="sidebar">
<div class="sb-brand"><div class="sb-brand-logo"><svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="#fff" stroke-width="2"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path><circle cx="12" cy="10" r="3"></circle></svg></div><h1>Kemiskinan Terpadu</h1><p>Panel Superadmin</p></div>
<nav class="sb-nav">
<div class="sb-lbl">Menu</div>
<a href="dashboard.php" class="sb-item <?= $current==='dashboard.php'?'active':'' ?>"><span class="ico"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg></span> Dashboard</a>
<a href="data_penduduk.php" class="sb-item <?= $current==='data_penduduk.php'?'active':'' ?>"><span class="ico"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75"/></svg></span> Data Penduduk</a>
<a href="data_ibadah.php" class="sb-item <?= $current==='data_ibadah.php'?'active':'' ?>"><span class="ico"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 21h18M5 21V7l7-4 7 4v14"/><path d="M9 21v-6h6v6"/></svg></span> Rumah Ibadah</a>
<div class="sb-lbl">Navigasi</div>
<a href="index.php?readonly=1" class="sb-item" target="_blank"><span class="ico"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6"/><line x1="8" y1="2" x2="8" y2="18"/><line x1="16" y1="6" x2="16" y2="22"/></svg></span> Lihat Peta GIS</a>
</nav>
<div class="sb-footer">
<?php include __DIR__.'/includes/user-profile.php'; ?>
<a href="logout.php" class="btn-logout" data-confirm-logout>Keluar</a>
</div>
</aside>
<?php include __DIR__.'/includes/confirm-modal.php'; ?>
<main id="main">
<div class="topbar">
<h2>Dashboard</h2>
<span>Diperbarui <?= date('d M Y, H:i') ?> WIB</span>
</div>
<div class="content">
<div class="stats-grid">
<div class="stat-card">
<div class="stat-label">KK Penduduk Miskin</div>
<div class="stat-n blue"><?= $total_penduduk ?></div>
<div class="stat-sub">Kepala keluarga terdata</div>
</div>
<div class="stat-card">
<div class="stat-label">Total Jiwa</div>
<div class="stat-n green"><?= $total_anggota ?></div>
<div class="stat-sub">Anggota keluarga</div>
</div>
<div class="stat-card">
<div class="stat-label">Rumah Ibadah</div>
<div class="stat-n violet"><?= $total_ibadah ?></div>
<div class="stat-sub">Titik ibadah aktif</div>
</div>
<div class="stat-card">
<div class="stat-label">Terdaftar Radius</div>
<div class="stat-n amber"><?= $terdaftar ?></div>
<div class="stat-sub">KK dalam cakupan</div>
</div>
<div class="stat-card">
<div class="stat-label">Belum Terdaftar</div>
<div class="stat-n red"><?= $belum ?></div>
<div class="stat-sub">Di luar radius ibadah</div>
</div>
</div>
<div class="grid2">
<div class="card">
<div class="card-head">
<h3>Binaan per Rumah Ibadah</h3>
<p>Jumlah KK dalam radius tiap tempat ibadah</p>
</div>
<div class="card-body">
<?php foreach($rows_ibadah as $r): $pct=$max>0?round($r['jumlah']/$max*100):0; ?>
<div class="bar-row">
<div class="bar-lbl" title="<?= htmlspecialchars($r['nama']) ?>"><?= htmlspecialchars($r['nama']) ?></div>
<div class="bar-track"><div class="bar-fill" style="width:<?= $pct ?>%"></div></div>
<div class="bar-val"><?= $r['jumlah'] ?></div>
</div>
<?php endforeach ?>
</div>
</div>
<div class="card">
<div class="card-head">
<h3>Sebaran Jenis Rumah Ibadah</h3>
<p>Komposisi berdasarkan jenis bangunan</p>
</div>
<div class="card-body">
<?php foreach($rows_jenis as $r): $col=$jenis_colors[$r['jenis']]??'gray'; ?>
<div class="jenis-row">
<span class="badge badge-<?= $col ?>"><?= htmlspecialchars($r['jenis']) ?></span>
<span class="jenis-count"><?= $r['c'] ?> tempat</span>
</div>
<?php endforeach ?>
</div>
</div>
</div>
<div class="shortcut-grid" style="margin-bottom: 24px">
<a href="data_penduduk.php" class="shortcut">
<div class="shortcut-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/></svg>
</div>
<div>
<div class="shortcut-lbl">Data Penduduk</div>
<div class="shortcut-sub"><?= $total_penduduk ?> KK · <?= $total_anggota ?> jiwa</div>
</div>
</a>
<a href="data_ibadah.php" class="shortcut">
<div class="shortcut-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 21h18M5 21V7l7-4 7 4v14"/></svg>
</div>
<div>
<div class="shortcut-lbl">Rumah Ibadah</div>
<div class="shortcut-sub"><?= $total_ibadah ?> tempat ibadah</div>
</div>
</a>
</div>
<!-- Card Log Pembagian Bantuan Terbaru -->
<div class="card" style="margin-bottom: 24px">
<div class="card-head">
<h3>Log Pembagian Bantuan Terbaru</h3>
<p>Aktivitas penyaluran bantuan sosial kepada keluarga binaan</p>
</div>
<div class="card-body" style="padding: 0; overflow-x: auto;">
<table style="width: 100%; border-collapse: collapse; font-size: 13px; text-align: left;">
<thead>
<tr style="background: #f8fafc; border-bottom: 1px solid var(--border)">
<th style="padding: 12px 16px; font-weight: 600; color: var(--text2)">Nama Kepala Keluarga</th>
<th style="padding: 12px 16px; font-weight: 600; color: var(--text2)">Lokasi Tempat Ibadah</th>
<th style="padding: 12px 16px; font-weight: 600; color: var(--text2)">Jenis Bantuan</th>
<th style="padding: 12px 16px; font-weight: 600; color: var(--text2)">Tanggal Diberikan</th>
<th style="padding: 12px 16px; font-weight: 600; color: var(--text2)">Keterangan</th>
</tr>
</thead>
<tbody>
<?php if ($recent_bantuan->num_rows > 0): ?>
<?php while($rb = $recent_bantuan->fetch_assoc()): ?>
<tr style="border-bottom: 1px solid #f1f5f9">
<td style="padding: 12px 16px; font-weight: 600">
<?= htmlspecialchars($rb['nama_kk']) ?>
<?php if ($rb['nama_ibadah']): ?>
<br><span style="font-size: 11px; color: var(--blue); font-weight: normal;"><svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="currentColor" stroke-width="2" style="display:inline-block;vertical-align:middle;margin-right:3px;margin-top:-2px"><path d="M3 21h18M5 21V7l7-4 7 4v14"/><path d="M9 21v-6h6v6"/></svg><?= htmlspecialchars($rb['nama_ibadah']) ?></span>
<?php endif; ?>
</td>
<td style="padding: 12px 16px;">
<?php if ($rb['ibadah_terdaftar']): ?>
<span style="font-weight: 600; display: inline-flex; align-items: center; gap: 4px; color: var(--blue)">
<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" style="display:inline-block;vertical-align:middle"><path d="M3 21h18M5 21V7l7-4 7 4v14"/><path d="M9 21v-6h6v6"/></svg>
<?= htmlspecialchars($rb['ibadah_terdaftar']) ?>
</span>
<?php else: ?>
<span style="color: var(--red); font-weight: 500;">❌ Belum Terdaftar</span>
<?php endif; ?>
</td>
<td style="padding: 12px 16px;"><span class="badge badge-green" style="font-weight:normal"><?= htmlspecialchars($rb['jenis_bantuan']) ?></span></td>
<td style="padding: 12px 16px; font-family: 'DM Mono', monospace; color: var(--text2)"><?= date('d/m/Y', strtotime($rb['tanggal_pemberian'])) ?></td>
<td style="padding: 12px 16px; color: var(--text2)"><?= htmlspecialchars($rb['keterangan'] ?? '—') ?></td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="5" style="padding: 24px; text-align: center; color: var(--text3)">Belum ada riwayat pembagian bantuan.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<?php if ($total_pages > 1): ?>
<div class="pagination">
<?php if ($page > 1): ?>
<a href="?page=<?= $page - 1 ?>"> Seb</a>
<?php endif; ?>
<span>Halaman <?= $page ?> dari <?= $total_pages ?></span>
<?php if ($page < $total_pages): ?>
<a href="?page=<?= $page + 1 ?>">Sel </a>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</div>
</main>
</body></html>