UAS SIG Proyek WebGis

This commit is contained in:
L4zyL4mb
2026-06-10 21:46:56 +07:00
commit df18a7a99a
35 changed files with 8977 additions and 0 deletions
+246
View File
@@ -0,0 +1,246 @@
<?php
// api/export_pdf.php v2.0
// ============================================================
// Export Laporan PDF menggunakan HTML → browser print
// (Pure PHP, tanpa library eksternal)
// ============================================================
require_once __DIR__ . '/../includes/config.php';
$db = getDB();
// ── Filter ────────────────────────────────────────────────
$kelurahan = $_GET['kelurahan'] ?? null;
$kecamatan = $_GET['kecamatan'] ?? null;
$kategori = $_GET['kategori'] ?? null;
$verifikasi = $_GET['verifikasi'] ?? null;
$where = "WHERE 1=1";
$params = [];
if ($kelurahan) { $where .= " AND w.kelurahan = ?"; $params[] = $kelurahan; }
if ($kecamatan) { $where .= " AND w.kecamatan = ?"; $params[] = $kecamatan; }
if ($kategori) { $where .= " AND pm.kategori_kemiskinan = ?"; $params[] = $kategori; }
if ($verifikasi) { $where .= " AND pm.status_verifikasi = ?"; $params[] = $verifikasi; }
// Data penduduk
$stmt = $db->prepare("
SELECT pm.nik_kk, pm.nama_kk, pm.no_hp, pm.alamat, pm.rt, pm.rw,
COALESCE(w.kelurahan,'') AS kelurahan,
pm.jumlah_anggota, pm.jumlah_anak_sekolah,
pm.penghasilan_bulanan, pm.status_pekerjaan,
pm.kategori_kemiskinan, pm.kondisi_rumah,
CASE pm.punya_bpjs WHEN 1 THEN 'Ya' ELSE 'Tidak' END AS punya_bpjs,
pm.status_verifikasi,
(SELECT GROUP_CONCAT(jb.kode ORDER BY jb.kode SEPARATOR ', ')
FROM bantuan_penduduk bp JOIN jenis_bantuan jb ON jb.id = bp.bantuan_id
WHERE bp.penduduk_id = pm.id AND bp.status='aktif') AS bantuan
FROM penduduk_miskin pm
LEFT JOIN wilayah w ON w.id = pm.wilayah_id
$where
ORDER BY w.kelurahan, pm.kategori_kemiskinan, pm.nama_kk
");
$stmt->execute($params);
$rows = $stmt->fetchAll();
// Statistik ringkas
$statsStmt = $db->prepare("
SELECT COUNT(*) AS total, SUM(pm.jumlah_anggota) AS jiwa,
SUM(CASE WHEN pm.kategori_kemiskinan='sangat_miskin' THEN 1 ELSE 0 END) AS sangat_miskin,
SUM(CASE WHEN pm.kategori_kemiskinan='miskin' THEN 1 ELSE 0 END) AS miskin,
SUM(CASE WHEN pm.kategori_kemiskinan='hampir_miskin' THEN 1 ELSE 0 END) AS hampir_miskin,
SUM(CASE WHEN pm.kategori_kemiskinan='mampu' THEN 1 ELSE 0 END) AS mampu,
SUM(CASE WHEN EXISTS(SELECT 1 FROM bantuan_penduduk bp WHERE bp.penduduk_id=pm.id AND bp.status='aktif') THEN 1 ELSE 0 END) AS penerima
FROM penduduk_miskin pm LEFT JOIN wilayah w ON w.id = pm.wilayah_id $where
");
$statsStmt->execute($params);
$stats = $statsStmt->fetch();
$judul = "LAPORAN DATA PENDUDUK MISKIN";
$filter = $kelurahan ? " Kelurahan $kelurahan" : ($kecamatan ? " Kec. $kecamatan" : " Seluruh Wilayah");
$tgl = date('d F Y');
// Warna kategori
function warnaBg(string $k): string {
return match($k) {
'sangat_miskin' => '#fee2e2',
'miskin' => '#fef3c7',
'hampir_miskin' => '#dcfce7',
'mampu' => '#dbeafe',
default => '#f3f4f6',
};
}
function labelKat(string $k): string {
return match($k) {
'sangat_miskin' => 'Sangat Miskin',
'miskin' => 'Miskin',
'hampir_miskin' => 'Nyaris Miskin',
'mampu' => 'Mampu',
default => $k,
};
}
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title><?= htmlspecialchars($judul . $filter) ?></title>
<style>
@page { size: A4 landscape; margin: 15mm 10mm; }
@media print {
.no-print { display: none; }
body { font-size: 8pt; }
table { font-size: 7.5pt; }
thead { display: table-header-group; }
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: Arial, sans-serif; font-size: 9pt; color: #111; background: #fff; }
/* Header laporan */
.kop { text-align: center; border-bottom: 3px double #1e3a5f; padding-bottom: 10px; margin-bottom: 14px; }
.kop h1 { font-size: 13pt; font-weight: 900; text-transform: uppercase; color: #1e3a5f; }
.kop h2 { font-size: 11pt; font-weight: 700; margin: 2px 0; }
.kop p { font-size: 8pt; color: #555; }
/* Statistik */
.stat-grid { display: flex; gap: 8px; margin-bottom: 14px; }
.stat-box {
flex: 1; border: 1px solid #ddd; border-radius: 6px;
padding: 7px 10px; text-align: center; background: #f8faff;
}
.stat-box .val { font-size: 16pt; font-weight: 900; color: #1e3a5f; }
.stat-box .lbl { font-size: 7pt; color: #666; text-transform: uppercase; }
/* Tabel */
table { width: 100%; border-collapse: collapse; margin-top: 4px; }
th { background: #1e3a5f; color: #fff; padding: 5px 4px; text-align: center; font-size: 7.5pt; border: 1px solid #1e3a5f; }
td { padding: 4px; border: 1px solid #ddd; vertical-align: top; font-size: 7.5pt; }
tr:nth-child(even) td { background: #f9fafb; }
.badge-sm {
display: inline-block; padding: 1px 5px; border-radius: 3px;
font-size: 6.5pt; font-weight: bold;
}
.c { text-align: center; }
.r { text-align: right; }
/* Footer */
.footer { margin-top: 20px; display: flex; justify-content: space-between; font-size: 8pt; }
.ttd-box { text-align: center; width: 200px; }
.ttd-box .line { border-top: 1px solid #111; margin-top: 50px; padding-top: 3px; font-weight: bold; }
/* Print button */
.no-print { text-align: center; margin: 12px 0; }
.btn-print {
background: #1e3a5f; color: #fff; border: none; padding: 8px 24px;
border-radius: 5px; font-size: 10pt; cursor: pointer; margin-right: 8px;
}
.btn-print:hover { background: #274e81; }
</style>
</head>
<body>
<!-- Print Button -->
<div class="no-print">
<button class="btn-print" onclick="window.print()">🖨 Cetak / Simpan PDF</button>
<button class="btn-print" style="background:#555;" onclick="window.close()">✕ Tutup</button>
</div>
<!-- Kop Surat -->
<div class="kop">
<h1><?= htmlspecialchars($judul) ?></h1>
<h2>SISTEM INFORMASI GEOGRAFIS KEMISKINAN<?= htmlspecialchars($filter) ?></h2>
<p>Dicetak pada: <?= $tgl ?> &nbsp;|&nbsp; Total: <?= count($rows) ?> KK</p>
</div>
<!-- Statistik Ringkas -->
<div class="stat-grid">
<div class="stat-box"><div class="val"><?= number_format($stats['total']) ?></div><div class="lbl">Total KK</div></div>
<div class="stat-box"><div class="val"><?= number_format($stats['jiwa']) ?></div><div class="lbl">Total Jiwa</div></div>
<div class="stat-box" style="background:#fee2e2"><div class="val"><?= number_format($stats['sangat_miskin']) ?></div><div class="lbl">Sangat Miskin</div></div>
<div class="stat-box" style="background:#fef3c7"><div class="val"><?= number_format($stats['miskin']) ?></div><div class="lbl">Miskin</div></div>
<div class="stat-box" style="background:#dcfce7"><div class="val"><?= number_format($stats['hampir_miskin']) ?></div><div class="lbl">Nyaris Miskin</div></div>
<div class="stat-box" style="background:#dbeafe"><div class="val"><?= number_format($stats['mampu']) ?></div><div class="lbl">Mampu</div></div>
<div class="stat-box"><div class="val"><?= number_format($stats['penerima']) ?></div><div class="lbl">Penerima Bantuan</div></div>
<div class="stat-box" style="background:#fff7ed"><div class="val"><?= number_format($stats['total'] - $stats['penerima']) ?></div><div class="lbl">Belum Bantuan</div></div>
</div>
<!-- Tabel Data -->
<table>
<thead>
<tr>
<th style="width:2%">No</th>
<th style="width:11%">NIK / Nama KK</th>
<th style="width:6%">Kelurahan</th>
<th style="width:4%">RT/RW</th>
<th style="width:13%">Alamat</th>
<th style="width:3%">Angg.</th>
<th style="width:3%">Anak</th>
<th style="width:7%">Penghasilan</th>
<th style="width:7%">Pekerjaan</th>
<th style="width:8%">Kategori</th>
<th style="width:7%">Kondisi Rumah</th>
<th style="width:4%">BPJS</th>
<th style="width:11%">Bantuan Diterima</th>
<th style="width:10%">Status Verifikasi</th>
</tr>
</thead>
<tbody>
<?php $no = 1; foreach ($rows as $r): ?>
<tr>
<td class="c"><?= $no++ ?></td>
<td>
<small style="color:#666"><?= htmlspecialchars($r['nik_kk']) ?></small><br>
<strong><?= htmlspecialchars($r['nama_kk']) ?></strong><br>
<small><?= htmlspecialchars($r['no_hp'] ?? '') ?></small>
</td>
<td class="c"><?= htmlspecialchars($r['kelurahan']) ?></td>
<td class="c"><?= ($r['rt'] ? $r['rt'].'/'.$r['rw'] : '') ?></td>
<td><?= htmlspecialchars($r['alamat'] ?? '') ?></td>
<td class="c"><?= $r['jumlah_anggota'] ?></td>
<td class="c"><?= $r['jumlah_anak_sekolah'] ?></td>
<td class="r"><?= $r['penghasilan_bulanan'] ? 'Rp '.number_format($r['penghasilan_bulanan'],0,',','.') : '' ?></td>
<td><?= htmlspecialchars(ucwords(str_replace('_',' ',$r['status_pekerjaan']))) ?></td>
<td class="c">
<span class="badge-sm" style="background:<?= warnaBg($r['kategori_kemiskinan']) ?>">
<?= labelKat($r['kategori_kemiskinan']) ?>
</span>
</td>
<td class="c"><?= htmlspecialchars(ucwords(str_replace('_',' ',$r['kondisi_rumah']))) ?></td>
<td class="c"><?= $r['punya_bpjs'] ?></td>
<td>
<?php if ($r['bantuan']): ?>
<?php foreach (explode(', ', $r['bantuan']) as $b): ?>
<span class="badge-sm" style="background:#dbeafe;color:#1e40af"><?= htmlspecialchars(trim($b)) ?></span>
<?php endforeach; ?>
<?php else: ?>
<span style="color:#dc2626">Belum Ada</span>
<?php endif; ?>
</td>
<td class="c">
<?php
$sv = $r['status_verifikasi'];
$svColor = match($sv) { 'terverifikasi'=>'#dcfce7', 'belum_diverifikasi'=>'#fef3c7', default=>'#fee2e2' };
?>
<span class="badge-sm" style="background:<?= $svColor ?>">
<?= htmlspecialchars(ucwords(str_replace('_',' ',$sv))) ?>
</span>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<!-- Footer / TTD -->
<div class="footer">
<div>
<p>Dicetak: <?= date('d/m/Y H:i') ?> WIB</p>
<p>Filter: <?= htmlspecialchars(implode(', ', array_filter([$kelurahan, $kecamatan, $kategori ? "Kategori: $kategori" : null])) ?: 'Semua Data') ?></p>
<p>Sumber: SIG Kemiskinan v2.0</p>
</div>
<div class="ttd-box">
<p>Pontianak, <?= $tgl ?></p>
<p>Mengetahui,</p>
<div class="line">Kepala Dinas / Pejabat Berwenang</div>
</div>
</div>
</body>
</html>