Files
UAS_WebGIS_MuthiaNurainiAst…/SIG_miskin/gis/data_penduduk.php
T
2026-06-11 18:10:22 +07:00

207 lines
16 KiB
PHP
Raw 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';
$per_page = 15;
$page = max(1, intval($_GET['page'] ?? 1));
$cari = trim($_GET['cari'] ?? '');
$offset = ($page - 1) * $per_page;
$where = '';
if($cari !== '') {
$c = $conn->real_escape_string($cari);
$where = "WHERE pm.nama_kk LIKE '%$c%' OR pm.alamat LIKE '%$c%' OR ri.nama LIKE '%$c%'";
}
$total_rows = $conn->query("SELECT COUNT(*) c FROM penduduk_miskin pm LEFT JOIN rumah_ibadah ri ON ri.id=pm.rumah_ibadah_id $where")->fetch_assoc()['c'];
$total_pages= max(1, ceil($total_rows / $per_page));
$page = min($page, $total_pages);
$offset = ($page - 1) * $per_page;
$data = $conn->query("
SELECT pm.*, ri.nama AS nama_ibadah, ri.jenis AS jenis_ibadah,
(SELECT GROUP_CONCAT(CONCAT(rb.jenis_bantuan, ' (', DATE_FORMAT(rb.tanggal_pemberian, '%d/%m/%Y'), ')') ORDER BY rb.tanggal_pemberian DESC SEPARATOR ', ')
FROM riwayat_bantuan rb WHERE rb.penduduk_id = pm.id) AS riwayat_bantuan_list
FROM penduduk_miskin pm
LEFT JOIN rumah_ibadah ri ON ri.id = pm.rumah_ibadah_id
$where
ORDER BY pm.id ASC
LIMIT $per_page OFFSET $offset
");
// Untuk download CSV — ambil semua tanpa limit
$all = $conn->query("
SELECT pm.nama_kk, pm.jumlah_anggota, pm.alamat,
(SELECT GROUP_CONCAT(CONCAT(rb.jenis_bantuan, ' (', DATE_FORMAT(rb.tanggal_pemberian, '%d/%m/%Y'), ')') ORDER BY rb.tanggal_pemberian DESC SEPARATOR '; ')
FROM riwayat_bantuan rb WHERE rb.penduduk_id = pm.id) AS riwayat_bantuan_list,
ri.nama AS nama_ibadah, ri.jenis AS jenis_ibadah, pm.jarak_ke_ibadah,
IF(pm.rumah_ibadah_id IS NOT NULL,'Terdaftar','Belum Terdaftar') AS status, pm.lat, pm.lng
FROM penduduk_miskin pm
LEFT JOIN rumah_ibadah ri ON ri.id=pm.rumah_ibadah_id
ORDER BY pm.id ASC
");
$all_rows = [];
while($r=$all->fetch_assoc()) $all_rows[]=$r;
$jenis_colors=['Masjid'=>'blue','Gereja'=>'violet','Pura'=>'amber','Vihara'=>'green','Kelenteng'=>'cyan','Lainnya'=>'gray'];
$current = basename($_SERVER['PHP_SELF']);
function pag_url($p, $cari) {
$q = $cari !== '' ? '&cari='.urlencode($cari) : '';
return '?page='.$p.$q;
}
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Data Penduduk — Pemetaan Kemiskinan Terpadu</title>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@300;400;500;600;700;800&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 24px;gap:12px;position:sticky;top:0;z-index:50}.topbar h2{font-size:15px;font-weight:700;flex:1}.topbar span{font-size:12px;color:var(--text3)}
.content{padding:24px;flex:1}
.page-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}
.page-title h2{font-size:17px;font-weight:800}.page-title p{font-size:12px;color:var(--text3);margin-top:2px}
.btn-dl{display:inline-flex;align-items:center;gap:7px;padding:8px 16px;background:var(--green);color:#fff;border:none;border-radius:8px;font-size:13px;font-weight:600;cursor:pointer;font-family:inherit;transition:background .15s}.btn-dl:hover{background:#15803d}
.tbl-wrap{background:var(--white);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow)}
.tbl-toolbar{padding:12px 14px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px}
.tbl-toolbar form{display:flex;gap:8px;flex:1}
.tbl-toolbar input{flex:1;padding:7px 10px;border:1px solid var(--border);border-radius:8px;font-family:inherit;font-size:12.5px;color:var(--text);background:var(--bg);outline:none}.tbl-toolbar input:focus{border-color:var(--blue);background:#fff}
.tbl-toolbar button{padding:7px 14px;background:var(--blue);color:#fff;border:none;border-radius:8px;font-size:12.5px;font-weight:600;cursor:pointer;font-family:inherit}
.tbl-info{font-size:12px;color:var(--text3);white-space:nowrap}
table{width:100%;border-collapse:collapse;font-size:12.5px}
thead th{padding:10px 14px;text-align:left;font-size:10px;font-weight:700;color:var(--text3);text-transform:uppercase;letter-spacing:.5px;background:var(--bg);border-bottom:1px solid var(--border);white-space:nowrap}
tbody td{padding:10px 14px;border-bottom:1px solid var(--border);vertical-align:middle}
tbody tr:last-child td{border-bottom:none}tbody tr:hover{background:#fafbfc}
.badge{display:inline-flex;align-items:center;padding:2px 8px;border-radius:20px;font-size:10px;font-weight:700}
.badge-blue{background:var(--blue-lt);color:var(--blue)}.badge-green{background:var(--green-lt);color:var(--green)}.badge-red{background:var(--red-lt);color:var(--red)}.badge-amber{background:var(--amber-lt);color:var(--amber)}.badge-violet{background:var(--violet-lt);color:var(--violet)}.badge-cyan{background:var(--cyan-lt);color:var(--cyan)}.badge-gray{background:var(--bg);color:var(--text2);border:1px solid var(--border)}
.pagination{display:flex;align-items:center;gap:5px;padding:12px 14px;border-top:1px solid var(--border);flex-wrap:wrap}
.pag-btn{padding:5px 11px;border:1px solid var(--border);border-radius:7px;background:var(--white);font-size:12px;font-weight:600;cursor:pointer;color:var(--text2);text-decoration:none;transition:all .15s;font-family:inherit;display:inline-flex;align-items:center}
.pag-btn:hover{border-color:var(--blue);color:var(--blue)}.pag-btn.active{background:var(--blue);color:#fff;border-color:var(--blue)}.pag-btn.disabled{opacity:.4;pointer-events:none}
.pag-info{font-size:12px;color:var(--text3);margin-left:auto}
</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>Data Penduduk Miskin</h2><span>Total <?= $total_rows ?> KK ditemukan</span></div>
<div class="content">
<div class="page-head">
<div class="page-title">
<h2>Daftar Penduduk Miskin</h2>
<p>Menampilkan halaman <?= $page ?> dari <?= $total_pages ?> · <?= $total_rows ?> data total</p>
</div>
<button class="btn-dl" onclick="downloadCSV()"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg> Download Excel</button>
</div>
<div class="tbl-wrap">
<div class="tbl-toolbar">
<form method="GET" action="">
<div style="position:relative;flex:1;display:flex;align-items:center;">
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" style="position:absolute;left:10px;color:var(--text3)"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
<input type="text" name="cari" value="<?= htmlspecialchars($cari) ?>" placeholder="Cari nama KK, alamat, rumah ibadah..." style="padding-left:32px;width:100%;">
</div>
<button type="submit">Cari</button>
<?php if($cari): ?><a href="data_penduduk.php" style="padding:7px 12px;border:1px solid var(--border);border-radius:8px;font-size:12px;color:var(--text2);text-decoration:none">✕ Reset</a><?php endif ?>
</form>
<span class="tbl-info"><?= $per_page*(($page-1)+1)-($per_page-1) ?><?= min($per_page*$page,$total_rows) ?> dari <?= $total_rows ?></span>
</div>
<table>
<thead>
<tr>
<th>#</th><th>Nama KK</th><th>Anggota</th><th>Alamat</th>
<th>Riwayat Bantuan</th>
<th>Rumah Ibadah Terdekat</th><th>Jarak</th><th>Status</th><th>Foto</th>
</tr>
</thead>
<tbody>
<?php $no=($page-1)*$per_page+1; while($r=$data->fetch_assoc()): ?>
<tr>
<td style="color:var(--text3);font-family:'DM Mono',monospace"><?= $no++ ?></td>
<td><b><?= htmlspecialchars($r['nama_kk']) ?></b></td>
<td style="font-family:'DM Mono',monospace;text-align:center"><?= $r['jumlah_anggota'] ?></td>
<td style="color:var(--text2);max-width:180px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis" title="<?= htmlspecialchars($r['alamat']??'') ?>"><?= htmlspecialchars($r['alamat']??'—') ?></td>
<td>
<?php if($r['riwayat_bantuan_list']): ?>
<?php
$items = explode(', ', $r['riwayat_bantuan_list']);
foreach($items as $idx => $item):
if ($idx < 2): ?>
<span class="badge badge-green" style="margin:2px; font-weight:normal"><?= htmlspecialchars($item) ?></span>
<?php else: ?>
<span class="badge badge-gray" style="margin:2px; font-weight:normal" title="<?= htmlspecialchars($r['riwayat_bantuan_list']) ?>">+<?= count($items) - 2 ?> lainnya</span>
<?php break;
endif;
endforeach; ?>
<?php else: ?>
<span style="color:var(--text3)">Belum ada bantuan</span>
<?php endif; ?>
</td>
<td><?php if($r['nama_ibadah']): $col=$jenis_colors[$r['jenis_ibadah']]??'gray'; ?><span class="badge badge-<?= $col ?>"><?= htmlspecialchars($r['nama_ibadah']) ?></span><?php else: ?><span style="color:var(--text3)">—</span><?php endif ?></td>
<td style="font-family:'DM Mono',monospace;color:var(--text2)"><?= $r['jarak_ke_ibadah'] ? number_format($r['jarak_ke_ibadah'],0).' m' : '—' ?></td>
<td><?= $r['rumah_ibadah_id'] ? '<span class="badge badge-green"><svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="currentColor" stroke-width="3" style="margin-right:4px"><polyline points="20 6 9 17 4 12"></polyline></svg>Terdaftar</span>' : '<span class="badge badge-red"><svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="currentColor" stroke-width="3" style="margin-right:4px"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>Belum</span>' ?></td>
<td><?php if($r['foto_rumah']): ?><a href="<?= htmlspecialchars($r['foto_rumah']) ?>" target="_blank" style="display:flex;align-items:center;color:var(--blue);text-decoration:none" title="Lihat foto"><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg></a><?php else: ?><span style="color:var(--text3)">—</span><?php endif ?></td>
</tr>
<?php endwhile ?>
</tbody>
</table>
<div class="pagination">
<a href="<?= pag_url(1,$cari) ?>" class="pag-btn <?= $page<=1?'disabled':'' ?>">«</a>
<a href="<?= pag_url(max(1,$page-1),$cari) ?>" class="pag-btn <?= $page<=1?'disabled':'' ?>"></a>
<?php
$from=max(1,$page-2); $to=min($total_pages,$page+2);
for($i=$from;$i<=$to;$i++): ?>
<a href="<?= pag_url($i,$cari) ?>" class="pag-btn <?= $i===$page?'active':'' ?>"><?= $i ?></a>
<?php endfor ?>
<a href="<?= pag_url(min($total_pages,$page+1),$cari) ?>" class="pag-btn <?= $page>=$total_pages?'disabled':'' ?>"></a>
<a href="<?= pag_url($total_pages,$cari) ?>" class="pag-btn <?= $page>=$total_pages?'disabled':'' ?>">»</a>
<span class="pag-info">Halaman <?= $page ?> / <?= $total_pages ?></span>
</div>
</div>
</div>
</main>
<script>
const allData = <?= json_encode($all_rows) ?>;
function downloadCSV(){
if(!allData.length) return;
const keys=['Nama KK','Jumlah Anggota','Alamat','Riwayat Penerimaan Bantuan','Rumah Ibadah','Jenis Ibadah','Jarak (m)','Status','Lat','Lng'];
const map =['nama_kk','jumlah_anggota','alamat','riwayat_bantuan_list','nama_ibadah','jenis_ibadah','jarak_ke_ibadah','status','lat','lng'];
const rows=[keys,...allData.map(r=>map.map(k=>'"'+(r[k]??'')+'"'))];
const csv='\uFEFF'+rows.map(r=>r.join(',')).join('\n');
const a=document.createElement('a');
a.href='data:text/csv;charset=utf-8,'+encodeURIComponent(csv);
a.download='penduduk_miskin_<?= date('Ymd') ?>.csv';
a.click();
}
</script>
</body></html>