162 lines
10 KiB
PHP
162 lines
10 KiB
PHP
<?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>
|