Files
UAS_WEBGIS_IhyaUlumuddinHar…/project_final/enumerator/data.php
T
2026-06-13 11:24:58 +07:00

162 lines
10 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/../config/auth_check.php';
requireAnyRole(['enumerator']);
$pdo = Database::getConnection();
$uid = currentUser()['id'];
$stmt = $pdo->prepare("
SELECT w.*, wl.nama AS wilayah_nama,
(SELECT COUNT(*) FROM foto_rumah f WHERE f.warga_id=w.id) AS jumlah_foto
FROM warga_miskin w LEFT JOIN wilayah wl ON wl.id=w.wilayah_id
WHERE w.created_by=? ORDER BY w.id DESC
");
$stmt->execute([$uid]);
$rows = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Data Saya — 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">
<style>
*{margin:0;padding:0;box-sizing:border-box;font-family:'Inter',sans-serif;}
body{background:#F3F4F6;color:#111827;padding-bottom:30px;}
.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;}
.topbar a{color:#fff;text-decoration:none;font-size:1.2rem;}
.topbar h1{font-size:1rem;font-weight:700;}
.container{max-width:560px;margin:0 auto;padding:16px;}
.card{background:#fff;border:1px solid #E5E7EB;border-radius:12px;padding:14px;margin-bottom:10px;}
.card .nm{font-weight:700;font-size:0.95rem;}
.card .meta{font-size:0.78rem;color:#6B7280;margin-top:2px;}
.badge{font-size:0.7rem;padding:3px 9px;border-radius:20px;}
.b-ok{background:#D1FAE5;color:#065F46;} .b-no{background:#F3F4F6;color:#6B7280;} .b-rev{background:#FEF3C7;color:#92400E;}
.acts{display:flex;gap:8px;margin-top:10px;}
.acts button{flex:1;padding:9px;border:1px solid #D1D5DB;background:#fff;border-radius:8px;font-size:0.8rem;cursor:pointer;}
.acts button.pri{background:#2563EB;color:#fff;border-color:#2563EB;}
.overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:1000;align-items:flex-end;}
.overlay.show{display:flex;}
.sheet{background:#fff;width:100%;max-width:560px;margin:0 auto;border-radius:16px 16px 0 0;padding:18px;max-height:88vh;overflow-y:auto;}
.sheet h3{font-size:1rem;margin-bottom:12px;}
label{display:block;font-size:0.78rem;font-weight:600;margin-bottom:4px;}
input,select{width:100%;padding:11px;border:1px solid #D1D5DB;border-radius:9px;font-size:0.92rem;margin-bottom:10px;}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:8px;}
.btn-save{width:100%;background:#2563EB;color:#fff;border:none;padding:13px;border-radius:10px;font-weight:700;cursor:pointer;}
.photo-prev{display:flex;flex-wrap:wrap;gap:8px;margin:8px 0;}
.photo-prev .ph{position:relative;}
.photo-prev img{width:70px;height:70px;object-fit:cover;border-radius:8px;border:1px solid #E5E7EB;}
.photo-prev .del{position:absolute;top:-6px;right:-6px;background:#EF4444;color:#fff;border:none;border-radius:50%;width:20px;height:20px;cursor:pointer;}
.toast{position:fixed;top:70px;left:50%;transform:translateX(-50%);background:#111827;color:#fff;padding:10px 18px;border-radius:10px;font-size:0.85rem;z-index:2000;opacity:0;transition:.3s;}
.toast.show{opacity:1;} .toast.err{background:#DC2626;}
.empty{text-align:center;color:#9CA3AF;padding:40px 0;font-size:0.9rem;}
</style>
</head>
<body>
<div class="topbar">
<a href="<?= app_url('enumerator/index.php') ?>"><i class="fas fa-arrow-left"></i></a>
<h1>Data yang Saya Input (<?= count($rows) ?>)</h1>
</div>
<div class="container">
<?php if (!$rows): ?><div class="empty">Belum ada data. <br>Tambahkan via "Input Data Warga Baru".</div><?php endif; ?>
<?php foreach ($rows as $r):
$vb = $r['status_verifikasi']==='terverifikasi' ? 'b-ok' : ($r['status_verifikasi']==='perlu_tinjauan' ? 'b-rev' : 'b-no'); ?>
<div class="card">
<div style="display:flex;justify-content:space-between;align-items:start;">
<div>
<div class="nm"><?= htmlspecialchars($r['nama_kk']) ?></div>
<div class="meta"><?= htmlspecialchars($r['wilayah_nama'] ?: 'Tanpa kelurahan') ?> · Rp <?= number_format($r['penghasilan'],0,',','.') ?> · 📷 <?= $r['jumlah_foto'] ?></div>
</div>
<span class="badge <?= $vb ?>"><?= htmlspecialchars($r['status_verifikasi']) ?></span>
</div>
<div class="acts">
<button onclick='openEdit(<?= json_encode($r, JSON_HEX_APOS|JSON_HEX_QUOT) ?>)'><i class="fas fa-edit"></i> Edit</button>
<button class="pri" onclick="openFoto(<?= $r['id'] ?>)"><i class="fas fa-camera"></i> Foto</button>
</div>
</div>
<?php endforeach; ?>
</div>
<!-- Sheet Edit -->
<div class="overlay" id="editOverlay"><div class="sheet">
<h3>✏️ Edit Data</h3>
<input type="hidden" id="eId">
<label>Nama KK *</label><input id="eNama">
<label>NIK</label><input id="eNik" maxlength="16">
<label>Alamat</label><input id="eAlamat">
<div class="row2"><div><label>Jiwa</label><input id="eJiwa" type="number"></div><div><label>Tanggungan</label><input id="eTang" type="number"></div></div>
<label>Pekerjaan</label><input id="ePek">
<label>Penghasilan (Rp)</label><input id="ePeng" type="number">
<label>Sumber Air</label><select id="eAir"><option value="">-</option><option>SUMUR_BOR</option><option>PDAM</option><option>SUNGAI</option><option>HUJAN</option><option>TIDAK_ADA</option></select>
<label>Material Dinding</label><select id="eDind"><option value="">-</option><option>PERMANEN</option><option>SEMI_PERMANEN</option><option>TIDAK_PERMANEN</option></select>
<button class="btn-save" onclick="saveEdit()">Simpan Perubahan</button>
<button class="btn-save" style="background:#fff;color:#374151;border:1px solid #D1D5DB;margin-top:8px;" onclick="closeSheet('editOverlay')">Batal</button>
</div></div>
<!-- Sheet Foto -->
<div class="overlay" id="fotoOverlay"><div class="sheet">
<h3>📷 Foto Kondisi Rumah</h3>
<div class="photo-prev" id="fotoList"></div>
<input type="file" id="fotoFile" accept="image/*" capture="environment" multiple style="margin-bottom:10px;">
<button class="btn-save" onclick="uploadFoto()">Unggah Foto</button>
<button class="btn-save" style="background:#fff;color:#374151;border:1px solid #D1D5DB;margin-top:8px;" onclick="closeSheet('fotoOverlay')">Tutup</button>
</div></div>
<div class="toast" id="toast"></div>
<script>
const APP_BASE='<?= app_url() ?>';
let fotoWid=null;
function toast(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show'+(t==='err'?' err':'');setTimeout(()=>e.className='toast',2800);}
function closeSheet(id){document.getElementById(id).classList.remove('show');}
function openEdit(r){
document.getElementById('eId').value=r.id;
document.getElementById('eNama').value=r.nama_kk||'';
document.getElementById('eNik').value=r.nik_kk||'';
document.getElementById('eAlamat').value=r.alamat||'';
document.getElementById('eJiwa').value=r.jumlah_jiwa||'';
document.getElementById('eTang').value=r.jumlah_tanggungan||'';
document.getElementById('ePek').value=r.pekerjaan_kk||'';
document.getElementById('ePeng').value=r.penghasilan||'';
document.getElementById('eAir').value=r.sumber_air||'';
document.getElementById('eDind').value=r.material_dinding||'';
document.getElementById('editOverlay').classList.add('show');
}
async function saveEdit(){
const id=document.getElementById('eId').value;
const body={
nama_kk:document.getElementById('eNama').value.trim(),
nik_kk:document.getElementById('eNik').value.trim(),
alamat:document.getElementById('eAlamat').value.trim(),
jumlah_jiwa:document.getElementById('eJiwa').value||null,
jumlah_tanggungan:parseInt(document.getElementById('eTang').value)||0,
pekerjaan_kk:document.getElementById('ePek').value.trim(),
penghasilan:parseFloat(document.getElementById('ePeng').value)||0,
sumber_air:document.getElementById('eAir').value,
material_dinding:document.getElementById('eDind').value
};
if(!body.nama_kk) return toast('Nama wajib','err');
const res=await fetch(APP_BASE+'/api/warga_miskin.php?id='+id,{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)});
const d=await res.json();
if(d.status==='success'){toast('Tersimpan ✓');setTimeout(()=>location.reload(),900);}else toast(d.message||'Gagal','err');
}
async function openFoto(wid){
fotoWid=wid; document.getElementById('fotoOverlay').classList.add('show');
const res=await fetch(APP_BASE+'/api/foto.php?warga_id='+wid); const d=await res.json();
const g=document.getElementById('fotoList');
g.innerHTML=(d.data&&d.data.length)?d.data.map(f=>`<div class="ph"><img src="${f.url}"><button class="del" onclick="delFoto(${f.id})">×</button></div>`).join(''):'<p style="color:#9CA3AF;font-size:0.85rem">Belum ada foto.</p>';
}
async function uploadFoto(){
const inp=document.getElementById('fotoFile'); if(!inp.files.length) return toast('Pilih foto','err');
const fd=new FormData(); fd.append('warga_id',fotoWid);
for(const f of inp.files) fd.append('foto[]',f);
const res=await fetch(APP_BASE+'/api/foto.php',{method:'POST',body:fd}); const d=await res.json();
if(d.status==='success'){toast(d.message);inp.value='';openFoto(fotoWid);}else toast(d.message,'err');
}
async function delFoto(id){const res=await fetch(APP_BASE+'/api/foto.php?id='+id,{method:'DELETE'});const d=await res.json();if(d.status==='success'){toast('Foto dihapus');openFoto(fotoWid);}}
</script>
</body>
</html>