Files
UAS_SIG/bencana.php
T
2026-06-03 05:04:28 +00:00

516 lines
25 KiB
PHP

<?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';
?>