Files
2026-06-13 11:24:58 +07:00

191 lines
12 KiB
PHP

<?php
require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/../config/auth_check.php';
requireAnyRole(['enumerator']);
$user = currentUser();
$wilayah = $user['wilayah_tugas'] ?: 'Belum ditentukan';
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Input Data Warga — Enumerator</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<style>
*{margin:0;padding:0;box-sizing:border-box;font-family:'Inter',sans-serif;}
body{background:#F3F4F6;color:#111827;padding-bottom:90px;}
.topbar{position:sticky;top:0;z-index:500;background:linear-gradient(135deg,#2563EB,#1D4ED8);color:#fff;padding:14px 16px;display:flex;align-items:center;gap:12px;box-shadow:0 2px 8px rgba(0,0,0,.15);}
.topbar a{color:#fff;text-decoration:none;font-size:1.2rem;}
.topbar h1{font-size:1rem;font-weight:700;}
.topbar .sub{font-size:0.72rem;opacity:.9;}
.container{max-width:560px;margin:0 auto;padding:16px;}
.section{background:#fff;border:1px solid #E5E7EB;border-radius:14px;padding:16px;margin-bottom:14px;}
.section h3{font-size:0.85rem;color:#2563EB;margin-bottom:12px;text-transform:uppercase;letter-spacing:.5px;}
label{display:block;font-size:0.8rem;font-weight:600;margin-bottom:5px;color:#374151;}
input,select{width:100%;padding:12px;border:1px solid #D1D5DB;border-radius:10px;font-size:0.95rem;margin-bottom:12px;outline:none;}
input:focus,select:focus{border-color:#2563EB;}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:10px;}
.gps-btn{width:100%;background:#059669;color:#fff;border:none;padding:14px;border-radius:10px;font-size:0.95rem;font-weight:600;cursor:pointer;margin-bottom:10px;display:flex;align-items:center;justify-content:center;gap:8px;}
#map{height:240px;border-radius:10px;border:1px solid #E5E7EB;margin-bottom:10px;}
.coord{font-size:0.78rem;color:#6B7280;text-align:center;margin-bottom:8px;}
.photo-prev{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px;}
.photo-prev img{width:72px;height:72px;object-fit:cover;border-radius:8px;border:1px solid #E5E7EB;}
.savebar{position:fixed;bottom:0;left:0;right:0;background:#fff;border-top:1px solid #E5E7EB;padding:12px 16px;display:flex;gap:10px;max-width:560px;margin:0 auto;}
.btn-save{flex:1;background:#2563EB;color:#fff;border:none;padding:14px;border-radius:10px;font-size:1rem;font-weight:700;cursor:pointer;}
.btn-save:disabled{opacity:.6;}
.toast{position:fixed;top:70px;left:50%;transform:translateX(-50%);background:#111827;color:#fff;padding:12px 20px;border-radius:10px;font-size:0.88rem;z-index:1000;opacity:0;transition:.3s;}
.toast.show{opacity:1;}
.toast.err{background:#DC2626;}
</style>
</head>
<body>
<div class="topbar">
<a href="<?= app_url('enumerator/index.php') ?>"><i class="fas fa-arrow-left"></i></a>
<div><h1>Input Data Warga</h1><div class="sub">Wilayah: <?= htmlspecialchars($wilayah) ?></div></div>
</div>
<div class="container">
<div class="section">
<h3>📍 Lokasi (Geotagging)</h3>
<button type="button" class="gps-btn" onclick="getGPS()"><i class="fas fa-location-crosshairs"></i> <span id="gpsLabel">Gunakan GPS Otomatis</span></button>
<div id="map"></div>
<div class="coord" id="coordHint">Gunakan GPS, <b>ketuk peta</b>, <b>geser pin</b>, atau ketik koordinat manual di bawah.</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:8px;">
<div><label>Latitude</label><input id="inLat" type="number" step="any" inputmode="decimal" placeholder="-0.0500" onchange="applyManual()"></div>
<div><label>Longitude</label><input id="inLng" type="number" step="any" inputmode="decimal" placeholder="109.3450" onchange="applyManual()"></div>
</div>
</div>
<div class="section">
<h3>👤 Identitas</h3>
<label>Nama Kepala Keluarga *</label><input id="nama" placeholder="Nama lengkap KK">
<label>NIK KK</label><input id="nik" maxlength="16" inputmode="numeric" placeholder="16 digit">
<label>Alamat</label><input id="alamat" placeholder="Alamat tempat tinggal">
<div class="row2"><div><label>RT</label><input id="rt"></div><div><label>RW</label><input id="rw"></div></div>
</div>
<div class="section">
<h3>👨‍👩‍👧 Demografi & Ekonomi</h3>
<div class="row2">
<div><label>Jumlah Jiwa</label><input id="jiwa" type="number" inputmode="numeric"></div>
<div><label>Tanggungan</label><input id="tanggungan" type="number" inputmode="numeric"></div>
</div>
<label>Pekerjaan KK</label><input id="pekerjaan" placeholder="mis. Buruh harian">
<label>Penghasilan / bulan (Rp)</label><input id="penghasilan" type="number" inputmode="numeric">
</div>
<div class="section">
<h3>🏠 Kondisi Rumah</h3>
<label>Sumber Air</label>
<select id="air"><option value="">-</option><option>SUMUR_BOR</option><option>PDAM</option><option>SUNGAI</option><option>HUJAN</option><option>TIDAK_ADA</option></select>
<label>Listrik</label>
<select id="listrik"><option value="">-</option><option>PLN</option><option>NON_PLN</option><option>TIDAK_ADA</option></select>
<label>Material Dinding</label>
<select id="dinding"><option value="">-</option><option>PERMANEN</option><option>SEMI_PERMANEN</option><option>TIDAK_PERMANEN</option></select>
<label>Status Kepemilikan</label>
<select id="kepemilikan"><option value="">-</option><option>MILIK</option><option>SEWA</option><option>NUMPANG</option><option>LAINNYA</option></select>
</div>
<div class="section">
<h3>📷 Foto Kondisi Rumah</h3>
<input type="file" id="foto" accept="image/*" capture="environment" multiple>
<div class="photo-prev" id="photoPrev"></div>
</div>
</div>
<div class="savebar">
<button class="btn-save" id="btnSave" onclick="simpan()"><i class="fas fa-save"></i> Simpan Data</button>
</div>
<div class="toast" id="toast"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
const APP_BASE = '<?= app_url() ?>';
let map, marker, lat=null, lng=null;
function initMap(){
map = L.map('map').setView([-0.0500,109.3450],13);
L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png',{subdomains:'abcd',maxZoom:19}).addTo(map);
map.on('click',e=>setPoint(e.latlng.lat,e.latlng.lng,false));
}
function ensureMarker(la,ln){
if(!marker){
marker=L.marker([la,ln],{draggable:true}).addTo(map);
marker.on('dragend',ev=>{const p=ev.target.getLatLng();lat=p.lat;lng=p.lng;syncInputs();});
} else { marker.setLatLng([la,ln]); }
}
function setPoint(la,ln,zoom){
lat=la; lng=ln;
ensureMarker(la,ln);
if(zoom!==false) map.setView([la,ln],16);
syncInputs();
}
function syncInputs(){
document.getElementById('inLat').value = lat.toFixed(6);
document.getElementById('inLng').value = lng.toFixed(6);
document.getElementById('coordHint').innerHTML = `📌 Titik terpasang: ${lat.toFixed(6)}, ${lng.toFixed(6)} — geser pin / ketik untuk koreksi.`;
}
function applyManual(){
const la=parseFloat(document.getElementById('inLat').value), ln=parseFloat(document.getElementById('inLng').value);
if(isNaN(la)||isNaN(ln)){ showToast('Koordinat tidak valid','err'); return; }
setPoint(la,ln);
}
function getGPS(){
const lbl=document.getElementById('gpsLabel');
if(!navigator.geolocation){ toast('GPS tidak didukung perangkat','err'); return; }
lbl.textContent='Mencari lokasi...';
navigator.geolocation.getCurrentPosition(
pos=>{ setPoint(pos.coords.latitude,pos.coords.longitude); lbl.textContent='GPS Terdeteksi ✓'; toast('Lokasi GPS terisi'); },
err=>{ lbl.textContent='Gunakan GPS Otomatis'; toast('Gagal ambil GPS: '+err.message+'. Ketuk peta manual.','err'); },
{ enableHighAccuracy:true, timeout:10000 }
);
}
// preview foto
document.getElementById('foto').addEventListener('change',function(){
const p=document.getElementById('photoPrev'); p.innerHTML='';
[...this.files].slice(0,5).forEach(f=>{ const img=document.createElement('img'); img.src=URL.createObjectURL(f); p.appendChild(img); });
});
function toast(msg,type){ const t=document.getElementById('toast'); t.textContent=msg; t.className='toast show'+(type==='err'?' err':''); setTimeout(()=>t.className='toast',3000); }
async function simpan(){
const nama=document.getElementById('nama').value.trim();
if(!nama) return toast('Nama KK wajib diisi','err');
if(lat===null||lng===null) return toast('Tentukan lokasi (GPS / ketuk peta)','err');
const btn=document.getElementById('btnSave'); btn.disabled=true; btn.innerHTML='Menyimpan...';
const body={
nama_kk:nama, nik_kk:document.getElementById('nik').value.trim(),
alamat:document.getElementById('alamat').value.trim(),
rt:document.getElementById('rt').value.trim(), rw:document.getElementById('rw').value.trim(),
jumlah_jiwa:document.getElementById('jiwa').value||null,
jumlah_tanggungan:parseInt(document.getElementById('tanggungan').value)||0,
pekerjaan_kk:document.getElementById('pekerjaan').value.trim(),
penghasilan:parseFloat(document.getElementById('penghasilan').value)||0,
sumber_air:document.getElementById('air').value, status_listrik:document.getElementById('listrik').value,
material_dinding:document.getElementById('dinding').value, status_kepemilikan:document.getElementById('kepemilikan').value,
geometry:{type:'Point',coordinates:[lng,lat]}
};
try{
const res=await fetch(APP_BASE+'/api/warga_miskin.php',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)});
const d=await res.json();
if(d.status!=='success'){ toast(d.message||'Gagal','err'); btn.disabled=false; btn.innerHTML='<i class="fas fa-save"></i> Simpan Data'; return; }
const wid=d.data.id;
const files=document.getElementById('foto').files;
if(files.length){
const fd=new FormData(); fd.append('warga_id',wid);
for(const f of files) fd.append('foto[]',f);
btn.innerHTML='Mengunggah foto...';
await fetch(APP_BASE+'/api/foto.php',{method:'POST',body:fd});
}
toast('Data tersimpan ✓');
setTimeout(()=>{ window.location.href=APP_BASE+'/enumerator/index.php'; },1200);
}catch(e){ toast('Error: '+e.message,'err'); btn.disabled=false; btn.innerHTML='<i class="fas fa-save"></i> Simpan Data'; }
}
initMap();
</script>
</body>
</html>