329 lines
15 KiB
PHP
329 lines
15 KiB
PHP
<?php
|
||
// ================================================================
|
||
// Admin: CRUD Rumah Ibadah
|
||
// ================================================================
|
||
require_once __DIR__ . '/../config/config.php';
|
||
require_once __DIR__ . '/../config/database.php';
|
||
require_once __DIR__ . '/../includes/auth.php';
|
||
require_once __DIR__ . '/../includes/functions.php';
|
||
requireLogin();
|
||
|
||
$pageTitle = 'Rumah Ibadah';
|
||
require_once __DIR__ . '/../includes/header.php';
|
||
|
||
$db = getDB();
|
||
|
||
// Pagination
|
||
$perPage = 15;
|
||
$page = max(1, (int)($_GET['page'] ?? 1));
|
||
$offset = ($page - 1) * $perPage;
|
||
|
||
// Filter & search
|
||
$search = trim($_GET['search'] ?? '');
|
||
$filterJenis = $_GET['jenis'] ?? '';
|
||
$filterKec = $_GET['kecamatan'] ?? '';
|
||
|
||
$where = ['1=1'];
|
||
$params = [];
|
||
if ($search) { $where[] = '(nama LIKE ? OR kontak LIKE ? OR alamat LIKE ?)'; $q = "%$search%"; $params = array_merge($params, [$q,$q,$q]); }
|
||
if ($filterJenis) { $where[] = 'jenis = ?'; $params[] = $filterJenis; }
|
||
if ($filterKec) { $where[] = 'kecamatan = ?'; $params[] = $filterKec; }
|
||
|
||
$whereStr = implode(' AND ', $where);
|
||
$total = (int)$db->prepare("SELECT COUNT(*) FROM rumah_ibadah WHERE $whereStr")->execute($params) ? $db->prepare("SELECT COUNT(*) FROM rumah_ibadah WHERE $whereStr")->execute($params) : 0;
|
||
|
||
// Re-execute for count
|
||
$stmtCount = $db->prepare("SELECT COUNT(*) FROM rumah_ibadah WHERE $whereStr");
|
||
$stmtCount->execute($params);
|
||
$total = (int)$stmtCount->fetchColumn();
|
||
$totalPages = max(1, ceil($total / $perPage));
|
||
|
||
$stmt = $db->prepare("
|
||
SELECT ri.*,
|
||
(SELECT COUNT(*) FROM penduduk_miskin pm WHERE pm.rumah_ibadah_id = ri.id) AS jumlah_binaan
|
||
FROM rumah_ibadah ri
|
||
WHERE $whereStr ORDER BY ri.created_at DESC LIMIT $perPage OFFSET $offset
|
||
");
|
||
$stmt->execute($params);
|
||
$rows = $stmt->fetchAll();
|
||
|
||
// Kecamatan list for filter
|
||
$kecamatanList = $db->query("SELECT DISTINCT kecamatan FROM rumah_ibadah WHERE kecamatan IS NOT NULL AND kecamatan != '' ORDER BY kecamatan")->fetchAll(PDO::FETCH_COLUMN);
|
||
?>
|
||
|
||
<!-- ── Page Header ─────────────────────────────────────────── -->
|
||
<div class="page-header">
|
||
<div class="page-title-block">
|
||
<h1>🏛️ Rumah Ibadah</h1>
|
||
<div class="page-subtitle">Total <?= $total ?> data terdaftar</div>
|
||
</div>
|
||
<div class="page-actions">
|
||
<a href="<?= BASE_URL ?>/?mode=ibadah" target="_blank" class="btn btn-ghost btn-sm">
|
||
<i class="bi bi-map"></i> Tambah di Peta
|
||
</a>
|
||
<button class="btn btn-primary btn-sm" onclick="openModal()">
|
||
<i class="bi bi-plus-lg"></i> Tambah Manual
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── Filter Bar ──────────────────────────────────────────── -->
|
||
<div class="card" style="margin-bottom:16px;">
|
||
<div class="card-body" style="padding:14px;">
|
||
<form method="GET" style="display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;">
|
||
<div class="search-bar" style="flex:1;min-width:200px;">
|
||
<i class="bi bi-search search-ico"></i>
|
||
<input type="text" class="form-control" name="search" placeholder="Cari nama, kontak, alamat..." value="<?= htmlspecialchars($search) ?>">
|
||
</div>
|
||
<div>
|
||
<select class="form-control" name="jenis">
|
||
<option value="">Semua Jenis</option>
|
||
<?php foreach (array_keys(JENIS_IBADAH) as $j): ?>
|
||
<option value="<?= $j ?>" <?= $filterJenis===$j?'selected':'' ?>><?= JENIS_EMOJI[$j]??'' ?> <?= $j ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<select class="form-control" name="kecamatan">
|
||
<option value="">Semua Kecamatan</option>
|
||
<?php foreach ($kecamatanList as $k): ?>
|
||
<option value="<?= htmlspecialchars($k) ?>" <?= $filterKec===$k?'selected':'' ?>><?= htmlspecialchars($k) ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<button type="submit" class="btn btn-primary btn-sm"><i class="bi bi-search"></i> Filter</button>
|
||
<a href="<?= BASE_URL ?>/admin/rumah_ibadah.php" class="btn btn-ghost btn-sm"><i class="bi bi-x"></i> Reset</a>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── Table ───────────────────────────────────────────────── -->
|
||
<div class="card">
|
||
<div class="table-responsive">
|
||
<table class="admin-table">
|
||
<thead>
|
||
<tr>
|
||
<th>#</th>
|
||
<th>Nama</th>
|
||
<th>Jenis</th>
|
||
<th>Kontak</th>
|
||
<th>Kecamatan</th>
|
||
<th>Radius</th>
|
||
<th>Binaan</th>
|
||
<th>Koordinat</th>
|
||
<th>Ditambahkan</th>
|
||
<th class="td-actions">Aksi</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($rows as $i => $row): ?>
|
||
<tr>
|
||
<td style="color:var(--text3);font-size:11px;"><?= $offset + $i + 1 ?></td>
|
||
<td style="font-weight:700;"><?= htmlspecialchars($row['nama']) ?></td>
|
||
<td>
|
||
<span class="badge-status" style="background:rgba(91,127,255,0.12);color:var(--accent)">
|
||
<?= JENIS_EMOJI[$row['jenis']]??'' ?> <?= $row['jenis'] ?>
|
||
</span>
|
||
</td>
|
||
<td style="color:var(--text2);font-size:12px;"><?= htmlspecialchars($row['kontak'] ?: '—') ?></td>
|
||
<td style="color:var(--text2);font-size:12px;"><?= htmlspecialchars($row['kecamatan'] ?: '—') ?></td>
|
||
<td style="color:var(--accent);font-weight:700;"><?= formatRadius($row['radius']) ?></td>
|
||
<td>
|
||
<?php if ($row['jumlah_binaan'] > 0): ?>
|
||
<a href="<?= BASE_URL ?>/admin/penduduk_miskin.php?ibadah_id=<?= $row['id'] ?>" style="color:var(--green);font-weight:700;text-decoration:none;"><?= $row['jumlah_binaan'] ?> warga</a>
|
||
<?php else: ?>
|
||
<span style="color:var(--text3)">0</span>
|
||
<?php endif; ?>
|
||
</td>
|
||
<td style="font-size:10px;color:var(--text3);font-family:monospace;"><?= number_format($row['lat'],5) ?>, <?= number_format($row['lng'],5) ?></td>
|
||
<td style="font-size:11px;color:var(--text3);"><?= formatTanggal($row['created_at']) ?></td>
|
||
<td class="td-actions">
|
||
<button class="btn btn-ghost btn-sm" onclick="editRow(<?= htmlspecialchars(json_encode($row)) ?>)" title="Edit">
|
||
<i class="bi bi-pencil-fill"></i>
|
||
</button>
|
||
<a href="<?= BASE_URL ?>/?focus=ibadah&id=<?= $row['id'] ?>" target="_blank" class="btn btn-ghost btn-sm" title="Lihat di Peta">
|
||
<i class="bi bi-map-fill"></i>
|
||
</a>
|
||
<button class="btn btn-danger btn-sm" onclick="deleteRow(<?= $row['id'] ?>, '<?= addslashes($row['nama']) ?>')" title="Hapus">
|
||
<i class="bi bi-trash-fill"></i>
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
<?php if (empty($rows)): ?>
|
||
<tr><td colspan="10" style="text-align:center;padding:32px;color:var(--text3);">
|
||
<div style="font-size:28px;margin-bottom:6px;">🏛️</div>
|
||
Tidak ada data ditemukan
|
||
</td></tr>
|
||
<?php endif; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- Pagination -->
|
||
<?php if ($totalPages > 1): ?>
|
||
<div style="padding:14px 18px;border-top:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px;">
|
||
<div style="font-size:12px;color:var(--text2);">
|
||
Menampilkan <?= $offset+1 ?>–<?= min($offset+$perPage,$total) ?> dari <?= $total ?> data
|
||
</div>
|
||
<div class="pagination">
|
||
<?php
|
||
$base = BASE_URL . '/admin/rumah_ibadah.php?' . http_build_query(array_filter(['search'=>$search,'jenis'=>$filterJenis,'kecamatan'=>$filterKec]));
|
||
for ($p = 1; $p <= $totalPages; $p++):
|
||
?>
|
||
<a href="<?= $base ?>&page=<?= $p ?>" class="page-btn <?= $p===$page?'active':'' ?>"><?= $p ?></a>
|
||
<?php endfor; ?>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<!-- ── Modal Tambah/Edit ───────────────────────────────────── -->
|
||
<div class="modal fade" id="modal-ibadah" tabindex="-1">
|
||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="modal-title">🏛️ Tambah Rumah Ibadah</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<input type="hidden" id="edit-id">
|
||
<div class="section-label">📍 Lokasi</div>
|
||
<div class="form-row" style="margin-bottom:14px;">
|
||
<div class="form-group">
|
||
<label class="form-label">Latitude <span style="color:var(--red)">*</span></label>
|
||
<input class="form-control" id="f-lat" type="number" step="any" placeholder="-0.0263">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Longitude <span style="color:var(--red)">*</span></label>
|
||
<input class="form-control" id="f-lng" type="number" step="any" placeholder="109.3425">
|
||
</div>
|
||
</div>
|
||
<div class="form-row" style="margin-bottom:14px;">
|
||
<div class="form-group">
|
||
<label class="form-label">Kelurahan</label>
|
||
<input class="form-control" id="f-kelurahan" placeholder="Kelurahan">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Kecamatan</label>
|
||
<input class="form-control" id="f-kecamatan" placeholder="Kecamatan">
|
||
</div>
|
||
</div>
|
||
<div class="section-label">🕌 Data Ibadah</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Nama Rumah Ibadah <span style="color:var(--red)">*</span></label>
|
||
<input class="form-control" id="f-nama" placeholder="Nama lengkap rumah ibadah">
|
||
</div>
|
||
<div class="form-row" style="margin-bottom:14px;">
|
||
<div class="form-group">
|
||
<label class="form-label">Jenis</label>
|
||
<select class="form-control" id="f-jenis">
|
||
<option value="Masjid">🕌 Masjid</option>
|
||
<option value="Musholla">🕌 Musholla</option>
|
||
<option value="Gereja">⛪ Gereja</option>
|
||
<option value="Katolik">⛪ Gereja Katolik</option>
|
||
<option value="Pura">🛕 Pura</option>
|
||
<option value="Vihara">🛕 Vihara</option>
|
||
<option value="Klenteng">⛩️ Klenteng</option>
|
||
<option value="Lainnya">🙏 Lainnya</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Kontak</label>
|
||
<input class="form-control" id="f-kontak" placeholder="Telepon / WhatsApp">
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Alamat Lengkap</label>
|
||
<input class="form-control" id="f-alamat" placeholder="Jalan, nomor, dll.">
|
||
</div>
|
||
<div class="section-label">📏 Radius Layanan</div>
|
||
<div class="form-group">
|
||
<div class="range-wrapper">
|
||
<input type="range" id="f-radius" min="100" max="5000" step="50" value="300" style="flex:1;accent-color:var(--accent);">
|
||
<span class="range-val" id="f-radius-val">300 m</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-ghost" data-bs-dismiss="modal"><i class="bi bi-x-lg"></i> Batal</button>
|
||
<button type="button" class="btn btn-primary" id="btn-save"><i class="bi bi-floppy2-fill"></i> Simpan</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
const BASE = '<?= BASE_URL ?>';
|
||
|
||
// Radius slider
|
||
document.getElementById('f-radius').addEventListener('input', function() {
|
||
const v = parseInt(this.value);
|
||
document.getElementById('f-radius-val').textContent = v >= 1000 ? (v/1000).toFixed(1)+' km' : v+' m';
|
||
});
|
||
|
||
function openModal(data = null) {
|
||
const isEdit = data !== null;
|
||
document.getElementById('modal-title').textContent = isEdit ? '✏️ Edit Rumah Ibadah' : '🏛️ Tambah Rumah Ibadah';
|
||
document.getElementById('edit-id').value = isEdit ? data.id : '';
|
||
document.getElementById('f-nama').value = isEdit ? data.nama : '';
|
||
document.getElementById('f-jenis').value = isEdit ? data.jenis : 'Masjid';
|
||
document.getElementById('f-kontak').value = isEdit ? (data.kontak || '') : '';
|
||
document.getElementById('f-alamat').value = isEdit ? (data.alamat || '') : '';
|
||
document.getElementById('f-kelurahan').value = isEdit ? (data.kelurahan||'') : '';
|
||
document.getElementById('f-kecamatan').value = isEdit ? (data.kecamatan||'') : '';
|
||
document.getElementById('f-lat').value = isEdit ? data.lat : '';
|
||
document.getElementById('f-lng').value = isEdit ? data.lng : '';
|
||
const rad = isEdit ? parseInt(data.radius) : 300;
|
||
document.getElementById('f-radius').value = rad;
|
||
document.getElementById('f-radius-val').textContent = rad >= 1000 ? (rad/1000).toFixed(1)+' km' : rad+' m';
|
||
new bootstrap.Modal(document.getElementById('modal-ibadah')).show();
|
||
}
|
||
|
||
function editRow(data) { openModal(data); }
|
||
|
||
document.getElementById('btn-save').addEventListener('click', async function() {
|
||
const nama = document.getElementById('f-nama').value.trim();
|
||
const lat = document.getElementById('f-lat').value;
|
||
const lng = document.getElementById('f-lng').value;
|
||
if (!nama || !lat || !lng) { Swal.fire('Error','Nama, Lat, dan Lng wajib diisi!','error'); return; }
|
||
const editId = document.getElementById('edit-id').value;
|
||
const payload = {
|
||
nama, jenis: document.getElementById('f-jenis').value,
|
||
kontak: document.getElementById('f-kontak').value,
|
||
alamat: document.getElementById('f-alamat').value,
|
||
kelurahan: document.getElementById('f-kelurahan').value,
|
||
kecamatan: document.getElementById('f-kecamatan').value,
|
||
lat: parseFloat(lat), lng: parseFloat(lng),
|
||
radius: parseInt(document.getElementById('f-radius').value)
|
||
};
|
||
this.disabled = true; this.textContent = '⏳ Menyimpan...';
|
||
try {
|
||
const url = editId ? `${BASE}/api/rumah_ibadah.php?id=${editId}` : `${BASE}/api/rumah_ibadah.php`;
|
||
const resp = await fetch(url, { method: editId?'PUT':'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload) });
|
||
const json = await resp.json();
|
||
if (json.success) { location.reload(); } else { Swal.fire('Error', json.message, 'error'); }
|
||
} catch(e) { Swal.fire('Error','Gagal menyimpan data','error'); }
|
||
finally { this.disabled = false; this.innerHTML = '<i class="bi bi-floppy2-fill"></i> Simpan'; }
|
||
});
|
||
|
||
async function deleteRow(id, nama) {
|
||
const res = await Swal.fire({
|
||
title: 'Hapus Rumah Ibadah?',
|
||
html: `<b>${nama}</b> akan dihapus permanen. Warga binaan akan di-reset.`,
|
||
icon: 'warning', showCancelButton: true,
|
||
confirmButtonText: 'Ya, Hapus!', cancelButtonText: 'Batal',
|
||
confirmButtonColor: '#ef4444', background: '#161b27', color: '#e8ecf4'
|
||
});
|
||
if (!res.isConfirmed) return;
|
||
try {
|
||
const r = await fetch(`${BASE}/api/rumah_ibadah.php?id=${id}`, { method:'DELETE' });
|
||
const js = await r.json();
|
||
if (js.success) { Swal.fire({title:'Terhapus!',icon:'success',timer:1500,background:'#161b27',color:'#e8ecf4'}).then(() => location.reload()); }
|
||
else Swal.fire('Error', js.message, 'error');
|
||
} catch { Swal.fire('Error','Gagal menghapus','error'); }
|
||
}
|
||
</script>
|
||
|
||
<?php require_once __DIR__ . '/../includes/footer.php'; ?>
|