Upload files to "/"

This commit is contained in:
2026-06-03 05:03:55 +00:00
commit aca3515dca
4 changed files with 772 additions and 0 deletions
+205
View File
@@ -0,0 +1,205 @@
<?php
// dashboard-pemerintah.php
require_once 'koneksi.php';
cekLogin(); // Memastikan user sudah login
// Proteksi: Hanya Role Pemerintah yang Boleh Mengakses Halaman Ini
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'pemerintah') {
header('Location: login.php');
exit;
}
$page = 'beranda'; // Penanda agar menu "Beranda" di sidebar menyala biru
$pageTitle = 'Dashboard Pemerintah';
// Mengambil Data Statistik Utama untuk Instansi Pemerintah
$totalIbadah = $conn->query("SELECT COUNT(*) AS c FROM rumah_ibadah")->fetch_assoc()['c'] ?? 0;
$totalKpm = $conn->query("SELECT COUNT(*) AS c FROM rumah_miskin")->fetch_assoc()['c'] ?? 0;
$terjangkau = $conn->query("SELECT COUNT(*) AS c FROM rumah_miskin WHERE status_bantuan='Terjangkau'")->fetch_assoc()['c'] ?? 0;
$blankSpot = $conn->query("SELECT COUNT(*) AS c FROM rumah_miskin WHERE status_bantuan='Belum Terbantu'")->fetch_assoc()['c'] ?? 0;
$bencanaAktif = $conn->query("SELECT COUNT(*) AS c FROM bencana WHERE status='Aktif'")->fetch_assoc()['c'] ?? 0;
$totalBantuan = $conn->query("SELECT COUNT(*) AS c FROM bantuan_tersalur")->fetch_assoc()['c'] ?? 0;
$pct = $totalKpm > 0 ? round($terjangkau / $totalKpm * 100) : 0;
// Preview Log Data Lapangan Terkini (Limit 5)
$kpmBaru = $conn->query("SELECT nama_kepala_keluarga, nik, kelurahan, kondisi_rumah FROM rumah_miskin ORDER BY created_at DESC LIMIT 5");
$bantuanBaru = $conn->query("SELECT bt.jenis_bantuan, bt.jumlah, bt.tanggal, rm.nama_kepala_keluarga FROM bantuan_tersalur bt LEFT JOIN rumah_miskin rm ON bt.warga_id=rm.id ORDER BY bt.created_at DESC LIMIT 5");
// MEMANGGIL SIDEBAR PREMIUM
include 'includes/sidebar.php';
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Panel Monitoring Pemerintah - Poverty Mapping</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"/>
<style>
.db-wrap { max-width: 1200px; font-family: 'Inter', sans-serif; }
/* Welcome Banner Pemerintah (Gradasi Royal Blue - Indigo yang Formal) */
.db-welcome {
background: linear-gradient(135deg, #1e3a8a 0%, #4338ca 100%);
color: white;
border-radius: 16px;
padding: 26px 28px;
margin-bottom: 24px;
box-shadow: 0 10px 25px -5px rgba(30, 58, 138, 0.2);
position: relative;
overflow: hidden;
}
.db-welcome h1 { font-size: 22px; font-weight: 700; margin-bottom: 6px; }
.db-welcome p { font-size: 13px; opacity: 0.9; max-width: 750px; line-height: 1.5; }
/* Grid Kartu Statistik */
.stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 24px; }
.scard {
background: #fff; border: 1px solid #e2e8f0; border-radius: 14px; padding: 20px;
display: flex; align-items: center; justify-content: space-between;
transition: box-shadow .2s, transform .2s; box-shadow: 0 4px 6px -1px rgba(15,23,42,0.02);
}
.scard:hover { box-shadow: 0 12px 20px -5px rgba(15, 23, 42, 0.05); transform: translateY(-4px); }
.scard-label { font-size: 11px; font-weight: 700; color: #64748b; text-transform: uppercase; letter-spacing: .5px; margin-bottom: 6px; }
.scard-num { font-size: 26px; font-weight: 800; line-height: 1; color: #0f172a; }
.scard-sub { font-size: 11px; color: #64748b; margin-top: 5px; }
.scard-icon { width: 44px; height: 44px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 16px; }
/* Progress Box */
.coverage-box {
background: #fff; border: 1px solid #e2e8f0; border-radius: 14px; padding: 24px;
margin-bottom: 24px; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.02);
}
.cov-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.cov-pct { font-size: 24px; font-weight: 800; color: #1e3a8a; }
.cov-track { height: 12px; background: #e2e8f0; border-radius: 99px; overflow: hidden; }
.cov-fill { height: 100%; background: linear-gradient(90deg, #1e3a8a, #3b82f6); border-radius: 99px; }
.cov-meta { display: flex; gap: 20px; font-size: 12px; color: #475569; margin-top: 14px; flex-wrap: wrap; }
/* Grid Tabel */
.db-tables { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.dbt-card { background: #fff; border: 1px solid #e2e8f0; border-radius: 14px; overflow: hidden; }
.dbt-head { padding: 16px 20px; border-bottom: 1px solid #f1f5f9; display: flex; justify-content: space-between; align-items: center; background: #fafbfc; }
.dbt-head h3 { font-size: 13px; font-weight: 700; color: #0f172a; display: flex; align-items: center; gap: 8px; }
.dbt-head a { font-size: 12px; color: #1e3a8a; text-decoration: none; font-weight: 600; background: #f1f5f9; padding: 4px 10px; border-radius: 6px; }
table.dbt { width: 100%; border-collapse: collapse; font-size: 13px; }
table.dbt th { background: #f8fafc; padding: 12px 16px; text-align: left; font-size: 11px; font-weight: 700; color: #64748b; text-transform: uppercase; border-bottom: 1px solid #e2e8f0; }
table.dbt td { padding: 14px 16px; border-bottom: 1px solid #f1f5f9; color: #334155; }
.badge-modern { padding: 4px 10px; border-radius: 99px; font-size: 11px; font-weight: 600; display: inline-block; }
.badge-danger { background: #fee2e2; color: #dc2626; }
.badge-success { background: #d1fae5; color: #059669; }
@media (max-width: 992px) {
.stat-row { grid-template-columns: repeat(2, 1fr); }
.db-tables { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<div class="db-wrap">
<div class="db-welcome">
<h1>Selamat Datang di Panel Eksekutif Monitoring Pemerintah 🏛️</h1>
<p>Hak akses pejabat pemerintah aktif. Gunakan panel ini untuk meninjau status kemiskinan makro secara wilayah, mengawasi pergerakan distribusi bantuan logistik, dan mengukur efisiensi pos rumah ibadah.</p>
</div>
<div class="stat-row">
<div class="scard">
<div>
<div class="scard-label">Total Sasaran KPM</div>
<div class="scard-num"><?= $totalKpm ?></div>
<div class="scard-sub">Keluarga Terdaftar</div>
</div>
<div class="scard-icon" style="background: #e0e7ff; color: #4f46e5;"><i class="fa fa-users"></i></div>
</div>
<div class="scard">
<div>
<div class="scard-label">Pos Ibadah Aktif</div>
<div class="scard-num"><?= $totalIbadah ?></div>
<div class="scard-sub">Mitra Distribusi</div>
</div>
<div class="scard-icon" style="background: #e0f2fe; color: #0369a1;"><i class="fa fa-mosque"></i></div>
</div>
<div class="scard">
<div>
<div class="scard-label">Wilayah Blank Spot</div>
<div class="scard-num" style="color:#dc2626"><?= $blankSpot ?></div>
<div class="scard-sub">Belum Tersentuh</div>
</div>
<div class="scard-icon" style="background: #fee2e2; color: #dc2626;"><i class="fa fa-street-view"></i></div>
</div>
<div class="scard">
<div>
<div class="scard-label">Bencana Daerah</div>
<div class="scard-num" style="color:<?= $bencanaAktif > 0 ? '#dc2626' : '#0f172a' ?>"><?= $bencanaAktif ?></div>
<div class="scard-sub">Status Darurat Aktif</div>
</div>
<div class="scard-icon" style="background: #fff1f2; color: #e11d48;"><i class="fa fa-triangle-exclamation"></i></div>
</div>
</div>
<div class="coverage-box">
<div class="cov-top">
<div>
<h3 style="font-size: 14px; font-weight: 700;">Indeks Efektivitas Jangkauan Bantuan Daerah</h3>
<p style="font-size: 12px; color: #64748b; margin-top:2px;">Rasio keberhasilan penyerapan bantuan sosial yang dikoordinasikan melalui jajaran Rumah Ibadah.</p>
</div>
<div class="cov-pct"><?= $pct ?>%</div>
</div>
<div class="cov-track"><div class="cov-fill" style="width:<?= $pct ?>%"></div></div>
<div class="cov-meta">
<span>Terbantu: <strong><?= $terjangkau ?> KPM</strong></span>
<span>Blank Spot: <strong><?= $blankSpot ?> KPM</strong></span>
<span>Total Transaksi Bantuan: <strong><?= $totalBantuan ?> Kali</strong></span>
</div>
</div>
<div class="db-tables">
<div class="dbt-card">
<div class="dbt-head">
<h3><i class="fa fa-file-invoice"></i> Catatan Survei Rumah Warga (Melihat)</h3>
<a href="data-warga.php">Buka Halaman</a>
</div>
<table class="dbt">
<thead><tr><th>Kepala Keluarga</th><th>Kelurahan</th><th>Kondisi</th></tr></thead>
<tbody>
<?php while ($k = $kpmBaru->fetch_assoc()): ?>
<tr>
<td><strong><?= htmlspecialchars($k['nama_kepala_keluarga']) ?></strong><div style="font-size:11px;color:#94a3b8;">NIK: <?= $k['nik']?:'-' ?></div></td>
<td><?= htmlspecialchars($k['kelurahan'] ?: '-') ?></td>
<td><span class="badge-modern badge-danger"><?= $k['kondisi_rumah'] ?></span></td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
<div class="dbt-card">
<div class="dbt-head">
<h3><i class="fa fa-hand-holding-heart"></i> Alokasi Logistik Terakhir</h3>
<a href="bantuan.php">Kelola Logistik</a>
</div>
<table class="dbt">
<thead><tr><th>Penerima KPM</th><th>Paket Bantuan</th><th>Tanggal</th></tr></thead>
<tbody>
<?php while ($b = $bantuanBaru->fetch_assoc()): ?>
<tr>
<td><strong><?= htmlspecialchars($b['nama_kepala_keluarga'] ?? '-') ?></strong></td>
<td><span class="badge-modern badge-success"><?= htmlspecialchars($b['jenis_bantuan']) ?></span></td>
<td style="color:#64748b"><?= date('d M Y', strtotime($b['tanggal'])) ?></td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
</div>
</div>
</div> <?php include 'includes/footer.php'; ?>
</body>
</html>
+214
View File
@@ -0,0 +1,214 @@
<?php
// dashboard-pengurus.php
require_once 'koneksi.php';
cekLogin();
// Proteksi: Hanya Role Pengurus yang Boleh Mengakses Halaman Ini
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'pengurus') {
header('Location: login.php');
exit;
}
$page = 'beranda'; // Penanda agar menu "Beranda" di sidebar menyala biru
$pageTitle = 'Dashboard Pengurus';
// Mengambil Data Statistik untuk Pengurus Rumah Ibadah / Wilayah
$totalIbadah = $conn->query("SELECT COUNT(*) AS c FROM rumah_ibadah")->fetch_assoc()['c'] ?? 0;
$totalKpm = $conn->query("SELECT COUNT(*) AS c FROM rumah_miskin")->fetch_assoc()['c'] ?? 0;
$terjangkau = $conn->query("SELECT COUNT(*) AS c FROM rumah_miskin WHERE status_bantuan='Terjangkau'")->fetch_assoc()['c'] ?? 0;
$blankSpot = $conn->query("SELECT COUNT(*) AS c FROM rumah_miskin WHERE status_bantuan='Belum Terbantu'")->fetch_assoc()['c'] ?? 0;
$bencanaAktif = $conn->query("SELECT COUNT(*) AS c FROM bencana WHERE status='Aktif'")->fetch_assoc()['c'] ?? 0;
$pct = $totalKpm > 0 ? round($terjangkau / $totalKpm * 100) : 0;
// Log Aktivitas Pengurus Terupdate (Limit 5)
$kpmBaru = $conn->query("SELECT nama_kepala_keluarga, nik, kelurahan, kondisi_rumah FROM rumah_miskin ORDER BY created_at DESC LIMIT 5");
$bantuanBaru = $conn->query("SELECT bt.jenis_bantuan, bt.jumlah, bt.tanggal, rm.nama_kepala_keluarga FROM bantuan_tersalur bt LEFT JOIN rumah_miskin rm ON bt.warga_id=rm.id ORDER BY bt.created_at DESC LIMIT 5");
include 'includes/sidebar.php';
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Panel Pengurus Wilayah - Poverty Mapping</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"/>
<style>
.db-wrap { max-width: 1200px; font-family: 'Inter', sans-serif; }
/* Welcome Banner Pengurus (Gradasi Ungu - Fuchsia Modern & Dinamis) */
.db-welcome {
background: linear-gradient(135deg, #6d28d9 0%, #db2777 100%);
color: white; border-radius: 16px; padding: 26px 28px; margin-bottom: 24px;
box-shadow: 0 10px 25px -5px rgba(109, 40, 217, 0.2); position: relative; overflow: hidden;
}
.db-welcome h1 { font-size: 22px; font-weight: 700; margin-bottom: 6px; }
.db-welcome p { font-size: 13px; opacity: 0.9; max-width: 750px; line-height: 1.5; }
/* Quick Action */
.action-row { display: flex; gap: 12px; margin-bottom: 24px; flex-wrap: wrap; }
.btn-action {
display: inline-flex; align-items: center; gap: 8px; background: #ffffff; border: 1px solid #e2e8f0;
padding: 10px 18px; border-radius: 10px; font-size: 13px; font-weight: 600; color: #1e293b; text-decoration: none;
transition: all 0.2s; box-shadow: 0 2px 4px rgba(0,0,0,0.02);
}
.btn-action:hover { background: #f8fafc; border-color: #cbd5e1; transform: translateY(-1px); }
.btn-action i { color: #6d28d9; }
.btn-action.btn-maps i { color: #db2777; }
/* Grid Kartu */
.stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 24px; }
.scard {
background: #fff; border: 1px solid #e2e8f0; border-radius: 14px; padding: 20px;
display: flex; align-items: center; justify-content: space-between; box-shadow: 0 4px 6px -1px rgba(15,23,42,0.02);
}
.scard:hover { box-shadow: 0 12px 20px -5px rgba(15, 23, 42, 0.05); transform: translateY(-4px); }
.scard-label { font-size: 11px; font-weight: 700; color: #64748b; text-transform: uppercase; letter-spacing: .5px; margin-bottom: 6px; }
.scard-num { font-size: 26px; font-weight: 800; color: #0f172a; }
.scard-sub { font-size: 11px; color: #64748b; margin-top: 5px; }
.scard-icon { width: 44px; height: 44px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 16px; }
/* Progress Box */
.coverage-box {
background: #fff; border: 1px solid #e2e8f0; border-radius: 14px; padding: 24px;
margin-bottom: 24px; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.02);
}
.cov-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.cov-pct { font-size: 24px; font-weight: 800; color: #6d28d9; }
.cov-track { height: 12px; background: #e2e8f0; border-radius: 99px; overflow: hidden; }
.cov-fill { height: 100%; background: linear-gradient(90deg, #6d28d9, #db2777); border-radius: 99px; }
.cov-meta { display: flex; gap: 20px; font-size: 12px; color: #475569; margin-top: 14px; flex-wrap: wrap; }
/* Grid Tabel */
.db-tables { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.dbt-card { background: #fff; border: 1px solid #e2e8f0; border-radius: 14px; overflow: hidden; }
.dbt-head { padding: 16px 20px; border-bottom: 1px solid #f1f5f9; display: flex; justify-content: space-between; align-items: center; background: #fafbfc; }
.dbt-head h3 { font-size: 13px; font-weight: 700; color: #0f172a; display: flex; align-items: center; gap: 8px; }
.dbt-head a { font-size: 12px; color: #6d28d9; text-decoration: none; font-weight: 600; background: #f3e8ff; padding: 4px 10px; border-radius: 6px; }
table.dbt { width: 100%; border-collapse: collapse; font-size: 13px; }
table.dbt th { background: #f8fafc; padding: 12px 16px; text-align: left; font-size: 11px; font-weight: 700; color: #64748b; text-transform: uppercase; border-bottom: 1px solid #e2e8f0; }
table.dbt td { padding: 14px 16px; border-bottom: 1px solid #f1f5f9; color: #334155; }
.badge-modern { padding: 4px 10px; border-radius: 99px; font-size: 11px; font-weight: 600; display: inline-block; }
.badge-danger { background: #fee2e2; color: #dc2626; }
.badge-success { background: #d1fae5; color: #059669; }
@media (max-width: 992px) {
.stat-row { grid-template-columns: repeat(2, 1fr); }
.db-tables { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<div class="db-wrap">
<div class="db-welcome">
<h1>Selamat Bertugas, Rekan Pengurus Wilayah! 🌟</h1>
<p>Akses kontrol pos koordinasi terpadu aktif. Gunakan hak akses ini untuk melacak dan memvalidasi survei lapangan dari relawan, mengatur logistik log penyaluran bantuan, serta mengoptimalkan peta geospatial.</p>
</div>
<div class="action-row">
<a href="data-warga.php" class="btn-action"><i class="fa fa-folder-plus"></i> Manajemen Data KPM</a>
<a href="bantuan.php" class="btn-action"><i class="fa fa-hand-holding-heart"></i> Transaksi Saluran Bantuan</a>
<a href="peta.php" class="btn-action btn-maps"><i class="fa fa-map-location-dot"></i> Buka Peta Distribusi</a>
</div>
<div class="stat-row">
<div class="scard">
<div>
<div class="scard-label">Pos Rumah Ibadah</div>
<div class="scard-num"><?= $totalIbadah ?></div>
<div class="scard-sub">Titik Kemitraan</div>
</div>
<div class="scard-icon" style="background: #f3e8ff; color: #6d28d9;"><i class="fa fa-mosque"></i></div>
</div>
<div class="scard">
<div>
<div class="scard-label">KPM Terdata</div>
<div class="scard-num"><?= $totalKpm ?></div>
<div class="scard-sub">Hasil Survei Lapangan</div>
</div>
<div class="scard-icon" style="background: #fcf2e9; color: #ea580c;"><i class="fa fa-users"></i></div>
</div>
<div class="scard">
<div>
<div class="scard-label">Blank Spot</div>
<div class="scard-num" style="color:#dc2626"><?= $blankSpot ?></div>
<div class="scard-sub">Butuh Respons Cepat</div>
</div>
<div class="scard-icon" style="background: #fee2e2; color: #dc2626;"><i class="fa fa-street-view"></i></div>
</div>
<div class="scard">
<div>
<div class="scard-label">Posko Bencana</div>
<div class="scard-num" style="color:<?= $bencanaAktif > 0 ? '#dc2626' : '#0f172a' ?>"><?= $bencanaAktif ?></div>
<div class="scard-sub">Siaga Logistik</div>
</div>
<div class="scard-icon" style="background: #fff1f2; color: #e11d48;"><i class="fa fa-triangle-exclamation"></i></div>
</div>
</div>
<div class="coverage-box">
<div class="cov-top">
<div>
<h3>Rasio Pemenuhan Target Penyaluran Wilayah</h3>
<p>Presentase keluarga kurang mampu terdaftar yang telah menerima alokasi bantuan sosial secara berkala.</p>
</div>
<div class="cov-pct"><?= $pct ?>%</div>
</div>
<div class="cov-track"><div class="cov-fill" style="width:<?= $pct ?>%"></div></div>
<div class="cov-meta">
<span>Terdistribusi: <strong style="color:#6d28d9;"><?= $terjangkau ?> KPM</strong></span>
<span>Belum Kebagian: <strong style="color:#dc2626;"><?= $blankSpot ?> KPM</strong></span>
<span>Total Target Sasaran: <strong><?= $totalKpm ?> KPM</strong></span>
</div>
</div>
<div class="db-tables">
<div class="dbt-card">
<div class="dbt-head">
<h3><i class="fa fa-users-viewfinder"></i> Survei Relawan Terakhir</h3>
<a href="data-warga.php">Kelola Data</a>
</div>
<table class="dbt">
<thead><tr><th>Nama KK</th><th>Kelurahan</th><th>Kondisi Rumah</th></tr></thead>
<tbody>
<?php while ($k = $kpmBaru->fetch_assoc()): ?>
<tr>
<td><strong><?= htmlspecialchars($k['nama_kepala_keluarga']) ?></strong><div style="font-size:11px;color:#94a3b8;">NIK: <?= $k['nik']?:'-' ?></div></td>
<td><?= htmlspecialchars($k['kelurahan'] ?: '-') ?></td>
<td><span class="badge-modern badge-danger"><?= $k['kondisi_rumah'] ?></span></td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
<div class="dbt-card">
<div class="dbt-head">
<h3><i class="fa fa-clock-rotate-left"></i> Riwayat Penyaluran Wilayah</h3>
<a href="bantuan.php">Semua Log</a>
</div>
<table class="dbt">
<thead><tr><th>Penerima KPM</th><th>Jenis Paket</th><th>Tanggal</th></tr></thead>
<tbody>
<?php while ($b = $bantuanBaru->fetch_assoc()): ?>
<tr>
<td><strong><?= htmlspecialchars($b['nama_kepala_keluarga'] ?? '-') ?></strong></td>
<td><span class="badge-modern badge-success"><?= htmlspecialchars($b['jenis_bantuan']) ?></span></td>
<td style="color:#64748b"><?= date('d M Y', strtotime($b['tanggal'])) ?></td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
</div>
</div>
</div> <?php include 'includes/footer.php'; ?>
</body>
</html>
+35
View File
@@ -0,0 +1,35 @@
</div><!-- end page-body -->
</div><!-- end #main -->
<script>
// Toast utility
function toast(msg, type) {
var icons = { success:'✅', error:'❌', info:'️', warning:'⚠️' };
var el = document.createElement('div');
el.className = 'toast ' + (type||'');
el.innerHTML = '<span>' + (icons[type]||'️') + '</span> ' + msg;
document.getElementById('toast-wrap').appendChild(el);
setTimeout(() => { el.style.opacity='0'; el.style.transition='.3s'; setTimeout(()=>el.remove(),300); }, 3500);
}
// Modal helpers
function openModal(id) { document.getElementById(id).classList.add('show'); }
function closeModal(id) { document.getElementById(id).classList.remove('show'); }
// Close modal on overlay click
document.querySelectorAll('.modal-overlay').forEach(el => {
el.addEventListener('click', function(e) {
if (e.target === this) this.classList.remove('show');
});
});
<?php if (isset($_GET['success'])): ?>
toast('<?= htmlspecialchars($_GET['success']) ?>', 'success');
<?php endif; ?>
<?php if (isset($_GET['error'])): ?>
toast('<?= htmlspecialchars($_GET['error']) ?>', 'error');
<?php endif; ?>
</script>
<?= $extraScript ?? '' ?>
</body>
</html>
+318
View File
@@ -0,0 +1,318 @@
<?php
if (session_status() === PHP_SESSION_NONE) session_start();
$page = $page ?? '';
$current_role = $_SESSION['role'] ?? '';
$user_display_name = $_SESSION['nama'] ?? 'Pengguna';
$roleLabel = [
'admin' => 'Administrator',
'pemerintah' => 'Pemerintah',
'pengurus' => 'Operator Lembaga',
'relawan' => 'Relawan',
];
// Badge bencana aktif & konfirmasi menunggu
$bAktif = 0;
$menungguKonf = 0;
if (isset($conn)) {
$bAktif = $conn->query("SELECT COUNT(*) AS c FROM bencana WHERE status='Aktif'")->fetch_assoc()['c'] ?? 0;
if (in_array($current_role, ['pengurus','relawan'])) {
$menungguKonf = $conn->query("SELECT COUNT(*) AS c FROM bantuan_tersalur WHERE status_konfirmasi='Menunggu'")->fetch_assoc()['c'] ?? 0;
}
}
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= htmlspecialchars($pageTitle ?? 'WebGIS Poverty Mapping') ?></title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"/>
<style>
/* ── RESET ── */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
--blue:#3b82f6;--blue-dk:#1d4ed8;--blue-lt:#eff6ff;
--green:#16a34a;--green-lt:#f0fdf4;
--red:#dc2626;--red-lt:#fef2f2;
--orange:#ea580c;--orange-lt:#fff7ed;
--purple:#7c3aed;--purple-lt:#faf5ff;
--yellow:#d97706;--yellow-lt:#fffbeb;
--gray:#6b7280;--gray-lt:#f9fafb;--gray-md:#e5e7eb;
--dark:#111827;--white:#fff;
--sb-w:250px;
--radius:8px;--radius-sm:6px;--radius-lg:12px;
--font:'Inter',sans-serif;
}
/* ── BODY ── */
body{font-family:var(--font);background:#f3f4f6;color:var(--dark);display:flex;min-height:100vh}
/* ── SIDEBAR ── */
#sidebar{
width:var(--sb-w);min-height:100vh;background:#0f172a;
display:flex;flex-direction:column;
position:fixed;top:0;left:0;z-index:600;
}
.sb-brand{
padding:18px 16px 14px;
border-bottom:1px solid rgba(255,255,255,.06);
display:flex;align-items:center;gap:10px;
}
.sb-brand-ico{
width:30px;height:30px;background:var(--blue);border-radius:7px;
display:flex;align-items:center;justify-content:center;flex-shrink:0;
}
.sb-brand-ico i{color:#fff;font-size:13px}
.sb-brand strong{font-size:13px;font-weight:800;color:#fff;letter-spacing:-.2px}
.sb-brand span{font-size:10px;color:rgba(255,255,255,.3);display:block;margin-top:1px}
.sb-user{
padding:12px 14px;border-bottom:1px solid rgba(255,255,255,.06);
display:flex;align-items:center;gap:9px;
}
.sb-av{
width:30px;height:30px;border-radius:7px;flex-shrink:0;
display:flex;align-items:center;justify-content:center;
font-size:12px;font-weight:700;color:#fff;
background:linear-gradient(135deg,var(--blue),#8b5cf6);
}
.sb-user-info strong{font-size:12px;color:#fff;display:block;font-weight:600;line-height:1.3}
.sb-user-info span{
font-size:9px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;
color:#10b981;display:inline-flex;align-items:center;gap:4px;
background:rgba(16,185,129,.12);padding:1px 6px;border-radius:4px;margin-top:2px;
}
.sb-nav{flex:1;padding:8px;overflow-y:auto}
.sb-nav::-webkit-scrollbar{width:3px}
.sb-nav::-webkit-scrollbar-thumb{background:rgba(255,255,255,.06);border-radius:99px}
.sb-sec{
font-size:9px;font-weight:700;color:rgba(255,255,255,.2);
text-transform:uppercase;letter-spacing:.9px;
padding:10px 8px 4px;
}
.sb-a{
display:flex;align-items:center;gap:9px;padding:8px 10px;
color:rgba(255,255,255,.45);font-size:13px;font-weight:500;
text-decoration:none;border-radius:var(--radius-sm);
margin-bottom:1px;transition:.15s;position:relative;
}
.sb-a i{width:14px;text-align:center;font-size:13px;color:rgba(255,255,255,.2);transition:.15s;flex-shrink:0}
.sb-a:hover{background:rgba(255,255,255,.05);color:#fff}
.sb-a:hover i{color:rgba(255,255,255,.6)}
.sb-a.on{background:rgba(59,130,246,.18);color:var(--blue);font-weight:600}
.sb-a.on i{color:var(--blue)}
.sb-a.on::before{content:'';position:absolute;left:0;top:20%;height:60%;width:3px;background:var(--blue);border-radius:0 3px 3px 0}
.sb-badge{margin-left:auto;background:var(--red);color:#fff;font-size:9px;font-weight:700;padding:1px 5px;border-radius:99px}
.sb-foot{padding:10px 8px;border-top:1px solid rgba(255,255,255,.06)}
.sb-out{
display:flex;align-items:center;gap:9px;padding:8px 10px;
color:#f87171;font-size:12px;font-weight:600;text-decoration:none;
border-radius:var(--radius-sm);transition:.15s;
}
.sb-out i{font-size:12px}
.sb-out:hover{background:rgba(239,68,68,.12);color:#ef4444}
/* ── MAIN WRAPPER ── */
#main-wrap{
margin-left:var(--sb-w);
flex:1;display:flex;flex-direction:column;min-height:100vh;
/* penting: tidak overflow tersembunyi, biarkan konten mengisi */
}
/* ── TOPBAR ── */
#topbar{
background:#fff;border-bottom:1px solid var(--gray-md);
height:50px;padding:0 22px;
display:flex;align-items:center;gap:12px;
position:sticky;top:0;z-index:500;
}
.tb-title{font-size:14px;font-weight:700;color:var(--dark);flex:1}
.tb-title span{font-size:12px;font-weight:400;color:var(--gray);margin-left:6px}
.tb-right{display:flex;align-items:center;gap:10px}
.tb-date{font-size:12px;color:var(--gray)}
.tb-role{font-size:11px;font-weight:600;color:#fff;padding:3px 10px;border-radius:5px;background:var(--blue)}
/* ── PAGE ── */
.page-wrap{padding:20px 22px;flex:1}
.page-head{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:18px}
.page-head h2{font-size:18px;font-weight:800}
.page-head p{font-size:13px;color:var(--gray);margin-top:3px}
/* ── CARD ── */
.card{background:#fff;border-radius:var(--radius);border:1px solid var(--gray-md)}
.card-hd{padding:13px 16px;border-bottom:1px solid var(--gray-md);display:flex;align-items:center;justify-content:space-between}
.card-hd h3{font-size:13px;font-weight:700}
.card-bd{padding:16px}
/* ── STAT GRID ── */
.sg{display:grid;gap:12px;margin-bottom:16px}
.sg4{grid-template-columns:repeat(4,1fr)}
.sg3{grid-template-columns:repeat(3,1fr)}
.sg2{grid-template-columns:repeat(2,1fr)}
.sbox{background:#fff;border-radius:var(--radius);padding:16px;border:1px solid var(--gray-md);display:flex;align-items:center;gap:12px}
.sico{width:38px;height:38px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:15px;flex-shrink:0}
.snum{font-size:22px;font-weight:800;line-height:1}
.slbl{font-size:11px;color:var(--gray);font-weight:500;margin-top:2px}
/* ── TABLE ── */
.tbl-w{overflow-x:auto}
table{width:100%;border-collapse:collapse;font-size:13px}
thead th{background:var(--gray-lt);padding:8px 13px;font-weight:700;color:var(--gray);font-size:10px;text-transform:uppercase;letter-spacing:.5px;text-align:left;border-bottom:1px solid var(--gray-md)}
tbody td{padding:10px 13px;border-bottom:1px solid #f9fafb;color:var(--dark);vertical-align:middle}
tbody tr:last-child td{border-bottom:none}
tbody tr:hover{background:#fafafa}
/* ── BADGE ── */
.badge{display:inline-flex;align-items:center;font-size:10px;font-weight:600;padding:2px 7px;border-radius:4px}
.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-orange{background:var(--orange-lt);color:var(--orange)}
.badge-purple{background:var(--purple-lt);color:var(--purple)}
.badge-yellow{background:var(--yellow-lt);color:var(--yellow)}
.badge-gray{background:var(--gray-lt);color:var(--gray)}
/* ── BTN ── */
.btn{display:inline-flex;align-items:center;gap:5px;padding:7px 14px;font-family:var(--font);font-size:13px;font-weight:600;border:none;border-radius:var(--radius-sm);cursor:pointer;text-decoration:none;transition:.15s}
.btn:hover{opacity:.88}
.btn-sm{padding:5px 10px;font-size:12px}
.btn-primary{background:var(--blue);color:#fff}
.btn-success{background:var(--green);color:#fff}
.btn-danger{background:var(--red);color:#fff}
.btn-warning{background:var(--orange);color:#fff}
.btn-purple{background:var(--purple);color:#fff}
.btn-ghost{background:var(--gray-lt);color:var(--dark);border:1px solid var(--gray-md)}
.btn-ghost:hover{background:var(--gray-md)}
/* ── FORM ── */
.fg{margin-bottom:13px}
.fg label{display:block;font-size:11px;font-weight:600;color:var(--gray);text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px}
.fc{width:100%;padding:8px 10px;border:1px solid var(--gray-md);border-radius:var(--radius-sm);font-family:var(--font);font-size:13px;color:var(--dark);transition:.15s;background:#fff}
.fc:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(59,130,246,.08)}
.form-control{width:100%;padding:8px 10px;border:1px solid var(--gray-md);border-radius:var(--radius-sm);font-family:var(--font);font-size:13px;color:var(--dark);transition:.15s;background:#fff}
.form-control:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(59,130,246,.08)}
.form-group{margin-bottom:13px}
.form-group label{display:block;font-size:11px;font-weight:600;color:var(--gray);text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px}
.form-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.form-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px}
/* ── MODAL ── */
.modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:9000;display:none;align-items:center;justify-content:center}
.modal-overlay.show{display:flex}
.modal-box{background:#fff;border-radius:var(--radius-lg);width:90%;max-width:540px;max-height:90vh;overflow-y:auto;box-shadow:0 16px 48px rgba(0,0,0,.15)}
.modal-head{padding:15px 18px;border-bottom:1px solid var(--gray-md);display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;background:#fff;z-index:10}
.modal-head h3{font-size:14px;font-weight:700}
.modal-body{padding:18px}
.modal-foot{padding:12px 18px;border-top:1px solid var(--gray-md);display:flex;justify-content:flex-end;gap:8px}
.btn-close{background:none;border:none;font-size:15px;cursor:pointer;color:var(--gray);width:26px;height:26px;border-radius:5px;display:flex;align-items:center;justify-content:center}
.btn-close:hover{background:var(--gray-lt)}
/* ── TOAST ── */
#toast-wrap{position:fixed;top:13px;right:13px;z-index:99999;display:flex;flex-direction:column;gap:7px}
.toast{background:#fff;border-radius:var(--radius-sm);padding:10px 13px;box-shadow:0 4px 16px rgba(0,0,0,.12);font-size:13px;font-weight:600;display:flex;align-items:center;gap:8px;min-width:200px;border-left:3px solid var(--blue);animation:tIn .2s ease}
.toast.success{border-left-color:var(--green)}.toast.error{border-left-color:var(--red)}
@keyframes tIn{from{transform:translateX(28px);opacity:0}to{transform:none;opacity:1}}
.divider{border:none;border-top:1px solid var(--gray-md);margin:14px 0}
@media(max-width:768px){
#sidebar{transform:translateX(-100%)}
#main-wrap{margin-left:0}
.sg4,.sg3{grid-template-columns:repeat(2,1fr)}
.form-grid-2,.form-grid-3{grid-template-columns:1fr}
}
</style>
<?= $extraHead ?? '' ?>
</head>
<body>
<div id="toast-wrap"></div>
<!-- SIDEBAR -->
<nav id="sidebar">
<div class="sb-brand">
<div class="sb-brand-ico"><i class="fa fa-map-location-dot"></i></div>
<div>
<strong>Poverty Mapping</strong>
<span>WebGIS v2.0</span>
</div>
</div>
<div class="sb-user">
<div class="sb-av"><?= strtoupper(substr($user_display_name,0,1)) ?></div>
<div class="sb-user-info">
<strong><?= htmlspecialchars($user_display_name) ?></strong>
<span><i class="fa fa-circle" style="font-size:6px"></i> <?= $roleLabel[$current_role] ?? $current_role ?></span>
</div>
</div>
<div class="sb-nav">
<?php if ($current_role === 'admin'): ?>
<div class="sb-sec">Utama</div>
<a href="index.php" class="sb-a <?= $page==='beranda'?'on':'' ?>"><i class="fa fa-house"></i> Beranda</a>
<div class="sb-sec">Laporan</div>
<a href="laporan.php" class="sb-a <?= $page==='laporan'?'on':'' ?>"><i class="fa fa-chart-bar"></i> Laporan & Statistik</a>
<div class="sb-sec">Administrasi</div>
<a href="manajemen-user.php" class="sb-a <?= $page==='users'?'on':'' ?>"><i class="fa fa-user-gear"></i> Manajemen User</a>
<?php elseif ($current_role === 'pemerintah'): ?>
<div class="sb-sec">Utama</div>
<a href="index.php" class="sb-a <?= $page==='beranda'?'on':'' ?>"><i class="fa fa-house"></i> Beranda</a>
<a href="peta.php" class="sb-a <?= $page==='peta'?'on':'' ?>"><i class="fa fa-map"></i> Peta Interaktif</a>
<div class="sb-sec">Data</div>
<a href="data-ibadah.php" class="sb-a <?= $page==='ibadah'?'on':'' ?>"><i class="fa fa-mosque"></i> Rumah Ibadah</a>
<a href="data-warga.php" class="sb-a <?= $page==='warga'?'on':'' ?>"><i class="fa fa-users"></i> Data KPM</a>
<div class="sb-sec">Program</div>
<a href="bencana.php" class="sb-a <?= $page==='bencana'?'on':'' ?>">
<i class="fa fa-triangle-exclamation"></i> Bencana & Prioritas
<?php if ($bAktif > 0) echo "<span class='sb-badge'>$bAktif</span>"; ?>
</a>
<a href="bantuan.php" class="sb-a <?= $page==='bantuan'?'on':'' ?>"><i class="fa fa-hand-holding-heart"></i> Bantuan Tersalur</a>
<div class="sb-sec">Analisis</div>
<a href="laporan.php" class="sb-a <?= $page==='laporan'?'on':'' ?>"><i class="fa fa-chart-bar"></i> Laporan & Statistik</a>
<?php elseif (in_array($current_role, ['pengurus','relawan'])): ?>
<div class="sb-sec">Utama</div>
<a href="index.php" class="sb-a <?= $page==='beranda'?'on':'' ?>"><i class="fa fa-house"></i> Beranda</a>
<a href="peta.php" class="sb-a <?= $page==='peta'?'on':'' ?>"><i class="fa fa-map"></i> Peta Interaktif</a>
<div class="sb-sec">Data</div>
<a href="data-warga.php" class="sb-a <?= $page==='warga'?'on':'' ?>"><i class="fa fa-users"></i> Data KPM</a>
<a href="data-ibadah.php" class="sb-a <?= $page==='ibadah'?'on':'' ?>"><i class="fa fa-mosque"></i> Rumah Ibadah</a>
<div class="sb-sec">Program</div>
<a href="bencana.php" class="sb-a <?= $page==='bencana'?'on':'' ?>">
<i class="fa fa-triangle-exclamation"></i> Bencana & Prioritas
<?php if ($bAktif > 0) echo "<span class='sb-badge'>$bAktif</span>"; ?>
</a>
<a href="konfirmasi-bantuan.php" class="sb-a <?= $page==='konfirmasi'?'on':'' ?>">
<i class="fa fa-clipboard-check"></i> Konfirmasi Bantuan
<?php if ($menungguKonf > 0) echo "<span class='sb-badge'>$menungguKonf</span>"; ?>
</a>
<div class="sb-sec">Analisis</div>
<a href="laporan.php" class="sb-a <?= $page==='laporan'?'on':'' ?>"><i class="fa fa-chart-bar"></i> Laporan</a>
<?php endif; ?>
</div>
<div class="sb-foot">
<a href="logout.php" class="sb-out"><i class="fa fa-right-from-bracket"></i> Keluar</a>
</div>
</nav>
<!-- MAIN -->
<div id="main-wrap">
<div id="topbar">
<div class="tb-title">
<?= htmlspecialchars($pageTitle ?? 'Dashboard') ?>
<span><?= htmlspecialchars($pageSubtitle ?? '') ?></span>
</div>
<div class="tb-right">
<span class="tb-date"><?= date('d M Y') ?></span>
<div class="tb-role"><?= $roleLabel[$current_role] ?? $current_role ?></div>
</div>
</div>
<div class="page-wrap">