Harden Project 01 public endpoints
This commit is contained in:
+36
-19
@@ -74,14 +74,18 @@
|
||||
return `
|
||||
<div class="info-popup">
|
||||
<div class="info-popup-header">
|
||||
<div class="info-popup-icon" style="background:${color}22;">🏘️</div>
|
||||
<div class="info-popup-icon" style="background:${color}22;">
|
||||
<i data-lucide="pentagon" style="color:${color};width:18px;height:18px;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="info-popup-name">${escapeHTML(row.nama_parsil)}</div>
|
||||
<div class="info-popup-id">#${row.id}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-row-icon">📜</div>
|
||||
<div class="info-row-icon">
|
||||
<i data-lucide="file-text" style="width:14px;height:14px;color:var(--text-m)"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="info-row-label">Status Kepemilikan</div>
|
||||
<div class="info-row-value">
|
||||
@@ -93,13 +97,15 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-row-icon">📐</div>
|
||||
<div class="info-row-icon">
|
||||
<i data-lucide="maximize-2" style="width:14px;height:14px;color:var(--text-m)"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="info-row-label">Luas Tanah</div>
|
||||
<div class="info-row-value" style="font-family:var(--font-mono);">${luas}</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn-hapus" onclick="window._parsilHapus(${row.id}, this)">🗑 Hapus Parsil</button>
|
||||
${window._IS_ADMIN ? `<button class="btn-hapus" onclick="window._parsilHapus(${row.id}, this)"><i data-lucide="trash-2" style="width:13px;height:13px;margin-right:4px;"></i> Hapus Parsil</button>` : ''}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -113,7 +119,7 @@
|
||||
.then(r => r.json())
|
||||
.then(j => {
|
||||
if (j.status !== 'success') throw new Error(j.message);
|
||||
updateCount(j.total, '🏘️');
|
||||
updateCount(j.total, 'Parsil');
|
||||
j.data.forEach(addPolygonToMap);
|
||||
refreshParsilList(j.data);
|
||||
})
|
||||
@@ -138,10 +144,11 @@
|
||||
showDeleteConfirm('Yakin ingin menghapus data parsil tanah ini?').then(confirmed => {
|
||||
if (!confirmed) return;
|
||||
btnEl.disabled = true;
|
||||
btnEl.textContent = '⏳ Menghapus...';
|
||||
btnEl.innerHTML = '<span class="btn-spinner" style="margin-right: 6px; display: inline-block; vertical-align: middle;"></span> Menghapus...';
|
||||
|
||||
const fd = new FormData();
|
||||
fd.append('id', id);
|
||||
fd.append('csrf_token', window._CSRF_TOKEN || '');
|
||||
|
||||
fetch('api/parsil/hapus.php', { method: 'POST', body: fd })
|
||||
.then(r => r.json())
|
||||
@@ -149,7 +156,7 @@
|
||||
if (j.status === 'success') {
|
||||
map.closePopup();
|
||||
if (allLayers[id]) { layerGroup.removeLayer(allLayers[id]); delete allLayers[id]; }
|
||||
updateCount(Object.keys(allLayers).length, '🏘️');
|
||||
updateCount(Object.keys(allLayers).length, 'Parsil');
|
||||
const remaining = Object.values(allLayers).map(l => ({
|
||||
id: l._parsilId, name: l._parsilNama,
|
||||
badge: l._parsilStatus,
|
||||
@@ -163,7 +170,8 @@
|
||||
.catch(err => {
|
||||
showToast(err.message || 'Gagal menghapus.', 'error');
|
||||
btnEl.disabled = false;
|
||||
btnEl.textContent = '🗑 Hapus Parsil';
|
||||
btnEl.innerHTML = '<i data-lucide="trash-2" style="width:13px;height:13px;margin-right:4px;"></i> Hapus Parsil';
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -197,14 +205,17 @@
|
||||
drawingMarkers.forEach(m => map.removeLayer(m));
|
||||
drawingMarkers = [];
|
||||
|
||||
if (save && drawingPoints.length >= 3) {
|
||||
const shouldSave = save && drawingPoints.length >= 3;
|
||||
if (shouldSave) {
|
||||
showFormParsil(drawingPoints.slice());
|
||||
} else if (save && drawingPoints.length < 3) {
|
||||
showToast('Minimal 3 titik untuk membuat parsil (Polygon)', 'error');
|
||||
}
|
||||
drawingPoints = [];
|
||||
|
||||
if (typeof window._resetActiveTool === 'function') window._resetActiveTool();
|
||||
if (!shouldSave) {
|
||||
if (typeof window._resetActiveTool === 'function') window._resetActiveTool();
|
||||
}
|
||||
}
|
||||
|
||||
function finishDrawing() {
|
||||
@@ -217,6 +228,7 @@
|
||||
}
|
||||
|
||||
function onMapClick(e) {
|
||||
console.log("parsil.js onMapClick: currentMode =", (typeof currentMode !== "undefined" ? currentMode : "undefined"), ", currentSubMode =", (typeof currentSubMode !== "undefined" ? currentSubMode : "undefined"), ", isDrawing =", isDrawing);
|
||||
if (currentMode !== 2 || currentSubMode !== 'parsil') return;
|
||||
if (!isDrawing) return;
|
||||
|
||||
@@ -330,7 +342,7 @@
|
||||
.setContent(`
|
||||
<div class="form-popup">
|
||||
<div class="form-popup-header">
|
||||
<div class="form-popup-icon amber">🏘️</div>
|
||||
<div class="form-popup-icon amber"><i data-lucide="pentagon" style="width:18px;height:18px;"></i></div>
|
||||
<div>
|
||||
<div class="form-popup-title">Tambah Data Parsil (Kavling)</div>
|
||||
<div class="form-popup-coords">${points.length} titik · Luas : ${luasStr} m²</div>
|
||||
@@ -355,7 +367,7 @@
|
||||
</div>
|
||||
<input type="hidden" id="fp_geojson" value='${escapeHTML(geojson)}'>
|
||||
<input type="hidden" id="fp_luas" value="${luasArea}">
|
||||
<button class="btn-save" id="btnSimpanParsil" style="background:var(--c-warn);color:#111" onclick="window._parsilSimpan()">💾 Simpan Parsil</button>
|
||||
<button class="btn-save" id="btnSimpanParsil" onclick="window._parsilSimpan()"><i data-lucide="save" style="width:14px;height:14px;margin-right:4px;"></i> Simpan Parsil</button>
|
||||
<div class="form-status" id="parsilStatus"></div>
|
||||
</div>
|
||||
`)
|
||||
@@ -363,9 +375,11 @@
|
||||
|
||||
setTimeout(() => { const el = document.getElementById('fp_nama'); if (el) el.focus(); }, 200);
|
||||
|
||||
// Kalau popup ditutup tanpa simpan: hapus preview
|
||||
// Reset active tool when popup is closed (either by saving or clicking close/outside)
|
||||
map.once('popupclose', () => {
|
||||
// preview sudah di-clear di stopDrawing
|
||||
if (typeof window._resetActiveTool === 'function') {
|
||||
window._resetActiveTool();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -379,20 +393,22 @@
|
||||
const btn = document.getElementById('btnSimpanParsil');
|
||||
|
||||
if (!nama) {
|
||||
statusEl.textContent = '⚠ Nama parsil wajib diisi.';
|
||||
statusEl.innerHTML = '<i data-lucide="alert-triangle" style="width:14px;height:14px;margin-right:4px;display:inline-block;vertical-align:middle;"></i> Nama parsil wajib diisi.';
|
||||
statusEl.className = 'form-status error';
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
document.getElementById('fp_nama').focus();
|
||||
return;
|
||||
}
|
||||
|
||||
btn.disabled = true;
|
||||
btn.textContent = '⏳ Menyimpan...';
|
||||
btn.innerHTML = '<span class="btn-spinner" style="margin-right: 6px; display: inline-block; vertical-align: middle;"></span> Menyimpan...';
|
||||
|
||||
const fd = new FormData();
|
||||
fd.append('nama_parsil', nama);
|
||||
fd.append('status_kepemilikan', status);
|
||||
fd.append('geojson', geojson);
|
||||
fd.append('luas_m2', luas);
|
||||
fd.append('csrf_token', window._CSRF_TOKEN || '');
|
||||
|
||||
fetch('api/parsil/simpan.php', { method: 'POST', body: fd })
|
||||
.then(r => r.json())
|
||||
@@ -400,7 +416,7 @@
|
||||
if (j.status === 'success') {
|
||||
map.closePopup();
|
||||
addPolygonToMap(j.data);
|
||||
updateCount(Object.keys(allLayers).length, '🏘️');
|
||||
updateCount(Object.keys(allLayers).length, 'Parsil');
|
||||
const allItems = Object.values(allLayers).map(l => ({
|
||||
id: l._parsilId, name: l._parsilNama,
|
||||
badge: l._parsilStatus,
|
||||
@@ -412,10 +428,11 @@
|
||||
} else throw new Error(j.message);
|
||||
})
|
||||
.catch(err => {
|
||||
statusEl.textContent = '✕ ' + err.message;
|
||||
statusEl.innerHTML = '<i data-lucide="x-circle" style="width:14px;height:14px;margin-right:4px;display:inline-block;vertical-align:middle;"></i> ' + escapeHTML(err.message);
|
||||
statusEl.className = 'form-status error';
|
||||
btn.disabled = false;
|
||||
btn.textContent = '💾 Simpan Parsil';
|
||||
btn.innerHTML = '<i data-lucide="save" style="width:14px;height:14px;margin-right:4px;"></i> Simpan Parsil';
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user