301 lines
18 KiB
PHP
301 lines
18 KiB
PHP
<?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>
|