Upload files to "/"
This commit is contained in:
+248
@@ -0,0 +1,248 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'koneksi.php';
|
||||||
|
cekLogin();
|
||||||
|
|
||||||
|
// Hanya pemerintah & admin yang bisa input bantuan
|
||||||
|
// Operator/relawan diarahkan ke konfirmasi-bantuan.php
|
||||||
|
if (in_array($role ?? $_SESSION['role'], ['pengurus','relawan'])) {
|
||||||
|
header('Location: konfirmasi-bantuan.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$page = 'bantuan';
|
||||||
|
$pageTitle = 'Bantuan Tersalur';
|
||||||
|
$pageSubtitle = 'Input & Rekap Penyaluran';
|
||||||
|
|
||||||
|
$cari = bersih($_GET['cari'] ?? '', $conn);
|
||||||
|
$filterJenis = bersih($_GET['jenis'] ?? '', $conn);
|
||||||
|
$where = "WHERE 1=1";
|
||||||
|
if ($cari) $where .= " AND (rm.nama_kepala_keluarga LIKE '%$cari%' OR bt.jenis_bantuan LIKE '%$cari%')";
|
||||||
|
if ($filterJenis) $where .= " AND bt.jenis_bantuan LIKE '%$filterJenis%'";
|
||||||
|
|
||||||
|
$data = $conn->query("
|
||||||
|
SELECT bt.*, rm.nama_kepala_keluarga, rm.kelurahan,
|
||||||
|
ri.nama_ibadah, b.nama_bencana, u.nama_lengkap AS petugas_user
|
||||||
|
FROM bantuan_tersalur bt
|
||||||
|
LEFT JOIN rumah_miskin rm ON bt.warga_id = rm.id
|
||||||
|
LEFT JOIN rumah_ibadah ri ON bt.ibadah_id = ri.id
|
||||||
|
LEFT JOIN bencana b ON bt.bencana_id = b.id
|
||||||
|
LEFT JOIN users u ON bt.disalurkan_oleh = u.id
|
||||||
|
$where
|
||||||
|
ORDER BY bt.created_at DESC
|
||||||
|
");
|
||||||
|
$total = $data->num_rows;
|
||||||
|
|
||||||
|
// Untuk dropdown pilih warga
|
||||||
|
$semuaKpm = $conn->query("SELECT id, nama_kepala_keluarga, kelurahan FROM rumah_miskin ORDER BY nama_kepala_keluarga ASC");
|
||||||
|
|
||||||
|
include 'includes/sidebar.php';
|
||||||
|
?>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.custom-header-wrapper {
|
||||||
|
display: flex !important;
|
||||||
|
justify-content: space-between !important;
|
||||||
|
align-items: center !important;
|
||||||
|
margin-bottom: 25px !important;
|
||||||
|
background: #ffffff !important;
|
||||||
|
padding: 20px 24px !important;
|
||||||
|
border-radius: 12px !important;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.05) !important;
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.custom-header-wrapper {
|
||||||
|
flex-direction: column !important;
|
||||||
|
align-items: flex-start !important;
|
||||||
|
gap: 15px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="custom-header-wrapper">
|
||||||
|
<div>
|
||||||
|
<h2 style="margin: 0; font-size: 24px; color: #1e293b; font-weight: 700; display: flex; align-items: center; gap: 10px;">
|
||||||
|
<span>🎁</span> Bantuan Tersalur
|
||||||
|
</h2>
|
||||||
|
<p style="margin: 4px 0 0 0; color: #64748b; font-size: 14px;">
|
||||||
|
Total <?= $total ?> transaksi logistik & bantuan sosial tercatat
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-success" onclick="openModal('modalTambah')" style="display: flex; align-items: center; gap: 8px; padding: 10px 18px; font-weight: 600; border-radius: 8px; cursor: pointer;">
|
||||||
|
<i class="fa fa-plus"></i> Input Bantuan Baru
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="background:var(--blue-lt);border:1px solid #93c5fd;border-radius:var(--radius);padding:11px 16px;margin-bottom:18px;font-size:13px;color:var(--blue)">
|
||||||
|
<i class="fa fa-info-circle"></i>
|
||||||
|
Bantuan yang diinput di sini akan otomatis diteruskan ke halaman <strong>Konfirmasi Bantuan</strong> pada akun Relawan / Pengurus untuk diverifikasi penerimaannya di lapangan.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card" style="margin-bottom:16px">
|
||||||
|
<div style="padding:14px 18px">
|
||||||
|
<form method="GET" style="display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap">
|
||||||
|
<div style="flex:2;min-width:180px">
|
||||||
|
<label style="font-size:11px;font-weight:600;color:var(--gray);display:block;margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px">Cari</label>
|
||||||
|
<input class="form-control" name="cari" value="<?= htmlspecialchars($cari) ?>" placeholder="Nama penerima atau jenis bantuan...">
|
||||||
|
</div>
|
||||||
|
<div style="flex:1;min-width:130px">
|
||||||
|
<label style="font-size:11px;font-weight:600;color:var(--gray);display:block;margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px">Jenis</label>
|
||||||
|
<input class="form-control" name="jenis" value="<?= htmlspecialchars($filterJenis) ?>" placeholder="Sembako, BPNT...">
|
||||||
|
</div>
|
||||||
|
<div style="display:flex;gap:6px">
|
||||||
|
<button type="submit" class="btn btn-primary">Filter</button>
|
||||||
|
<a href="bantuan.php" class="btn btn-ghost"><i class="fa fa-rotate-left"></i></a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3>Riwayat Distribusi Bantuan</h3>
|
||||||
|
<span class="badge badge-gray"><?= $total ?> data</span>
|
||||||
|
</div>
|
||||||
|
<div class="tbl-wrap">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th>Penerima</th>
|
||||||
|
<th>Jenis Bantuan</th>
|
||||||
|
<th>Jumlah</th>
|
||||||
|
<th>Tanggal</th>
|
||||||
|
<th>Petugas Lapangan</th>
|
||||||
|
<th>Status Konfirmasi</th>
|
||||||
|
<th>Aksi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if ($total === 0): ?>
|
||||||
|
<tr><td colspan="8" style="text-align:center;padding:36px;color:var(--gray)">Belum ada data bantuan</td></tr>
|
||||||
|
<?php else: $no=1; while ($r = $data->fetch_assoc()):
|
||||||
|
$konfStatus = $r['status_konfirmasi'] ?? 'Menunggu';
|
||||||
|
$konfBadge = ['Menunggu'=>'badge-yellow','Dikonfirmasi'=>'badge-green','Ditolak'=>'badge-red'][$konfStatus] ?? 'badge-gray';
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td style="color:var(--gray);font-size:12px"><?= $no++ ?></td>
|
||||||
|
<td>
|
||||||
|
<div style="font-weight:600"><?= htmlspecialchars($r['nama_kepala_keluarga'] ?? '-') ?></div>
|
||||||
|
<div style="font-size:11px;color:var(--gray)"><?= htmlspecialchars($r['kelurahan'] ?? '') ?></div>
|
||||||
|
<?php if ($r['nama_bencana']): ?>
|
||||||
|
<span class="badge badge-red" style="font-size:9px;margin-top:2px"><?= htmlspecialchars($r['nama_bencana']) ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
|
<td><span class="badge badge-blue"><?= htmlspecialchars($r['jenis_bantuan']) ?></span></td>
|
||||||
|
<td style="font-weight:600;font-size:13px"><?= htmlspecialchars($r['jumlah'] ?? '-') ?></td>
|
||||||
|
<td style="font-size:12px;color:var(--gray)"><?= date('d M Y', strtotime($r['tanggal'])) ?></td>
|
||||||
|
<td style="font-size:12px"><?= htmlspecialchars($r['petugas'] ?? $r['petugas_user'] ?? '-') ?></td>
|
||||||
|
<td><span class="badge <?= $konfBadge ?>"><?= $konfStatus ?></span></td>
|
||||||
|
<td>
|
||||||
|
<?php if ($_SESSION['role'] === 'admin'): ?>
|
||||||
|
<button class="btn btn-ghost btn-sm" onclick="hapusBantuan(<?= $r['id'] ?>)" style="color:var(--red)" title="Hapus Riwayat">
|
||||||
|
<i class="fa fa-trash" style="font-size:11px"></i>
|
||||||
|
</button>
|
||||||
|
<?php else: ?>
|
||||||
|
<span style="font-size:11px; color:#94a3b8">-</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endwhile; endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-overlay" id="modalTambah">
|
||||||
|
<div class="modal-box">
|
||||||
|
<div class="modal-head">
|
||||||
|
<h3><i class="fa fa-hand-holding-heart" style="color:#16a34a"></i> Catat Penyaluran Bantuan</h3>
|
||||||
|
<button class="btn-close" onclick="closeModal('modalTambah')">✕</button>
|
||||||
|
</div>
|
||||||
|
<form method="POST" action="proses.php">
|
||||||
|
<input type="hidden" name="aksi" value="simpan_bantuan">
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Nama Penerima (KPM) *</label>
|
||||||
|
<select class="form-control" name="warga_id" required>
|
||||||
|
<option value="">-- Pilih KPM --</option>
|
||||||
|
<?php $semuaKpm->data_seek(0); while ($k = $semuaKpm->fetch_assoc()): ?>
|
||||||
|
<option value="<?= $k['id'] ?>">
|
||||||
|
<?= htmlspecialchars($k['nama_kepala_keluarga']) ?>
|
||||||
|
<?= $k['kelurahan'] ? '('.$k['kelurahan'].')' : '' ?>
|
||||||
|
</option>
|
||||||
|
<?php endwhile; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Jenis Bantuan *</label>
|
||||||
|
<input class="form-control" name="jenis_bantuan" required placeholder="cth: Sembako, BPNT, Zakat Mal...">
|
||||||
|
</div>
|
||||||
|
<div class="form-grid-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Jumlah / Nominal</label>
|
||||||
|
<input class="form-control" name="jumlah" placeholder="cth: 50kg beras / Rp500.000">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Tanggal Penyaluran *</label>
|
||||||
|
<input class="form-control" type="date" name="tanggal" required value="<?= date('Y-m-d') ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Nama Petugas</label>
|
||||||
|
<input class="form-control" name="petugas" placeholder="Nama petugas / instansi penyalur">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Keterangan Tambahan</label>
|
||||||
|
<textarea class="form-control" name="keterangan" rows="2" placeholder="Catatan opsional..."></textarea>
|
||||||
|
</div>
|
||||||
|
<div style="background:#f0fdf4;border:1px solid #86efac;border-radius:var(--radius-sm);padding:9px 12px;font-size:12px;color:var(--green)">
|
||||||
|
Setelah disimpan, operator atau relawan di lapangan dapat melihat riwayat dan memvalidasi distribusi item fisik ini.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-foot">
|
||||||
|
<button type="button" class="btn btn-ghost" onclick="closeModal('modalTambah')">Batal</button>
|
||||||
|
<button type="submit" class="btn btn-success"><i class="fa fa-save"></i> Simpan Bantuan</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function openModal(id) {
|
||||||
|
const modal = document.getElementById(id);
|
||||||
|
if(modal) modal.style.display = 'flex';
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeModal(id) {
|
||||||
|
const modal = document.getElementById(id);
|
||||||
|
if(modal) modal.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fungsi tombol hapus bantuan khusus administrator
|
||||||
|
function hapusBantuan(id) {
|
||||||
|
if (confirm('Apakah Anda yakin ingin menghapus data rekam jejak penyaluran bantuan ini?')) {
|
||||||
|
// Membuat form virtual di memori browser
|
||||||
|
const form = document.createElement('form');
|
||||||
|
form.method = 'POST';
|
||||||
|
form.action = 'proses.php';
|
||||||
|
|
||||||
|
form.innerHTML = `
|
||||||
|
<input type="hidden" name="aksi" value="hapus_bantuan">
|
||||||
|
<input type="hidden" name="id" value="${id}">
|
||||||
|
`;
|
||||||
|
document.body.appendChild(form);
|
||||||
|
form.submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Menutup modal otomatis jika area luar modal diklik
|
||||||
|
window.onclick = function(event) {
|
||||||
|
if (event.target.classList.contains('modal-overlay')) {
|
||||||
|
closeModal(event.target.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
include 'includes/footer.php';
|
||||||
|
?>
|
||||||
+516
@@ -0,0 +1,516 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'koneksi.php';
|
||||||
|
cekLogin();
|
||||||
|
|
||||||
|
$page = 'bencana';
|
||||||
|
$pageTitle = 'Bencana & Prioritas';
|
||||||
|
$pageSubtitle = 'Manajemen Tanggap Darurat';
|
||||||
|
|
||||||
|
// --- HANDLER AJAX UNTUK KELOLA TERDAMPAK (REAL-TIME) ---
|
||||||
|
if (isset($_GET['ajax_aksi'])) {
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
// 1. Ambil daftar warga terdampak berdasarkan bencana_id
|
||||||
|
if ($_GET['ajax_aksi'] === 'ambil_terdampak') {
|
||||||
|
$bid = intval($_GET['bencana_id']);
|
||||||
|
$q = $conn->query("SELECT bd.*, rm.nama_kepala_keluarga, rm.kelurahan
|
||||||
|
FROM bencana_terdampak bd
|
||||||
|
JOIN rumah_miskin rm ON bd.warga_id = rm.id
|
||||||
|
WHERE bd.bencana_id = $bid
|
||||||
|
ORDER BY bd.id DESC");
|
||||||
|
$list = [];
|
||||||
|
while ($r = $q->fetch_assoc()) {
|
||||||
|
$list[] = $r;
|
||||||
|
}
|
||||||
|
echo json_encode(['status' => 'sukses', 'data' => $list]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Tambah warga terdampak (Tandai & Prioritaskan)
|
||||||
|
if ($_GET['ajax_aksi'] === 'tambah_terdampak' && $_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$bid = intval($_POST['bencana_id']);
|
||||||
|
$wid = intval($_POST['warga_id']);
|
||||||
|
$tingkat = bersih($_POST['tingkat'], $conn);
|
||||||
|
$ket = bersih($_POST['keterangan'], $conn);
|
||||||
|
|
||||||
|
// Cek apakah warga sudah ditandai di bencana ini sebelumnya
|
||||||
|
$cek = $conn->query("SELECT id FROM bencana_terdampak WHERE bencana_id = $bid AND warga_id = $wid");
|
||||||
|
if ($cek->num_rows > 0) {
|
||||||
|
echo json_encode(['status' => 'gagal', 'pesan' => 'Warga ini sudah ditandai terdampak dalam bencana ini!']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert ke bencana_terdampak
|
||||||
|
$insert = $conn->query("INSERT INTO bencana_terdampak (bencana_id, warga_id, tingkat, keterangan) VALUES ($bid, $wid, '$tingkat', '$ket')");
|
||||||
|
if ($insert) {
|
||||||
|
// Update status prioritas warga menjadi 1 (Prioritas Bencana) di tabel rumah_miskin
|
||||||
|
$conn->query("UPDATE rumah_miskin SET prioritas = 1, updated_at = NOW() WHERE id = $wid");
|
||||||
|
echo json_encode(['status' => 'sukses']);
|
||||||
|
} else {
|
||||||
|
echo json_encode(['status' => 'gagal', 'pesan' => 'Gagal menyimpan data ke database.']);
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Hapus warga terdampak (Batalkan Prioritas)
|
||||||
|
if ($_GET['ajax_aksi'] === 'hapus_terdampak' && $_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$bd_id = intval($_POST['id']);
|
||||||
|
|
||||||
|
// Ambil warga_id terlebih dahulu sebelum dihapus untuk keperluan update prioritas
|
||||||
|
$data_bd = $conn->query("SELECT warga_id FROM bencana_terdampak WHERE id = $bd_id")->fetch_assoc();
|
||||||
|
|
||||||
|
if ($data_bd) {
|
||||||
|
$wid = $data_bd['warga_id'];
|
||||||
|
// Hapus dari riwayat terdampak bencana
|
||||||
|
$delete = $conn->query("DELETE FROM bencana_terdampak WHERE id = $bd_id");
|
||||||
|
if ($delete) {
|
||||||
|
// Cek apakah warga ini masih terlibat di bencana aktif lainnya
|
||||||
|
$cek_lain = $conn->query("SELECT bd.id FROM bencana_terdampak bd
|
||||||
|
JOIN bencana b ON bd.bencana_id = b.id
|
||||||
|
WHERE bd.warga_id = $wid AND b.status = 'Aktif'");
|
||||||
|
if ($cek_lain->num_rows === 0) {
|
||||||
|
// Jika tidak ada bencana aktif lain, kembalikan status prioritasnya ke 0
|
||||||
|
$conn->query("UPDATE rumah_miskin SET prioritas = 0, updated_at = NOW() WHERE id = $wid");
|
||||||
|
}
|
||||||
|
echo json_encode(['status' => 'sukses']);
|
||||||
|
} else {
|
||||||
|
echo json_encode(['status' => 'gagal', 'pesan' => 'Gagal menghapus data terdampak.']);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo json_encode(['status' => 'gagal', 'pesan' => 'Data tidak ditemukan.']);
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query data utama halaman
|
||||||
|
$bencanaList = $conn->query("SELECT b.*, u.nama_lengkap AS petugas, COUNT(bd.id) AS jml_terdampak FROM bencana b LEFT JOIN users u ON b.dibuat_oleh=u.id LEFT JOIN bencana_terdampak bd ON b.id=bd.bencana_id GROUP BY b.id ORDER BY b.status ASC, b.tanggal DESC");
|
||||||
|
$semuaKpm = $conn->query("SELECT id, nama_kepala_keluarga, kelurahan, kondisi_rumah FROM rumah_miskin ORDER BY nama_kepala_keluarga ASC");
|
||||||
|
|
||||||
|
include 'includes/sidebar.php';
|
||||||
|
?>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.custom-header-wrapper {
|
||||||
|
display: flex !important;
|
||||||
|
justify-content: space-between !important;
|
||||||
|
align-items: center !important;
|
||||||
|
margin-bottom: 25px !important;
|
||||||
|
background: #ffffff !important;
|
||||||
|
padding: 20px 24px !important;
|
||||||
|
border-radius: 12px !important;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.05) !important;
|
||||||
|
}
|
||||||
|
.list-terdampak-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px 12px;
|
||||||
|
background: #f8fafc;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.list-terdampak-item:hover {
|
||||||
|
background: #f1f5f9;
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.custom-header-wrapper {
|
||||||
|
flex-direction: column !important;
|
||||||
|
align-items: flex-start !important;
|
||||||
|
gap: 15px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="custom-header-wrapper">
|
||||||
|
<div>
|
||||||
|
<h2 style="margin: 0; font-size: 24px; color: #1e293b; font-weight: 700; display: flex; align-items: center; gap: 10px;">
|
||||||
|
<span>🌋</span> Bencana & Prioritas Warga
|
||||||
|
</h2>
|
||||||
|
<p style="margin: 4px 0 0 0; color: #64748b; font-size: 14px;">
|
||||||
|
Catat kejadian bencana dan tandai warga terdampak sebagai prioritas bantuan
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<?php if (in_array($_SESSION['role'],['admin','pemerintah'])): ?>
|
||||||
|
<button class="btn btn-danger" onclick="openModal('modalTambahBencana')" style="display: flex; align-items: center; gap: 8px; padding: 10px 18px; font-weight: 600; border-radius: 8px; cursor: pointer;">
|
||||||
|
<i class="fa fa-plus"></i> Catat Bencana Baru
|
||||||
|
</button>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$aktif = $conn->query("SELECT b.*, COUNT(bd.id) AS jml FROM bencana b LEFT JOIN bencana_terdampak bd ON b.id=bd.bencana_id WHERE b.status='Aktif' GROUP BY b.id");
|
||||||
|
if ($aktif->num_rows > 0): ?>
|
||||||
|
<div style="background:linear-gradient(135deg,#dc2626,#b91c1c);border-radius:14px;padding:20px 24px;margin-bottom:20px;color:white">
|
||||||
|
<div style="font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:1px;opacity:.8;margin-bottom:8px">⚠️ Bencana Aktif Saat Ini</div>
|
||||||
|
<div style="display:flex;gap:16px;flex-wrap:wrap">
|
||||||
|
<?php while ($b = $aktif->fetch_assoc()): ?>
|
||||||
|
<div style="background:rgba(255,255,255,.15);border-radius:10px;padding:14px 18px;flex:1;min-width:200px">
|
||||||
|
<div style="font-size:16px;font-weight:800"><?= htmlspecialchars($b['nama_bencana']) ?></div>
|
||||||
|
<div style="font-size:12px;opacity:.8;margin-top:2px"><?= $b['jenis'] ?> · <?= date('d M Y',strtotime($b['tanggal'])) ?></div>
|
||||||
|
<div style="margin-top:8px;font-size:13px;font-weight:700"><?= $b['jml'] ?> warga terdampak</div>
|
||||||
|
<button class="btn btn-sm" style="background:rgba(255,255,255,.25);color:white;margin-top:10px;border:none;cursor:pointer" onclick="bukaKelolaTerdampak(<?= $b['id'] ?>, '<?= htmlspecialchars($b['nama_bencana'], ENT_QUOTES) ?>')">
|
||||||
|
<i class="fa fa-users"></i> Kelola Terdampak
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<?php endwhile; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header"><h3><i class="fa fa-list" style="color:#dc2626"></i> Riwayat Bencana</h3></div>
|
||||||
|
<div class="tbl-wrap">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>#</th><th>Nama Bencana</th><th>Jenis</th><th>Tanggal</th>
|
||||||
|
<th>Lokasi</th><th>Terdampak</th><th>Status</th><th>Aksi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if ($bencanaList->num_rows === 0): ?>
|
||||||
|
<tr><td colspan="8" style="text-align:center;padding:40px;color:#94a3b8">Belum ada data bencana</td></tr>
|
||||||
|
<?php else: $no=1; while ($b = $bencanaList->fetch_assoc()): ?>
|
||||||
|
<tr>
|
||||||
|
<td style="color:#94a3b8;font-weight:600"><?= $no++ ?></td>
|
||||||
|
<td>
|
||||||
|
<div style="font-weight:700"><?= htmlspecialchars($b['nama_bencana']) ?></div>
|
||||||
|
<div style="font-size:11px;color:#94a3b8"><?= htmlspecialchars($b['lokasi']??'') ?></div>
|
||||||
|
</td>
|
||||||
|
<td><?php
|
||||||
|
$jc=['Banjir'=>'badge-blue','Kebakaran'=>'badge-red','Gempa Bumi'=>'badge-orange','Longsor'=>'badge-yellow','Angin Puting Beliung'=>'badge-purple','Lainnya'=>'badge-gray'];
|
||||||
|
echo '<span class="badge '.($jc[$b['jenis']]??'badge-gray').'">'.$b['jenis'].'</span>';
|
||||||
|
?></td>
|
||||||
|
<td style="font-size:13px"><?= date('d M Y',strtotime($b['tanggal'])) ?></td>
|
||||||
|
<td style="font-size:12px"><?= htmlspecialchars($b['lokasi']??'-') ?></td>
|
||||||
|
<td>
|
||||||
|
<span style="font-size:18px;font-weight:800;color:<?= $b['jml_terdampak']>0?'#dc2626':'#94a3b8' ?>"><?= $b['jml_terdampak'] ?></span>
|
||||||
|
<span style="font-size:11px;color:#94a3b8"> KK</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span class="badge <?= $b['status']==='Aktif'?'badge-red':'badge-green' ?>">
|
||||||
|
<?= $b['status'] === 'Aktif' ? '● Aktif' : '✓ Selesai' ?>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div style="display:flex;gap:4px">
|
||||||
|
<button class="btn btn-warning btn-sm" onclick="bukaKelolaTerdampak(<?= $b['id'] ?>, '<?= htmlspecialchars($b['nama_bencana'], ENT_QUOTES) ?>')">
|
||||||
|
<i class="fa fa-users"></i> Terdampak
|
||||||
|
</button>
|
||||||
|
<?php if (in_array($_SESSION['role'],['admin','pemerintah'])): ?>
|
||||||
|
<?php if ($b['status']==='Aktif'): ?>
|
||||||
|
<button class="btn btn-success btn-sm" onclick="selesaikanBencana(<?= $b['id'] ?>)" title="Selesaikan Bencana">
|
||||||
|
<i class="fa fa-check"></i> Selesai
|
||||||
|
</button>
|
||||||
|
<?php endif; ?>
|
||||||
|
<button class="btn btn-danger btn-sm" onclick="hapusBencana(<?= $b['id'] ?>)" title="Hapus Bencana">
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
</button>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endwhile; endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card" style="margin-top:20px">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3><i class="fa fa-flag" style="color:#dc2626"></i> Warga Prioritas Bencana</h3>
|
||||||
|
<span class="badge badge-red"><?php
|
||||||
|
$p = $conn->query("SELECT COUNT(*) AS c FROM rumah_miskin WHERE prioritas=1")->fetch_assoc()['c'];
|
||||||
|
echo $p.' KK';
|
||||||
|
?></span>
|
||||||
|
</div>
|
||||||
|
<div class="tbl-wrap">
|
||||||
|
<table>
|
||||||
|
<thead><tr><th>Nama KK</th><th>Kondisi Rumah</th><th>Terdampak Bencana</th><th>Tingkat</th><th>Status Bantuan</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
$pList = $conn->query("SELECT rm.*, bt.nama_bencana, bd.tingkat FROM rumah_miskin rm LEFT JOIN bencana_terdampak bd ON rm.id=bd.warga_id LEFT JOIN bencana bt ON bd.bencana_id=bt.id WHERE rm.prioritas=1 ORDER BY rm.updated_at DESC");
|
||||||
|
if ($pList->num_rows === 0):
|
||||||
|
?>
|
||||||
|
<tr><td colspan="5" style="text-align:center;padding:30px;color:#94a3b8"><i class="fa fa-check-circle" style="color:#16a34a;font-size:24px;display:block;margin-bottom:6px"></i>Tidak ada warga prioritas saat ini</td></tr>
|
||||||
|
<?php else: while ($r = $pList->fetch_assoc()): ?>
|
||||||
|
<tr style="background:#fff5f5">
|
||||||
|
<td>
|
||||||
|
<i class="fa fa-flag" style="color:#dc2626;margin-right:6px"></i>
|
||||||
|
<span style="font-weight:700"><?= htmlspecialchars($r['nama_kepala_keluarga']) ?></span>
|
||||||
|
</td>
|
||||||
|
<td><?= $r['kondisi_rumah'] ?></td>
|
||||||
|
<td><?= htmlspecialchars($r['nama_bencana']??'-') ?></td>
|
||||||
|
<td><?php
|
||||||
|
$tc=['Ringan'=>'badge-yellow','Sedang'=>'badge-orange','Berat'=>'badge-red'];
|
||||||
|
echo '<span class="badge '.($tc[$r['tingkat']]??'badge-gray').'">'.($r['tingkat']??'-').'</span>';
|
||||||
|
?></td>
|
||||||
|
<td><?php
|
||||||
|
$sc=['Terjangkau'=>'badge-green','Belum Terbantu'=>'badge-red','Sudah Menerima'=>'badge-blue'];
|
||||||
|
echo '<span class="badge '.($sc[$r['status_bantuan']]??'badge-gray').'">'.$r['status_bantuan'].'</span>';
|
||||||
|
?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endwhile; endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-overlay" id="modalTambahBencana">
|
||||||
|
<div class="modal-box" style="max-width:520px">
|
||||||
|
<div class="modal-head">
|
||||||
|
<h3><i class="fa fa-exclamation-triangle" style="color:#dc2626"></i> Catat Bencana Baru</h3>
|
||||||
|
<button class="btn-close" onclick="closeModal('modalTambahBencana')">✕</button>
|
||||||
|
</div>
|
||||||
|
<form method="POST" action="proses.php">
|
||||||
|
<input type="hidden" name="aksi" value="simpan_bencana">
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group"><label>Nama Bencana *</label>
|
||||||
|
<input class="form-control" name="nama_bencana" required placeholder="cth: Banjir Kelurahan Sungai Jawi">
|
||||||
|
</div>
|
||||||
|
<div class="form-grid-2">
|
||||||
|
<div class="form-group"><label>Jenis Bencana *</label>
|
||||||
|
<select class="form-control" name="jenis">
|
||||||
|
<option>Banjir</option><option>Kebakaran</option><option>Gempa Bumi</option>
|
||||||
|
<option>Longsor</option><option>Angin Puting Beliung</option><option>Lainnya</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group"><label>Tanggal Kejadian *</label>
|
||||||
|
<input class="form-control" type="date" name="tanggal" required value="<?= date('Y-m-d') ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group"><label>Lokasi / Area Terdampak</label>
|
||||||
|
<input class="form-control" name="lokasi" placeholder="cth: RT 03/RW 05, Kel. Sungai Jawi">
|
||||||
|
</div>
|
||||||
|
<div class="form-group"><label>Deskripsi Kejadian</label>
|
||||||
|
<textarea class="form-control" name="deskripsi" rows="3" placeholder="Kronologi dan dampak bencana..."></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-foot">
|
||||||
|
<button type="button" class="btn btn-ghost" onclick="closeModal('modalTambahBencana')">Batal</button>
|
||||||
|
<button type="submit" class="btn btn-danger"><i class="fa fa-save"></i> Catat Bencana</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-overlay" id="modalTerdampak">
|
||||||
|
<div class="modal-box" style="max-width:640px">
|
||||||
|
<div class="modal-head">
|
||||||
|
<h3 id="md_judul"><i class="fa fa-users" style="color:#dc2626"></i> Kelola Warga Terdampak</h3>
|
||||||
|
<button class="btn-close" onclick="closeModal('modalTerdampak')">✕</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div style="background:#fff5f5;border:1px solid #fca5a5;border-radius:10px;padding:16px;margin-bottom:20px">
|
||||||
|
<div style="font-size:13px;font-weight:700;margin-bottom:12px;color:#dc2626"><i class="fa fa-flag"></i> Tandai Warga Terdampak</div>
|
||||||
|
<form id="formTerdampak" onsubmit="tandaiTerdampak(event)">
|
||||||
|
<input type="hidden" id="td_bencana_id">
|
||||||
|
<div class="form-grid-2" style="gap:10px">
|
||||||
|
<div class="form-group" style="margin-bottom:0">
|
||||||
|
<label>Pilih Warga KPM *</label>
|
||||||
|
<select class="form-control" id="td_warga_id" required>
|
||||||
|
<option value="">-- Pilih Warga --</option>
|
||||||
|
<?php $semuaKpm->data_seek(0); while ($k = $semuaKpm->fetch_assoc()): ?>
|
||||||
|
<option value="<?= $k['id'] ?>"><?= htmlspecialchars($k['nama_kepala_keluarga']) ?> (<?= htmlspecialchars($k['kelurahan']??'') ?>)</option>
|
||||||
|
<?php endwhile; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" style="margin-bottom:0">
|
||||||
|
<label>Tingkat Dampak</label>
|
||||||
|
<select class="form-control" id="td_tingkat">
|
||||||
|
<option>Ringan</option><option selected>Sedang</option><option>Berat</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" style="margin:10px 0 0 0">
|
||||||
|
<label>Keterangan</label>
|
||||||
|
<input class="form-control" id="td_ket" placeholder="Kondisi spesifik warga ini...">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-danger btn-sm" style="margin-top:10px"><i class="fa fa-flag"></i> Tandai & Prioritaskan</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="font-size:13px;font-weight:700;margin-bottom:10px">Sudah Ditandai Terdampak:</div>
|
||||||
|
<div id="daftarTerdampak" style="max-height:280px;overflow-y:auto"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function openModal(id) {
|
||||||
|
const modal = document.getElementById(id);
|
||||||
|
if(modal) modal.style.display = 'flex';
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeModal(id) {
|
||||||
|
const modal = document.getElementById(id);
|
||||||
|
if(modal) {
|
||||||
|
modal.style.display = 'none';
|
||||||
|
if (id === 'modalTerdampak') {
|
||||||
|
// Ketika modal ditutup, reload halaman utama agar angka statistik "Terdampak" ikut ter-update
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Fungsi Tombol "Kelola Terdampak" / "Terdampak" (Membuka Modal & Load Data via AJAX)
|
||||||
|
function bukaKelolaTerdampak(bencanaId, namaBencana) {
|
||||||
|
document.getElementById('md_judul').innerHTML = `<i class="fa fa-users" style="color:#dc2626"></i> Kelola Terdampak: <strong>${namaBencana}</strong>`;
|
||||||
|
document.getElementById('td_bencana_id').value = bencanaId;
|
||||||
|
|
||||||
|
// Reset form input penandaan
|
||||||
|
document.getElementById('td_warga_id').value = "";
|
||||||
|
document.getElementById('td_tingkat').value = "Sedang";
|
||||||
|
document.getElementById('td_ket').value = "";
|
||||||
|
|
||||||
|
loadDaftarTerdampak(bencanaId);
|
||||||
|
openModal('modalTerdampak');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Mengambil Data Warga Terdampak via Fetch API Internal (AJAX)
|
||||||
|
function loadDaftarTerdampak(bencanaId) {
|
||||||
|
const container = document.getElementById('daftarTerdampak');
|
||||||
|
container.innerHTML = `<p style="color:#94a3b8; font-size:13px; padding:10px;">Mengambil data...</p>`;
|
||||||
|
|
||||||
|
fetch(`bencana.php?ajax_aksi=ambil_terdampak&bencana_id=${bencanaId}`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 'sukses') {
|
||||||
|
if (res.data.length === 0) {
|
||||||
|
container.innerHTML = `<p style="color:#94a3b8; font-size:13px; padding:10px; text-align:center;">Belum ada warga yang ditandai untuk bencana ini.</p>`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let html = '';
|
||||||
|
res.data.forEach(item => {
|
||||||
|
let badgeColor = item.tingkat === 'Berat' ? 'badge-red' : (item.tingkat === 'Sedang' ? 'badge-orange' : 'badge-yellow');
|
||||||
|
html += `
|
||||||
|
<div class="list-terdampak-item">
|
||||||
|
<div>
|
||||||
|
<strong>${item.nama_kepala_keluarga}</strong> <span class="badge ${badgeColor}">${item.tingkat}</span>
|
||||||
|
<div style="font-size:11px; color:#64748b; margin-top:2px;">
|
||||||
|
Kelurahan: ${item.kelurahan || '-'} | Ket: ${item.keterangan || '-'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-ghost btn-sm" onclick="hapusTerdampak(${item.id}, ${bencanaId})" style="color:#dc2626; padding:4px 8px;" title="Batalkan Prioritas">
|
||||||
|
<i class="fa fa-times"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
container.innerHTML = html;
|
||||||
|
} else {
|
||||||
|
container.innerHTML = `<p style="color:#dc2626; font-size:13px; padding:10px;">Gagal memuat data.</p>`;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
container.innerHTML = `<p style="color:#dc2626; font-size:13px; padding:10px;">Terjadi kesalahan koneksi.</p>`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Menyimpan Data Penandaan Warga Terdampak Baru via AJAX
|
||||||
|
function tandaiTerdampak(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const bencanaId = document.getElementById('td_bencana_id').value;
|
||||||
|
const wargaId = document.getElementById('td_warga_id').value;
|
||||||
|
const tingkat = document.getElementById('td_tingkat').value;
|
||||||
|
const keterangan = document.getElementById('td_ket').value;
|
||||||
|
|
||||||
|
if (!wargaId) {
|
||||||
|
alert('Silakan pilih warga terlebih dahulu.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let formData = new FormData();
|
||||||
|
formData.append('bencana_id', bencanaId);
|
||||||
|
formData.append('warga_id', wargaId);
|
||||||
|
formData.append('tingkat', tingkat);
|
||||||
|
formData.append('keterangan', keterangan);
|
||||||
|
|
||||||
|
fetch('bencana.php?ajax_aksi=tambah_terdampak', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 'sukses') {
|
||||||
|
document.getElementById('td_warga_id').value = "";
|
||||||
|
document.getElementById('td_ket').value = "";
|
||||||
|
loadDaftarTerdampak(bencanaId); // Reload list terdampak secara instan
|
||||||
|
} else {
|
||||||
|
alert(res.pesan);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => console.error(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Menghapus Warga dari Daftar Terdampak via AJAX
|
||||||
|
function hapusTerdampak(idTerdampak, bencanaId) {
|
||||||
|
if (confirm('Apakah Anda yakin ingin menghapus warga ini dari daftar terdampak? Status prioritas tanggap darurat warga juga akan disesuaikan kembali.')) {
|
||||||
|
let formData = new FormData();
|
||||||
|
formData.append('id', idTerdampak);
|
||||||
|
|
||||||
|
fetch('bencana.php?ajax_aksi=hapus_terdampak', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 'sukses') {
|
||||||
|
loadDaftarTerdampak(bencanaId); // Reload list secara instan
|
||||||
|
} else {
|
||||||
|
alert(res.pesan);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => console.error(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Fungsi Tombol "Selesaikan" Bencana
|
||||||
|
function selesaikanBencana(id) {
|
||||||
|
if (confirm('Apakah Anda yakin ingin menyelesaikan status penanganan bencana ini? Status akan berubah menjadi Selesai.')) {
|
||||||
|
const form = document.createElement('form');
|
||||||
|
form.method = 'POST';
|
||||||
|
form.action = 'proses.php';
|
||||||
|
|
||||||
|
form.innerHTML = `
|
||||||
|
<input type="hidden" name="aksi" value="selesai_bencana">
|
||||||
|
<input type="hidden" name="id" value="${id}">
|
||||||
|
`;
|
||||||
|
document.body.appendChild(form);
|
||||||
|
form.submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. Fungsi Tombol "Hapus" Bencana
|
||||||
|
function hapusBencana(id) {
|
||||||
|
if (confirm('Apakah Anda yakin ingin menghapus data riwayat bencana ini? Data warga terdampak yang terhubung juga akan terputus.')) {
|
||||||
|
const form = document.createElement('form');
|
||||||
|
form.method = 'POST';
|
||||||
|
form.action = 'proses.php';
|
||||||
|
|
||||||
|
form.innerHTML = `
|
||||||
|
<input type="hidden" name="aksi" value="hapus_bencana">
|
||||||
|
<input type="hidden" name="id" value="${id}">
|
||||||
|
`;
|
||||||
|
document.body.appendChild(form);
|
||||||
|
form.submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Menutup modal otomatis jika area background gelap diklik
|
||||||
|
window.onclick = function(event) {
|
||||||
|
if (event.target.classList.contains('modal-overlay')) {
|
||||||
|
closeModal(event.target.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
include 'includes/footer.php';
|
||||||
|
?>
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
<?php
|
||||||
|
// dashboard-admin.php
|
||||||
|
require_once 'koneksi.php';
|
||||||
|
cekLogin(); // Memastikan user sudah login lewat fungsi sistem Anda
|
||||||
|
|
||||||
|
// Proteksi ketat: Hanya Role Admin yang Boleh Mengakses Halaman Ini
|
||||||
|
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
|
||||||
|
header('Location: login.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$page = 'beranda'; // Penanda agar menu "Beranda" di sidebar menyala
|
||||||
|
$pageTitle = 'Beranda Admin';
|
||||||
|
$pageSubtitle = 'Panel Kendali Otoritas Tertinggi';
|
||||||
|
|
||||||
|
// 1. MENGAMBIL DATA STATISTIK UTAMA (DIAMBIL DARI DATABASE)
|
||||||
|
$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;
|
||||||
|
$totalBantuan = $conn->query("SELECT COUNT(*) AS c FROM bantuan_tersalur")->fetch_assoc()['c'] ?? 0;
|
||||||
|
$bencanaAktif = $conn->query("SELECT COUNT(*) AS c FROM bencana WHERE status='Aktif'")->fetch_assoc()['c'] ?? 0;
|
||||||
|
$prioritas = $conn->query("SELECT COUNT(*) AS c FROM rumah_miskin WHERE prioritas=1")->fetch_assoc()['c'] ?? 0;
|
||||||
|
|
||||||
|
// Mengambil statistik tambahan khusus admin (Manajemen User)
|
||||||
|
$totalUser = $conn->query("SELECT COUNT(*) AS c FROM users")->fetch_assoc()['c'] ?? 0;
|
||||||
|
$userAktif = $conn->query("SELECT COUNT(*) AS c FROM users WHERE aktif=1")->fetch_assoc()['c'] ?? 0;
|
||||||
|
|
||||||
|
// Menghitung persentase capaian rasio jangkauan bantuan
|
||||||
|
$pct = $totalKpm > 0 ? round($terjangkau / $totalKpm * 100) : 0;
|
||||||
|
|
||||||
|
// 2. MENGAMBIL DATA TERBARU UNTUK PREVIEW LOG TABEL (LIMIT 5)
|
||||||
|
$kpmBaru = $conn->query("SELECT rm.nama_kepala_keluarga, rm.nik, rm.kelurahan, rm.kondisi_rumah, rm.prioritas FROM rumah_miskin rm ORDER BY rm.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 DINAMIS (Otomatis menyambung dan layout tidak akan pecah)
|
||||||
|
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 Administrasi Pusat - Poverty Mapping</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"/>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.db-wrap { max-width: 1200px; font-family: 'Inter', sans-serif; }
|
||||||
|
|
||||||
|
/* Welcome Banner Premium bergradasi linier mewah */
|
||||||
|
.db-welcome {
|
||||||
|
background: linear-gradient(135deg, #0f1d42 0%, #204075 100%);
|
||||||
|
color: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 26px 28px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
box-shadow: 0 10px 20px -3px rgba(30, 58, 138, 0.15);
|
||||||
|
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: 700px; }
|
||||||
|
.db-welcome::after {
|
||||||
|
content: ''; position: absolute; top:0; right:0; width: 250px; height: 100%;
|
||||||
|
background: radial-gradient(circle at 80% 20%, rgba(255,255,255,0.12) 0%, transparent 60%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grid Kartu Statistik Utama */
|
||||||
|
.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;
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
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; font-weight: 500; }
|
||||||
|
.scard-icon { width: 44px; height: 44px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 16px; }
|
||||||
|
|
||||||
|
/* Area Cakupan Bantuan (Progress Bar) */
|
||||||
|
.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-top h3 { font-size: 14px; font-weight: 700; color: #1e293b; }
|
||||||
|
.cov-top p { font-size: 12px; color: #64748b; margin-top: 2px; }
|
||||||
|
.cov-pct { font-size: 24px; font-weight: 800; color: #059669; }
|
||||||
|
.cov-track { height: 12px; background: #e2e8f0; border-radius: 99px; overflow: hidden; }
|
||||||
|
.cov-fill { height: 100%; background: linear-gradient(90deg, #10b981, #34d399); border-radius: 99px; transition: width .8s; }
|
||||||
|
.cov-meta { display: flex; gap: 20px; font-size: 12px; color: #475569; margin-top: 14px; flex-wrap: wrap; font-weight: 500; }
|
||||||
|
.cov-meta strong { color: #0f172a; }
|
||||||
|
|
||||||
|
/* Pembagian 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; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.02); }
|
||||||
|
.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: #1e3a8a; display: flex; align-items: center; gap: 8px; }
|
||||||
|
.dbt-head a { font-size: 12px; color: #3b82f6; text-decoration: none; font-weight: 600; background: #eff6ff; padding: 4px 10px; border-radius: 6px; transition: 0.2s; }
|
||||||
|
.dbt-head a:hover { background: #dbeafe; }
|
||||||
|
|
||||||
|
/* Styling Tabel Premium */
|
||||||
|
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; letter-spacing: .5px; border-bottom: 1px solid #e2e8f0; }
|
||||||
|
table.dbt td { padding: 14px 16px; border-bottom: 1px solid #f1f5f9; vertical-align: middle; color: #334155; }
|
||||||
|
table.dbt tr:last-child td { border-bottom: none; }
|
||||||
|
table.dbt tr:hover { background: #f8fafc; }
|
||||||
|
|
||||||
|
/* Lencana Modern (Badges) */
|
||||||
|
.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; }
|
||||||
|
.badge-warning { background: #fef3c7; color: #d97706; }
|
||||||
|
.badge-info { background: #e0f2fe; color: #0284c7; }
|
||||||
|
|
||||||
|
@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 Kembali, <?= htmlspecialchars($_SESSION['nama'] ?? 'Administrator') ?></h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="stat-row">
|
||||||
|
<div class="scard">
|
||||||
|
<div>
|
||||||
|
<div class="scard-label">Manajemen Akun</div>
|
||||||
|
<div class="scard-num"><?= $totalUser ?> Akun</div>
|
||||||
|
<div class="scard-sub"><i class="fa fa-circle" style="font-size:8px; color:#10b981;"></i> <?= $userAktif ?> User Aktif</div>
|
||||||
|
</div>
|
||||||
|
<div class="scard-icon" style="background: #e0e7ff; color: #4f46e5;">
|
||||||
|
<i class="fa fa-user-gear"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="scard">
|
||||||
|
<div>
|
||||||
|
<div class="scard-label">Total KPM</div>
|
||||||
|
<div class="scard-num"><?= $totalKpm ?></div>
|
||||||
|
<div class="scard-sub">Keluarga terdata</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">Belum terjangkau</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 Aktif</div>
|
||||||
|
<div class="scard-num" style="color:<?= $bencanaAktif > 0 ? '#dc2626' : '#0f172a' ?>"><?= $bencanaAktif ?></div>
|
||||||
|
<div class="scard-sub"><?= $bencanaAktif > 0 ? $prioritas.' KPM diprioritaskan' : 'Sistem kondusif' ?></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 Capaian Pengentasan Kemiskinan Makro</h3>
|
||||||
|
<p>Persentase keseluruhan KPM yang berhasil masuk dalam jangkauan koordinasi pos 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>Terjangkau: <strong><?= $terjangkau ?> KPM</strong></span>
|
||||||
|
<span>Blank Spot: <strong><?= $blankSpot ?> KPM</strong></span>
|
||||||
|
<span>Titik Pos Rumah Ibadah: <strong><?= $totalIbadah ?> Titik</strong></span>
|
||||||
|
<span>Total Penyaluran: <strong><?= $totalBantuan ?> Kali</strong></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="db-tables">
|
||||||
|
|
||||||
|
<div class="dbt-card">
|
||||||
|
<div class="dbt-head">
|
||||||
|
<h3><i class="fa fa-user-plus"></i> Pendaftaran KPM Terbaru</h3>
|
||||||
|
<a href="data-warga.php">Lihat semua</a>
|
||||||
|
</div>
|
||||||
|
<table class="dbt">
|
||||||
|
<thead>
|
||||||
|
<tr><th>Nama KK</th><th>Kelurahan</th><th>Kondisi Rumah</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if ($kpmBaru->num_rows === 0): ?>
|
||||||
|
<tr><td colspan="3" style="text-align:center;padding:28px;color:#94a3b8;">Belum ada entri data KPM terdaftar.</td></tr>
|
||||||
|
<?php else:
|
||||||
|
while ($k = $kpmBaru->fetch_assoc()):
|
||||||
|
$kondisiClass = 'badge-info';
|
||||||
|
if (in_array($k['kondisi_rumah'], ['Sangat Parah', 'Sangat Tidak Layak'])) $kondisiClass = 'badge-danger';
|
||||||
|
elseif (in_array($k['kondisi_rumah'], ['Parah', 'Tidak Layak'])) $kondisiClass = 'badge-warning';
|
||||||
|
elseif (in_array($k['kondisi_rumah'], ['Cukup Baik', 'Layak'])) $kondisiClass = 'badge-success';
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div style="font-weight:600"><?= htmlspecialchars($k['nama_kepala_keluarga']) ?></div>
|
||||||
|
<div style="font-size:11px;color:#94a3b8">NIK: <?= $k['nik'] ?: '-' ?></div>
|
||||||
|
</td>
|
||||||
|
<td style="font-size:12px;"><?= htmlspecialchars($k['kelurahan'] ?: '-') ?></td>
|
||||||
|
<td>
|
||||||
|
<span class="badge-modern <?= $kondisiClass ?>"><?= $k['kondisi_rumah'] ?></span>
|
||||||
|
<?php if ($k['prioritas'] == 1): ?>
|
||||||
|
<span class="badge-modern badge-danger" title="Prioritas Utama"><i class="fa fa-bolt"></i></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endwhile; endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dbt-card">
|
||||||
|
<div class="dbt-head">
|
||||||
|
<h3><i class="fa fa-hand-holding-heart"></i> Transaksi Distribusi Bantuan</h3>
|
||||||
|
<a href="bantuan.php">Lihat semua</a>
|
||||||
|
</div>
|
||||||
|
<table class="dbt">
|
||||||
|
<thead>
|
||||||
|
<tr><th>Penerima KPM</th><th>Paket Bantuan</th><th>Tanggal Penyaluran</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if ($bantuanBaru->num_rows === 0): ?>
|
||||||
|
<tr><td colspan="3" style="text-align:center;padding:28px;color:#94a3b8;">Belum ada log transaksi penyaluran bantuan.</td></tr>
|
||||||
|
<?php else: while ($b = $bantuanBaru->fetch_assoc()): ?>
|
||||||
|
<tr>
|
||||||
|
<td style="font-weight:600"><?= htmlspecialchars($b['nama_kepala_keluarga'] ?? '-') ?></td>
|
||||||
|
<td>
|
||||||
|
<span class="badge-modern badge-success"><?= htmlspecialchars($b['jenis_bantuan']) ?></span>
|
||||||
|
<?php if ($b['jumlah']): ?>
|
||||||
|
<div style="font-size:11px;color:#64748b;margin-top:2px; font-weight:500;"><?= htmlspecialchars($b['jumlah']) ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
|
<td style="font-size:12px;color:#64748b"><?= date('d M Y', strtotime($b['tanggal'])) ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endwhile; endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php include 'includes/footer.php'; ?>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user