update besar besaran
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
/* ═══════════════════════════════════════════════════════════
|
||||
7. CARD BUILDERS (sidebar)
|
||||
═══════════════════════════════════════════════════════════ */
|
||||
const Card = {
|
||||
_acts:(ln,id)=>`<div class="dcard-acts">
|
||||
<button class="bsm bsm-zoom" onclick="App.map.zoomTo('${ln}','${id}')">Zoom</button>
|
||||
<button class="bsm bsm-edit" onclick="App.crud.edit('${ln}','${id}')">Edit</button>
|
||||
<button class="bsm bsm-del" onclick="App.crud.delete('${ln}','${id}')">Hapus</button></div>`,
|
||||
|
||||
spbu(r){ const clr=CFG.spbu.color(r),bdg=CFG.spbu.badge(r);
|
||||
return `<div class="dcard" id="card-${r.id}">
|
||||
<div class="dcard-head" onclick="App.map.zoomTo('spbu','${r.id}')">
|
||||
<span class="dcard-sym circle" style="background:${clr}"></span>
|
||||
<span class="dcard-name">${H.esc(r.nama)}</span><span class="badge ${bdg.c}">${bdg.t}</span></div>
|
||||
<div class="dcard-attrs">
|
||||
<div class="attr"><span class="attr-k">WA</span><span class="attr-v">${H.esc(r.wa||'-')}</span></div>
|
||||
<div class="attr"><span class="attr-k">BBM</span><span class="attr-v">${H.esc(r.jenis_bbm||'-')}</span></div>
|
||||
</div>${this._acts('spbu',r.id)}</div>`; },
|
||||
|
||||
jalan(r){ const clr=CFG.jalan.color(r),bdg=CFG.jalan.badge(r);
|
||||
return `<div class="dcard" id="card-${r.id}">
|
||||
<div class="dcard-head" onclick="App.map.zoomTo('jalan','${r.id}')">
|
||||
<span class="dcard-sym line" style="background:${clr}"></span>
|
||||
<span class="dcard-name">${H.esc(r.nama)}</span><span class="badge ${bdg.c}">${bdg.t}</span></div>
|
||||
<div class="dcard-attrs">
|
||||
<div class="attr"><span class="attr-k">Panjang</span><span class="attr-v">${H.fmDist(r.panjang)}</span></div>
|
||||
<div class="attr"><span class="attr-k">Kondisi</span><span class="attr-v">${H.esc(r.kondisi||'-')}</span></div>
|
||||
</div>${this._acts('jalan',r.id)}</div>`; },
|
||||
|
||||
parsil(r){ const clr=CFG.parsil.color(r),bdg=CFG.parsil.badge(r);
|
||||
return `<div class="dcard" id="card-${r.id}">
|
||||
<div class="dcard-head" onclick="App.map.zoomTo('parsil','${r.id}')">
|
||||
<span class="dcard-sym poly" style="color:${clr};height:9px"></span>
|
||||
<span class="dcard-name">${H.esc(r.nama)}</span><span class="badge ${bdg.c}">${bdg.t}</span></div>
|
||||
<div class="dcard-attrs">
|
||||
<div class="attr"><span class="attr-k">Luas</span><span class="attr-v">${H.fmArea(r.luas)}</span></div>
|
||||
<div class="attr"><span class="attr-k">Sengketa</span><span class="attr-v">${H.esc(r.sengketa||'-')}</span></div>
|
||||
</div>${this._acts('parsil',r.id)}</div>`; },
|
||||
|
||||
warga(r){ const clr=CFG.warga.color(r),bdg=CFG.warga.badge(r);
|
||||
const pendapatan=r.pendapatan?'Rp '+parseInt(r.pendapatan).toLocaleString('id-ID'):'-';
|
||||
const histCount=r.history_bansos?.length||0;
|
||||
return `<div class="dcard" id="card-${r.id}">
|
||||
<div class="dcard-head" onclick="App.map.zoomTo('warga','${r.id}')">
|
||||
<span class="dcard-sym circle" style="background:${clr}"></span>
|
||||
<span class="dcard-name">${H.esc(r.nama)}</span><span class="badge ${bdg.c}">${bdg.t}</span></div>
|
||||
<div class="dcard-attrs">
|
||||
<div class="attr"><span class="attr-k">Anggota</span><span class="attr-v">${r.jml_anggota||'-'} jiwa</span></div>
|
||||
<div class="attr"><span class="attr-k">Pendapatan</span><span class="attr-v">${pendapatan}</span></div>
|
||||
<div class="attr"><span class="attr-k">Bansos</span><span class="attr-v">${H.esc(r.bansos||'-')}</span></div>
|
||||
<div class="attr"><span class="attr-k">Riwayat</span><span class="attr-v">${histCount} program</span></div>
|
||||
</div>${this._acts('warga',r.id)}</div>`; },
|
||||
|
||||
rumahIbadah(r){ const clr=CFG.rumahIbadah.color(r),bdg=CFG.rumahIbadah.badge(r);
|
||||
return `<div class="dcard" id="card-${r.id}">
|
||||
<div class="dcard-head" onclick="App.map.zoomTo('rumahIbadah','${r.id}')">
|
||||
<span class="dcard-sym circle" style="background:${clr}"></span>
|
||||
<span class="dcard-name">${H.esc(r.nama)}</span><span class="badge ${bdg.c}">${bdg.t}</span></div>
|
||||
<div class="dcard-attrs">
|
||||
<div class="attr"><span class="attr-k">Ketua</span><span class="attr-v">${H.esc(r.ketua||'-')}</span></div>
|
||||
<div class="attr"><span class="attr-k">Binaan</span><span class="attr-v">${r.jml_binaan||'-'} KK</span></div>
|
||||
</div>${this._acts('rumahIbadah',r.id)}</div>`; },
|
||||
};
|
||||
@@ -0,0 +1,361 @@
|
||||
/* ═══════════════════════════════════════════════════════════
|
||||
5. FORM BUILDERS
|
||||
═══════════════════════════════════════════════════════════ */
|
||||
const Forms = {
|
||||
spbu(rec, latlng){
|
||||
const lat=latlng?latlng.lat.toFixed(6):(rec?.lat?.toFixed(6)||'');
|
||||
const lng=latlng?latlng.lng.toFixed(6):(rec?.lng?.toFixed(6)||'');
|
||||
const v=f=>rec?H.esc(rec[f]||''):'';
|
||||
return `
|
||||
<div class="info-box">📍 Koordinat: <strong>${lat}, ${lng}</strong></div>
|
||||
<div class="form-sect">Identitas & Operasional</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Nama SPBU<span class="req">*</span></label>
|
||||
<input class="finput" id="f-nama" placeholder="cth: SPBU 64.754.01" value="${v('nama')}"/></div>
|
||||
<div class="fg"><label class="flabel">No. WhatsApp</label>
|
||||
<input class="finput" id="f-wa" placeholder="081234..." value="${v('wa')}"/></div>
|
||||
</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Jenis BBM Tersedia</label>
|
||||
<select class="finput" id="f-jenis_bbm">
|
||||
${['Pertalite & Pertamax','Pertalite Saja','Pertamax Series','Solar & Pertamina Dex','Semua Jenis'].map(j=>`<option ${v('jenis_bbm')===j?'selected':''}>${j}</option>`).join('')}
|
||||
</select></div>
|
||||
<div class="fg"><label class="flabel">Buka 24 Jam?</label>
|
||||
<div class="rtoggle" id="rtog">
|
||||
<label class="ropt ${rec?.buka24!==false?'yes':''}" data-v="true">
|
||||
<input type="radio" name="buka24" value="true" ${rec?.buka24!==false?'checked':''}/>✓ Ya
|
||||
</label>
|
||||
<label class="ropt ${rec?.buka24===false?'no':''}" data-v="false">
|
||||
<input type="radio" name="buka24" value="false" ${rec?.buka24===false?'checked':''}/>✗ Tidak
|
||||
</label>
|
||||
</div></div>
|
||||
</div>
|
||||
<div class="form-sect">Aksesibilitas & Sosial</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Pelayanan Disabilitas</label>
|
||||
<select class="finput" id="f-disabilitas">
|
||||
${['Ada','Tidak Ada','Dalam Proses'].map(j=>`<option ${v('disabilitas')===j?'selected':''}>${j}</option>`).join('')}
|
||||
</select></div>
|
||||
<div class="fg"><label class="flabel">Harga BBM Subsidi</label>
|
||||
<select class="finput" id="f-harga_bbm">
|
||||
${['Sesuai HET','Di Atas HET','Tidak Menjual Subsidi'].map(j=>`<option ${v('harga_bbm')===j?'selected':''}>${j}</option>`).join('')}
|
||||
</select></div>
|
||||
</div>
|
||||
<div class="form-sect">Catatan Lapangan</div>
|
||||
<div class="fg"><label class="flabel">Catatan / Keterangan Tambahan</label>
|
||||
<textarea class="finput" id="f-catatan" placeholder="Kondisi antrean, ketersediaan stok, dll...">${v('catatan')}</textarea></div>`;
|
||||
},
|
||||
|
||||
jalan(rec, len){
|
||||
const pj=len??rec?.panjang??0; const v=f=>rec?H.esc(rec[f]||''):'';
|
||||
return `
|
||||
<div class="info-box">📏 Panjang terukur otomatis: <strong>${H.fmDist(pj)}</strong></div>
|
||||
<input type="hidden" id="f-panjang" value="${pj}"/>
|
||||
<div class="form-sect">Identitas Ruas Jalan</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Nama Ruas Jalan<span class="req">*</span></label>
|
||||
<input class="finput" id="f-nama" placeholder="cth: Jl. H. Rais A Rahman" value="${v('nama')}"/></div>
|
||||
<div class="fg"><label class="flabel">Status Jalan<span class="req">*</span></label>
|
||||
<select class="finput" id="f-status">
|
||||
${CFG.jalan.statuses.map(s=>`<option ${v('status')===s?'selected':''}>${s}</option>`).join('')}
|
||||
</select></div>
|
||||
</div>
|
||||
<div class="form-sect">Kondisi & Infrastruktur</div>
|
||||
<div class="form-row cols3">
|
||||
<div class="fg"><label class="flabel">Kondisi Jalan</label>
|
||||
<select class="finput" id="f-kondisi">
|
||||
${CFG.jalan.kondisi.map(k=>`<option ${v('kondisi')===k?'selected':''}>${k}</option>`).join('')}
|
||||
</select></div>
|
||||
<div class="fg"><label class="flabel">Tahun Perbaikan Terakhir</label>
|
||||
<input class="finput" id="f-tahun_perbaikan" type="number" min="2000" max="2030" placeholder="2023" value="${v('tahun_perbaikan')}"/></div>
|
||||
<div class="fg"><label class="flabel">Lebar Jalan (meter)</label>
|
||||
<input class="finput" id="f-lebar" type="number" min="1" max="50" placeholder="4" value="${v('lebar')}"/></div>
|
||||
</div>
|
||||
<div class="form-sect">Dampak Sosial-Ekonomi</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Dilalui Angkutan Umum</label>
|
||||
<select class="finput" id="f-angkutan">
|
||||
${['Ya','Tidak'].map(k=>`<option ${v('angkutan')===k?'selected':''}>${k}</option>`).join('')}
|
||||
</select></div>
|
||||
<div class="fg"><label class="flabel">Akses ke Fasilitas Publik</label>
|
||||
<select class="finput" id="f-akses_publik">
|
||||
${['Pasar','RS/Puskesmas','Sekolah','Kantor Pemerintah','Tidak Ada'].map(k=>`<option ${v('akses_publik')===k?'selected':''}>${k}</option>`).join('')}
|
||||
</select></div>
|
||||
</div>
|
||||
<div class="fg"><label class="flabel">Catatan Kondisi</label>
|
||||
<textarea class="finput" id="f-catatan" placeholder="Kondisi berlubang, banjir saat hujan, dll...">${v('catatan')}</textarea></div>`;
|
||||
},
|
||||
|
||||
parsil(rec, area){
|
||||
const ls=area??rec?.luas??0; const v=f=>rec?H.esc(rec[f]||''):'';
|
||||
return `
|
||||
<div class="info-box">📐 Luas terukur otomatis: <strong>${H.fmArea(ls)}</strong></div>
|
||||
<input type="hidden" id="f-luas" value="${ls}"/>
|
||||
<div class="form-sect">Identitas Parsil</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Nama / ID Parsil<span class="req">*</span></label>
|
||||
<input class="finput" id="f-nama" placeholder="cth: Kavling A-01" value="${v('nama')}"/></div>
|
||||
<div class="fg"><label class="flabel">Nomor Induk Bidang (NIB)</label>
|
||||
<input class="finput" id="f-nib" placeholder="14.02.01.001" value="${v('nib')}"/></div>
|
||||
</div>
|
||||
<div class="form-sect">Status Kepemilikan</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Status Sertifikat<span class="req">*</span></label>
|
||||
<select class="finput" id="f-status">
|
||||
${CFG.parsil.statuses.map(s=>`<option ${v('status')===s?'selected':''}>${s}</option>`).join('')}
|
||||
</select></div>
|
||||
<div class="fg"><label class="flabel">Sengketa / Masalah Hukum</label>
|
||||
<select class="finput" id="f-sengketa">
|
||||
${['Tidak Ada','Ada Sengketa','Dalam Proses PTSL','Klaim Pihak Lain'].map(k=>`<option ${v('sengketa')===k?'selected':''}>${k}</option>`).join('')}
|
||||
</select></div>
|
||||
</div>
|
||||
<div class="form-sect">Penilaian & Pemanfaatan</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">NJOP (Rp/m²)</label>
|
||||
<input class="finput" id="f-njop" type="number" placeholder="500000" value="${v('njop')}"/></div>
|
||||
<div class="fg"><label class="flabel">Penggunaan Lahan</label>
|
||||
<select class="finput" id="f-penggunaan">
|
||||
${['Rumah Tinggal','Lahan Kosong','Pertanian','Usaha/Warung','Fasilitas Umum','Lainnya'].map(k=>`<option ${v('penggunaan')===k?'selected':''}>${k}</option>`).join('')}
|
||||
</select></div>
|
||||
</div>
|
||||
<div class="fg"><label class="flabel">Catatan Tambahan</label>
|
||||
<textarea class="finput" id="f-catatan" placeholder="Kondisi, penghuni, riwayat...">${v('catatan')}</textarea></div>`;
|
||||
},
|
||||
|
||||
warga(rec, latlng){
|
||||
const lat=latlng?latlng.lat.toFixed(6):(rec?.lat?.toFixed(6)||'');
|
||||
const lng=latlng?latlng.lng.toFixed(6):(rec?.lng?.toFixed(6)||'');
|
||||
const v=f=>rec?H.esc(rec[f]||''):'';
|
||||
const c=v=>rec?.penyakit?.includes(v)?'checked':'';
|
||||
const hist=rec?.history_bansos||[];
|
||||
const ri = Store.all('rumahIbadah');
|
||||
const hubOpts = ['Belum ditugaskan', ...ri.map(r=>r.nama)].map(opt=>`<option ${v('hub_ri')===opt?'selected':''}>${opt}</option>`).join('');
|
||||
|
||||
return `
|
||||
<div class="info-box warn">⚠️ Data warga bersifat sensitif. Pastikan survei akurat.</div>
|
||||
<div class="info-box">📍 Koordinat: <strong>${lat}, ${lng}</strong></div>
|
||||
<div class="form-tabs">
|
||||
<div class="form-tab active" data-panel="kk">Data KK</div>
|
||||
<div class="form-tab" data-panel="eko">Ekonomi</div>
|
||||
<div class="form-tab" data-panel="pddk">Pddk</div>
|
||||
<div class="form-tab" data-panel="kes">Kes</div>
|
||||
<div class="form-tab" data-panel="hist">Bansos</div>
|
||||
</div>
|
||||
|
||||
<!-- TAB: Data KK -->
|
||||
<div class="form-section-panel active" id="panel-kk">
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Nama KK<span class="req">*</span></label>
|
||||
<input class="finput" id="f-nama" placeholder="Nama KTP" value="${v('nama')}"/></div>
|
||||
<div class="fg"><label class="flabel">NIK</label>
|
||||
<input class="finput" id="f-nik" placeholder="3471..." maxlength="16" value="${v('nik')}"/></div>
|
||||
</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">No. KK</label>
|
||||
<input class="finput" id="f-no_kk" value="${v('no_kk')}"/></div>
|
||||
<div class="fg"><label class="flabel">WA/HP</label>
|
||||
<input class="finput" id="f-wa" value="${v('wa')}"/></div>
|
||||
</div>
|
||||
<div class="form-row cols3">
|
||||
<div class="fg"><label class="flabel">Tingkat Kemiskinan</label>
|
||||
<select class="finput" id="f-tingkat_kemiskinan">
|
||||
${CFG.warga.tingkat.map(t=>`<option ${v('tingkat_kemiskinan')===t?'selected':''}>${t}</option>`).join('')}
|
||||
</select></div>
|
||||
<div class="fg"><label class="flabel">Jml Anggota</label>
|
||||
<input class="finput" id="f-jml_anggota" type="number" placeholder="4" value="${v('jml_anggota')}"/></div>
|
||||
<div class="fg"><label class="flabel">Jml Lansia</label>
|
||||
<input class="finput" id="f-jml_lansia" type="number" placeholder="0" value="${v('jml_lansia')}"/></div>
|
||||
</div>
|
||||
<div class="fg"><label class="flabel">Alamat</label>
|
||||
<textarea class="finput" id="f-alamat" style="min-height:40px">${v('alamat')}</textarea></div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Penerima Bansos</label>
|
||||
<select class="finput" id="f-bansos">
|
||||
${CFG.warga.bantuan.map(b=>`<option ${v('bansos')===b?'selected':''}>${b}</option>`).join('')}
|
||||
</select></div>
|
||||
<div class="fg"><label class="flabel">Hub Rumah Ibadah</label>
|
||||
<select class="finput" id="f-hub_ri">${hubOpts}</select></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TAB: Ekonomi -->
|
||||
<div class="form-section-panel" id="panel-eko">
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Pendapatan (Rp/Bln)</label>
|
||||
<input class="finput" id="f-pendapatan" type="number" value="${v('pendapatan')}"/></div>
|
||||
<div class="fg"><label class="flabel">Pekerjaan KK</label>
|
||||
<select class="finput" id="f-pekerjaan">
|
||||
${CFG.warga.pekerjaan.map(p=>`<option ${v('pekerjaan')===p?'selected':''}>${p}</option>`).join('')}
|
||||
</select></div>
|
||||
</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Kondisi Rumah</label>
|
||||
<select class="finput" id="f-kondisi_rumah">
|
||||
${CFG.warga.kondisiRumah.map(k=>`<option ${v('kondisi_rumah')===k?'selected':''}>${k}</option>`).join('')}
|
||||
</select></div>
|
||||
<div class="fg"><label class="flabel">Aset (Tanah/Kendaraan)</label>
|
||||
<select class="finput" id="f-kepemilikan_aset">
|
||||
${['Tidak Ada','Motor Tua','Motor Baru','Tanah','Mobil'].map(j=>`<option ${v('kepemilikan_aset')===j?'selected':''}>${j}</option>`).join('')}
|
||||
</select></div>
|
||||
</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Air Bersih</label>
|
||||
<select class="finput" id="f-air_bersih">
|
||||
${['PDAM','Sumur','Sungai/Tadah Hujan'].map(j=>`<option ${v('air_bersih')===j?'selected':''}>${j}</option>`).join('')}
|
||||
</select></div>
|
||||
<div class="fg"><label class="flabel">Listrik</label>
|
||||
<select class="finput" id="f-listrik">
|
||||
${['Sendiri (>900W)','Subsidi (450/900W)','Numpang/Tidak Ada'].map(j=>`<option ${v('listrik')===j?'selected':''}>${j}</option>`).join('')}
|
||||
</select></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TAB: Pendidikan -->
|
||||
<div class="form-section-panel" id="panel-pddk">
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Pendidikan Terakhir KK</label>
|
||||
<select class="finput" id="f-pendidikan_kk">
|
||||
${CFG.warga.tingkatPendidikan.map(j=>`<option ${v('pendidikan_kk')===j?'selected':''}>${j}</option>`).join('')}
|
||||
</select></div>
|
||||
<div class="fg"><label class="flabel">Anak Bersekolah</label>
|
||||
<input class="finput" id="f-jml_anak" type="number" placeholder="1" value="${v('jml_anak')}"/></div>
|
||||
</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Anak Putus Sekolah</label>
|
||||
<input class="finput" id="f-anak_putus_sekolah" type="number" placeholder="0" value="${v('anak_putus_sekolah')}"/></div>
|
||||
<div class="fg"><label class="flabel">Penerima KIP/Beasiswa?</label>
|
||||
<select class="finput" id="f-penerima_beasiswa">
|
||||
${['Ya','Tidak'].map(j=>`<option ${v('penerima_beasiswa')===j?'selected':''}>${j}</option>`).join('')}
|
||||
</select></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TAB: Kesehatan -->
|
||||
<div class="form-section-panel" id="panel-kes">
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Kepesertaan BPJS</label>
|
||||
<select class="finput" id="f-bpjs">
|
||||
${['PBI (Gratis)','Mandiri','Perusahaan','Tidak Punya BPJS'].map(j=>`<option ${v('bpjs')===j?'selected':''}>${j}</option>`).join('')}
|
||||
</select></div>
|
||||
<div class="fg"><label class="flabel">Anggota Difabel/Kronis</label>
|
||||
<input class="finput" id="f-jml_sakit_kronis" type="number" value="${v('jml_sakit_kronis')}"/></div>
|
||||
</div>
|
||||
<div class="fg"><label class="flabel">Jenis Penyakit Khusus</label>
|
||||
<div class="penyakit-grid">
|
||||
${CFG.warga.jenisPenyakit.map(p=>`<label class="penyakit-check ${c(p)}"><input type="checkbox" name="penyakit" value="${p}" ${c(p)}/>${p}</label>`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TAB: Riwayat Bansos -->
|
||||
<div class="form-section-panel" id="panel-hist">
|
||||
<table class="history-table">
|
||||
<thead><tr><th>Program</th><th style="width:60px">Thn</th><th>Status</th><th style="width:28px"></th></tr></thead>
|
||||
<tbody id="hist-tbody">
|
||||
${hist.map(h=>`
|
||||
<tr>
|
||||
<td><input class="finput hist-program" style="padding:3px" value="${H.esc(h.program)}"/></td>
|
||||
<td><input class="finput hist-tahun" style="padding:3px" type="number" value="${h.tahun}"/></td>
|
||||
<td><select class="finput hist-status" style="padding:3px"><option ${h.status==='Aktif'?'selected':''}>Aktif</option><option ${h.status==='Berhenti'?'selected':''}>Berhenti</option></select></td>
|
||||
<td><button class="btn-del-row" type="button" onclick="this.closest('tr').remove()">✕</button></td>
|
||||
</tr>`).join('')}
|
||||
</tbody>
|
||||
</table>
|
||||
<button class="btn-add-row" type="button" id="btn-add-hist">+ Tambah</button>
|
||||
<div class="fg" style="margin-top:10px"><label class="flabel">Catatan / Rekomendasi</label>
|
||||
<textarea class="finput" id="f-catatan" style="min-height:50px">${v('catatan')}</textarea></div>
|
||||
</div>`;
|
||||
},
|
||||
|
||||
rumahIbadah(rec, latlng){
|
||||
const lat=latlng?latlng.lat.toFixed(6):(rec?.lat?.toFixed(6)||'');
|
||||
const lng=latlng?latlng.lng.toFixed(6):(rec?.lng?.toFixed(6)||'');
|
||||
const v=f=>rec?H.esc(rec[f]||''):'';
|
||||
return `
|
||||
<div class="info-box">📍 Koordinat: <strong>${lat}, ${lng}</strong></div>
|
||||
<div class="form-sect">Identitas Rumah Ibadah</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Nama Rumah Ibadah<span class="req">*</span></label>
|
||||
<input class="finput" id="f-nama" placeholder="cth: Masjid Al-Ikhlas" value="${v('nama')}"/></div>
|
||||
<div class="fg"><label class="flabel">Jenis<span class="req">*</span></label>
|
||||
<select class="finput" id="f-jenis">
|
||||
${CFG.rumahIbadah.jenis.map(j=>`<option ${v('jenis')===j?'selected':''}>${j}</option>`).join('')}
|
||||
</select></div>
|
||||
</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Nama Ketua / Imam / Pastor</label>
|
||||
<input class="finput" id="f-ketua" placeholder="Nama lengkap" value="${v('ketua')}"/></div>
|
||||
<div class="fg"><label class="flabel">No. WhatsApp Pengurus</label>
|
||||
<input class="finput" id="f-wa" placeholder="081..." value="${v('wa')}"/></div>
|
||||
</div>
|
||||
<div class="form-sect">Kapasitas & Jangkauan</div>
|
||||
<div class="form-row cols3">
|
||||
<div class="fg"><label class="flabel">Kapasitas Jamaah</label>
|
||||
<input class="finput" id="f-kapasitas" type="number" placeholder="200" value="${v('kapasitas')}"/></div>
|
||||
<div class="fg"><label class="flabel">Radius Wilayah Binaan (m)</label>
|
||||
<input class="finput" id="f-radius" type="number" placeholder="300" value="${v('radius')||300}"/></div>
|
||||
<div class="fg"><label class="flabel">Jml Warga Binaan</label>
|
||||
<input class="finput" id="f-jml_binaan" type="number" placeholder="150" value="${v('jml_binaan')}"/></div>
|
||||
</div>
|
||||
<div class="form-sect">Program Sosial</div>
|
||||
<div class="form-row cols2">
|
||||
<div class="fg"><label class="flabel">Program Aktif</label>
|
||||
<select class="finput" id="f-program">
|
||||
${['Baznas/Zakat','Bantuan Sembako','Santunan Anak Yatim','Pemberdayaan UMKM','Beasiswa','Belum Ada'].map(k=>`<option ${v('program')===k?'selected':''}>${k}</option>`).join('')}
|
||||
</select></div>
|
||||
<div class="fg"><label class="flabel">Dana Sosial/Bulan (Rp)</label>
|
||||
<input class="finput" id="f-dana_sosial" type="number" placeholder="2000000" value="${v('dana_sosial')}"/></div>
|
||||
</div>
|
||||
<div class="fg"><label class="flabel">Catatan / Kebutuhan Dukungan</label>
|
||||
<textarea class="finput" id="f-catatan" placeholder="Kebutuhan data, pelatihan, dll...">${v('catatan')}</textarea></div>`;
|
||||
},
|
||||
|
||||
readAll(ln){
|
||||
const g = id => document.getElementById(id)?.value?.trim();
|
||||
if(ln==='spbu'){
|
||||
const nm=g('f-nama'); if(!nm){Toast.error('Nama SPBU wajib diisi!');return null;}
|
||||
const buka=document.querySelector('input[name="buka24"]:checked')?.value!=='false';
|
||||
return {nama:nm,wa:g('f-wa'),buka24:buka,jenis_bbm:g('f-jenis_bbm'),disabilitas:g('f-disabilitas'),harga_bbm:g('f-harga_bbm'),catatan:g('f-catatan')};
|
||||
}
|
||||
if(ln==='jalan'){
|
||||
const nm=g('f-nama'); if(!nm){Toast.error('Nama jalan wajib diisi!');return null;}
|
||||
return {nama:nm,status:g('f-status'),panjang:parseFloat(g('f-panjang'))||0,kondisi:g('f-kondisi'),tahun_perbaikan:g('f-tahun_perbaikan'),lebar:g('f-lebar'),angkutan:g('f-angkutan'),akses_publik:g('f-akses_publik'),catatan:g('f-catatan')};
|
||||
}
|
||||
if(ln==='parsil'){
|
||||
const nm=g('f-nama'); if(!nm){Toast.error('Nama parsil wajib diisi!');return null;}
|
||||
return {nama:nm,status:g('f-status'),luas:parseFloat(g('f-luas'))||0,nib:g('f-nib'),sengketa:g('f-sengketa'),njop:g('f-njop'),penggunaan:g('f-penggunaan'),catatan:g('f-catatan')};
|
||||
}
|
||||
if(ln==='warga'){
|
||||
const nm=g('f-nama'); if(!nm){Toast.error('Nama KK wajib diisi!');return null;}
|
||||
const penyakit=[...document.querySelectorAll('input[name="penyakit"]:checked')].map(el=>el.value);
|
||||
const history_bansos=[];
|
||||
document.querySelectorAll('#hist-tbody tr').forEach(tr=>{
|
||||
const prog=tr.querySelector('.hist-program')?.value?.trim();
|
||||
const thn=tr.querySelector('.hist-tahun')?.value?.trim();
|
||||
const sts=tr.querySelector('.hist-status')?.value;
|
||||
if(prog) history_bansos.push({program:prog,tahun:parseInt(thn)||new Date().getFullYear(),status:sts});
|
||||
});
|
||||
return {
|
||||
nama: nm, nik: g('f-nik'), no_kk: g('f-no_kk'), wa: g('f-wa'), tingkat_kemiskinan: g('f-tingkat_kemiskinan'),
|
||||
jml_anggota: parseInt(g('f-jml_anggota'))||0, jml_lansia: parseInt(g('f-jml_lansia'))||0,
|
||||
alamat: g('f-alamat'), bansos: g('f-bansos'), hub_ri: g('f-hub_ri'),
|
||||
pendapatan: g('f-pendapatan'), pekerjaan: g('f-pekerjaan'),
|
||||
kondisi_rumah: g('f-kondisi_rumah'), kepemilikan_aset: g('f-kepemilikan_aset'),
|
||||
air_bersih: g('f-air_bersih'), listrik: g('f-listrik'),
|
||||
pendidikan_kk: g('f-pendidikan_kk'), jml_anak: parseInt(g('f-jml_anak'))||0,
|
||||
anak_putus_sekolah: parseInt(g('f-anak_putus_sekolah'))||0, penerima_beasiswa: g('f-penerima_beasiswa'),
|
||||
bpjs: g('f-bpjs'), jml_sakit_kronis: parseInt(g('f-jml_sakit_kronis'))||0,
|
||||
penyakit, history_bansos, catatan: g('f-catatan'),
|
||||
};
|
||||
}
|
||||
if(ln==='rumahIbadah'){
|
||||
const nm=g('f-nama'); if(!nm){Toast.error('Nama Rumah Ibadah wajib diisi!');return null;}
|
||||
return {
|
||||
nama: nm, jenis: g('f-jenis'), ketua: g('f-ketua'), wa: g('f-wa'),
|
||||
kapasitas: parseInt(g('f-kapasitas'))||0, radius: parseFloat(g('f-radius'))||300,
|
||||
jml_binaan: parseInt(g('f-jml_binaan'))||0, program: g('f-program'),
|
||||
dana_sosial: g('f-dana_sosial'), catatan: g('f-catatan')
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
/* ═══════════════════════════════════════════════════════════
|
||||
10. LEGEND
|
||||
═══════════════════════════════════════════════════════════ */
|
||||
function renderLegend(ln){
|
||||
const el=document.getElementById('legend-items');
|
||||
const rows=CFG[ln].legend||[];
|
||||
el.innerHTML=rows.map(r=>{
|
||||
let sym='';
|
||||
if(r.sym==='c') sym=`<span class="leg-c" style="background:${r.clr}"></span>`;
|
||||
else if(r.sym==='l') sym=`<span class="leg-l" style="background:${r.clr}"></span>`;
|
||||
else sym=`<span class="leg-p" style="border-color:${r.clr};background:${r.clr}33"></span>`;
|
||||
return `<div class="legend-row">${sym}<span>${r.l}</span></div>`;
|
||||
}).join('');
|
||||
// Add radius note for rumahIbadah and bansos
|
||||
if(ln==='rumahIbadah'||ln==='warga'){
|
||||
el.innerHTML+=`<div class="legend-radius"><span class="leg-radius-sym"></span>Radius Hub 300m</div>`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/* ═══════════════════════════════════════════════════════════
|
||||
6. POPUP BUILDERS
|
||||
═══════════════════════════════════════════════════════════ */
|
||||
const Popup = {
|
||||
_row:(k,v)=>`<div class="popup-row"><span class="popup-k">${k}</span><span class="popup-v">${H.esc(v||'-')}</span></div>`,
|
||||
_sect:t=>`<div class="popup-section">${t}</div>`,
|
||||
_acts:(ln,id)=>`<div class="popup-acts"><button class="bsm bsm-edit" onclick="App.crud.edit('${ln}','${id}')">Edit</button><button class="bsm bsm-del" onclick="App.crud.delete('${ln}','${id}')">Hapus</button></div>`,
|
||||
|
||||
spbu(r){ const cfg=CFG.spbu,clr=cfg.color(r),bdg=cfg.badge(r);
|
||||
return `<div class="popup-wrap"><div class="popup-title"><span class="popup-sym" style="background:${clr}"></span>${H.esc(r.nama)}</div>
|
||||
<span class="badge ${bdg.c}">${bdg.t}</span>
|
||||
${this._sect('Operasional')}
|
||||
${this._row('No. WA',r.wa)}${this._row('Jenis BBM',r.jenis_bbm)}${this._row('Harga BBM',r.harga_bbm)}${this._row('Akses Disabilitas',r.disabilitas)}
|
||||
${r.catatan?this._row('Catatan',r.catatan):''}
|
||||
${this._acts('spbu',r.id)}</div>`; },
|
||||
|
||||
jalan(r){ const cfg=CFG.jalan,bdg=cfg.badge(r);
|
||||
return `<div class="popup-wrap"><div class="popup-title">🛣️ ${H.esc(r.nama)}</div>
|
||||
<span class="badge ${bdg.c}">${bdg.t}</span>
|
||||
${this._sect('Spesifikasi')}
|
||||
${this._row('Panjang',H.fmDist(r.panjang))}${this._row('Lebar',r.lebar?(r.lebar+' m'):'-')}${this._row('Kondisi',r.kondisi)}${this._row('Perbaikan Terakhir',r.tahun_perbaikan||'-')}
|
||||
${this._sect('Dampak Sosial')}
|
||||
${this._row('Angkutan Umum',r.angkutan)}${this._row('Akses ke',r.akses_publik)}
|
||||
${r.catatan?this._row('Catatan',r.catatan):''}
|
||||
${this._acts('jalan',r.id)}</div>`; },
|
||||
|
||||
parsil(r){ const cfg=CFG.parsil,bdg=cfg.badge(r);
|
||||
return `<div class="popup-wrap"><div class="popup-title">🏗️ ${H.esc(r.nama)}</div>
|
||||
<span class="badge ${bdg.c}">${bdg.t}</span>
|
||||
${this._sect('Data Hukum')}
|
||||
${this._row('NIB',r.nib||'-')}${this._row('Status Sengketa',r.sengketa)}${this._row('Penggunaan',r.penggunaan)}
|
||||
${this._sect('Penilaian')}
|
||||
${this._row('Luas',H.fmArea(r.luas))}${this._row('NJOP/m²',r.njop?'Rp '+parseInt(r.njop).toLocaleString('id-ID'):'-')}
|
||||
${r.catatan?this._row('Catatan',r.catatan):''}
|
||||
${this._acts('parsil',r.id)}</div>`; },
|
||||
|
||||
warga(r){ const cfg=CFG.warga,clr=cfg.color(r),bdg=cfg.badge(r);
|
||||
const ri=Store.all('rumahIbadah');
|
||||
let nearestRI=null, nearestDist=Infinity;
|
||||
ri.forEach(hub=>{
|
||||
if(hub.lat==null||r.lat==null) return;
|
||||
const d=L.latLng(r.lat,r.lng).distanceTo(L.latLng(hub.lat,hub.lng));
|
||||
if(d<nearestDist){nearestDist=d;nearestRI=hub;}
|
||||
});
|
||||
const radius=nearestRI?(parseFloat(nearestRI.radius)||300):300;
|
||||
const covered=nearestRI&&nearestDist<=radius;
|
||||
const coverageHtml=nearestRI
|
||||
?`<div class="coverage-badge ${covered?'covered':'uncovered'}">
|
||||
<svg viewBox="0 0 24 24"><path d="${covered?'M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z':'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'}"/></svg>
|
||||
${covered?'Terjangkau Hub: '+H.esc(nearestRI.nama)+' ('+Math.round(nearestDist)+' m)':'Tidak Terjangkau ('+Math.round(nearestDist)+' m dari RI)'}
|
||||
</div>`
|
||||
:'<div class="coverage-badge uncovered">Belum ada Rumah Ibadah Hub</div>';
|
||||
const histHtml=r.history_bansos?.length
|
||||
?r.history_bansos.map(h=>`<div style="font-size:10px;padding:3px 0;border-bottom:1px solid var(--border0);display:flex;justify-content:space-between"><span>${H.esc(h.program)} (${h.tahun||'-'})</span><span class="status-${(h.status||'').toLowerCase().replace(' ','')}" style="font-weight:700">${H.esc(h.status)}</span></div>`).join('')
|
||||
:'<div style="font-size:10px;color:var(--text4)">Belum ada riwayat bansos</div>';
|
||||
return `<div class="popup-wrap"><div class="popup-title"><span class="popup-sym" style="background:${clr}"></span>${H.esc(r.nama)}</div>
|
||||
<span class="badge ${bdg.c}">${bdg.t}</span>
|
||||
${coverageHtml}
|
||||
${this._sect('Data Keluarga')}
|
||||
${this._row('NIK',r.nik||'-')}${this._row('No. KK',r.no_kk||'-')}${this._row('Jml Anggota',r.jml_anggota+' jiwa')}
|
||||
${this._sect('Ekonomi')}
|
||||
${this._row('Pekerjaan KK',r.pekerjaan)}${this._row('Pendapatan/Bln',r.pendapatan?'Rp '+parseInt(r.pendapatan).toLocaleString('id-ID'):'-')}${this._row('Kondisi Rumah',r.kondisi_rumah)}
|
||||
${this._sect('Fasilitas')}
|
||||
${this._row('Air Bersih',r.air_bersih)}${this._row('Listrik',r.listrik)}
|
||||
${this._sect('Bansos')}
|
||||
${this._row('Bansos Saat Ini',r.bansos)}${this._row('Hub RI',r.hub_ri||'-')}
|
||||
<div style="margin-top:2px">${histHtml}</div>
|
||||
${r.catatan?this._row('Rekomendasi',r.catatan):''}
|
||||
${this._acts('warga',r.id)}</div>`; },
|
||||
|
||||
rumahIbadah(r){ const cfg=CFG.rumahIbadah,clr=cfg.color(r),bdg=cfg.badge(r);
|
||||
return `<div class="popup-wrap"><div class="popup-title"><span class="popup-sym" style="background:${clr}"></span>${H.esc(r.nama)}</div>
|
||||
<span class="badge ${bdg.c}">${bdg.t}</span>
|
||||
${this._sect('Kontak')}
|
||||
${this._row('Ketua/Imam',r.ketua||'-')}${this._row('No. WA',r.wa||'-')}
|
||||
${this._sect('Kapasitas & Binaan')}
|
||||
${this._row('Kapasitas',r.kapasitas?r.kapasitas+' orang':'-')}${this._row('Radius Binaan',(r.radius||300)+' m')}${this._row('Warga Binaan',r.jml_binaan?r.jml_binaan+' KK':'-')}
|
||||
${this._sect('Program Sosial')}
|
||||
${this._row('Program Aktif',r.program)}${this._row('Dana Sosial/Bln',r.dana_sosial?'Rp '+parseInt(r.dana_sosial).toLocaleString('id-ID'):'-')}
|
||||
${r.catatan?this._row('Catatan',r.catatan):''}
|
||||
${this._acts('rumahIbadah',r.id)}</div>`; },
|
||||
};
|
||||
Reference in New Issue
Block a user