179 lines
9.8 KiB
HTML
179 lines
9.8 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="id">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Peta Bantuan Sosial - Dinsos Pontianak</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
|
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700&display=swap" rel="stylesheet">
|
|
<style>
|
|
body { font-family: 'Poppins', sans-serif; }
|
|
</style>
|
|
</head>
|
|
<body class="bg-gray-50 flex flex-col min-h-screen">
|
|
|
|
<nav class="bg-white p-4 shadow-sm z-30 flex justify-between items-center px-8 sticky top-0">
|
|
<h1 class="text-xl font-bold text-gray-800">SIG Dinsos Pontianak</h1>
|
|
<a href="petugas_login.html" class="text-sm font-semibold text-emerald-600 hover:text-emerald-800 transition">Login Petugas</a>
|
|
</nav>
|
|
|
|
<main class="flex-grow flex flex-col gap-10 pb-12">
|
|
|
|
<section class="bg-emerald-600 text-white px-6 py-12 text-center rounded-b-[3rem] shadow-md">
|
|
<div class="max-w-3xl mx-auto">
|
|
<h2 class="text-3xl font-bold mb-4">Cek Status Bantuan Sosial Anda</h2>
|
|
<p class="text-emerald-100 mb-8 font-light">Sistem Informasi Geografis terintegrasi untuk transparansi validasi data kemiskinan masyarakat Kota Pontianak.</p>
|
|
|
|
<div class="bg-white p-2 rounded-2xl shadow-xl flex flex-col sm:flex-row gap-2 max-w-xl mx-auto border border-emerald-100">
|
|
<input type="text" id="nik_input" placeholder="Masukkan 16 digit NIK..." maxlength="16" class="w-full p-4 rounded-xl bg-transparent focus:outline-none text-gray-800">
|
|
<button onclick="cek_status_bantuan()" id="btn_cari" class="bg-emerald-600 text-white px-8 py-4 rounded-xl font-bold hover:bg-emerald-700 transition flex-shrink-0">Cari Data</button>
|
|
</div>
|
|
|
|
<div id="hasil_pencarian" class="mt-6 hidden p-4 rounded-xl border max-w-xl mx-auto text-left bg-white text-gray-800 shadow-lg transition-all">
|
|
<p id="pesan_hasil" class="text-sm font-semibold"></p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="px-6">
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 max-w-5xl mx-auto">
|
|
<div class="bg-white p-6 rounded-2xl shadow-sm border border-gray-100 text-center">
|
|
<h3 class="text-gray-500 text-sm font-semibold uppercase tracking-wider mb-2">Total Terverifikasi</h3>
|
|
<p id="stat_publik_terverifikasi" class="text-3xl font-bold text-emerald-600">0</p>
|
|
</div>
|
|
<div class="bg-white p-6 rounded-2xl shadow-sm border border-gray-100 text-center">
|
|
<h3 class="text-gray-500 text-sm font-semibold uppercase tracking-wider mb-2">Sedang Diproses</h3>
|
|
<p id="stat_publik_diproses" class="text-3xl font-bold text-yellow-500">0</p>
|
|
</div>
|
|
<div class="bg-white p-6 rounded-2xl shadow-sm border border-gray-100 text-center">
|
|
<h3 class="text-gray-500 text-sm font-semibold uppercase tracking-wider mb-2">Pembaruan Terakhir</h3>
|
|
<p id="stat_publik_waktu" class="text-lg font-bold text-gray-700 mt-2">Menghitung...</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="px-6">
|
|
<div class="h-[400px] w-full max-w-5xl mx-auto rounded-2xl overflow-hidden shadow-sm border border-gray-200 z-0 relative">
|
|
<div id="map_container" class="absolute inset-0"></div>
|
|
</div>
|
|
</section>
|
|
|
|
</main>
|
|
|
|
<script>
|
|
const leaflet_map = L.map('map_container').setView([-0.0227, 109.3425], 13);
|
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
attribution: '© OpenStreetMap contributors'
|
|
}).addTo(leaflet_map);
|
|
|
|
let map_marker_warga = null;
|
|
let map_marker_pangkalan = null;
|
|
let map_garis_hubung = null;
|
|
|
|
// Custom ikon untuk pangkalan distribusi (Rumah Ibadah)
|
|
const ikon_pangkalan = L.icon({
|
|
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-green.png',
|
|
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
|
|
iconSize: [25, 41],
|
|
iconAnchor: [12, 41],
|
|
popupAnchor: [1, -34],
|
|
shadowSize: [41, 41]
|
|
});
|
|
|
|
async function muat_statistik_publik() {
|
|
try {
|
|
const respons_http = await fetch('/api/survey/statistik');
|
|
if (!respons_http.ok) throw new Error('Gagal mengambil data statistik');
|
|
const data_agregat = await respons_http.json();
|
|
|
|
document.getElementById('stat_publik_terverifikasi').textContent = data_agregat.terverifikasi || 0;
|
|
document.getElementById('stat_publik_diproses').textContent = data_agregat.diproses || 0;
|
|
|
|
const waktu_terformat_wib = new Date().toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit', timeZone: 'Asia/Jakarta' });
|
|
document.getElementById('stat_publik_waktu').textContent = `Hari ini, ${waktu_terformat_wib} WIB`;
|
|
|
|
} catch (error_sistem) {
|
|
document.getElementById('stat_publik_waktu').textContent = 'Sistem Terhubung';
|
|
}
|
|
}
|
|
|
|
const cek_status_bantuan = async () => {
|
|
const input_nik_value = document.getElementById('nik_input').value;
|
|
const kotak_hasil = document.getElementById('hasil_pencarian');
|
|
const pesan_hasil = document.getElementById('pesan_hasil');
|
|
const tombol_cari = document.getElementById('btn_cari');
|
|
|
|
if (!/^\d{16}$/.test(input_nik_value)) return alert('Masukkan NIK yang valid (16 digit angka).');
|
|
|
|
tombol_cari.disabled = true;
|
|
tombol_cari.textContent = 'Mencari...';
|
|
|
|
try {
|
|
const http_response = await fetch(`/api/survey/cek-nik/${input_nik_value}`);
|
|
if (!http_response.ok) throw new Error('Data tidak ditemukan');
|
|
|
|
const json_data = await http_response.json();
|
|
|
|
kotak_hasil.classList.remove('hidden', 'bg-red-50', 'bg-emerald-50', 'border-red-200', 'border-emerald-200');
|
|
kotak_hasil.classList.add('bg-emerald-50', 'border-emerald-200');
|
|
pesan_hasil.className = 'text-emerald-700';
|
|
|
|
let teks_respons = `Data ditemukan: ${json_data.nama_kk} | Status: ${json_data.status_validasi}`;
|
|
if (json_data.rumah_ibadah_nama) {
|
|
teks_respons += `<br><span class="text-xs text-emerald-600 font-normal mt-1 block">📍 Tempat Penyaluran: ${json_data.rumah_ibadah_nama}</span>`;
|
|
}
|
|
pesan_hasil.innerHTML = teks_respons;
|
|
|
|
// Menghapus layer peta sebelumnya secara bersih
|
|
if (map_marker_warga) leaflet_map.removeLayer(map_marker_warga);
|
|
if (map_marker_pangkalan) leaflet_map.removeLayer(map_marker_pangkalan);
|
|
if (map_garis_hubung) leaflet_map.removeLayer(map_garis_hubung);
|
|
|
|
if (json_data.lat && json_data.lng) {
|
|
const koordinat_warga = [parseFloat(json_data.lat), parseFloat(json_data.lng)];
|
|
|
|
// Merender titik lokasi rumah mustahik (ikon biru bawaan)
|
|
map_marker_warga = L.marker(koordinat_warga).addTo(leaflet_map)
|
|
.bindPopup(`<b>${json_data.nama_kk}</b><br>Status: ${json_data.status_validasi}`)
|
|
.openPopup();
|
|
|
|
// Baris Kompleks: Jika data pangkalan silang (JOIN) tersedia, kita merender ikon hijau khusus
|
|
// pada koordinat rumah ibadah, lalu menggambar objek vektor polyline merah putus-putus
|
|
// untuk memvisualisasikan jarak dan rute dari rumah warga menuju pangkalan penyaluran.
|
|
if (json_data.rumah_ibadah_lat && json_data.rumah_ibadah_lng) {
|
|
const koordinat_pangkalan = [parseFloat(json_data.rumah_ibadah_lat), parseFloat(json_data.rumah_ibadah_lng)];
|
|
|
|
map_marker_pangkalan = L.marker(koordinat_pangkalan, { icon: ikon_pangkalan }).addTo(leaflet_map)
|
|
.bindPopup(`<b>Pusat Penyaluran</b><br>${json_data.rumah_ibadah_nama}`);
|
|
|
|
map_garis_hubung = L.polyline([koordinat_warga, koordinat_pangkalan], {
|
|
color: 'red',
|
|
weight: 3,
|
|
dashArray: '10, 10',
|
|
opacity: 0.7
|
|
}).addTo(leaflet_map);
|
|
|
|
// Menyesuaikan bidang pandang kamera agar kedua titik terlihat di layar
|
|
leaflet_map.fitBounds(map_garis_hubung.getBounds(), { padding: [50, 50] });
|
|
} else {
|
|
leaflet_map.setView(koordinat_warga, 16);
|
|
}
|
|
}
|
|
|
|
} catch (error_object) {
|
|
kotak_hasil.classList.remove('hidden', 'bg-red-50', 'bg-emerald-50', 'border-red-200', 'border-emerald-200');
|
|
kotak_hasil.classList.add('bg-red-50', 'border-red-200');
|
|
pesan_hasil.className = 'text-red-700';
|
|
pesan_hasil.textContent = 'Mohon maaf, NIK tidak terdaftar atau terjadi kesalahan sistem.';
|
|
} finally {
|
|
tombol_cari.disabled = false;
|
|
tombol_cari.textContent = 'Cari Data';
|
|
}
|
|
};
|
|
|
|
muat_statistik_publik();
|
|
</script>
|
|
</body>
|
|
</html> |