Files
database-pertani-web/resources/views/ekosistem/lahan-cpcl/edit.blade.php
T
2026-05-06 15:53:59 +07:00

448 lines
21 KiB
PHP

@extends('layout.main')
@push('style')
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css" />
<style>
#map {
height: 600px;
width: 100%;
background-color: #f8f9fa;
z-index: 1;
}
</style>
@endpush
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4 d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">Edit Data Lahan</h5>
<a href="{{ route('lahan-cpcl.index') }}" class="btn btn-sm btn-label-secondary">
<i class="ti tabler-arrow-left me-1"></i> Kembali
</a>
</div>
<div class="card-body">
<form id="formLahanCPCL" action="{{ route('lahan-cpcl.update', $lahan->id) }}" method="POST">
@csrf
@method('PUT')
<div class="row">
<div class="col-lg-6 mb-4">
<h6 class="mb-3 text-primary"><i class="ti tabler-info-circle me-1"></i> Form Info Lahan</h6>
<div class="mb-3">
<label class="form-label">Nama Lahan <span class="text-danger">*</span></label>
<input type="text" name="nama" class="form-control" value="{{ old('nama', $lahan->nama) }}" placeholder="Masukkan nama lahan" required />
</div>
<div class="mb-3">
<label class="form-label">Pemilik Pemilik<span class="text-danger">*</span></label>
<input type="text" name="nama_pemilik" class="form-control" value="{{ old('nama_pemilik', $lahan->nama_pemilik) }}" placeholder="Masukkan nama pemilik" required />
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Status Kepemilikan <span class="text-danger">*</span></label>
<select name="status_kepemilikan" id="status_kepemilikan" class="form-select" required>
<option value="">Pilih Status</option>
@php $status = old('status_kepemilikan', $lahan->status_kepemilikan->value); @endphp
@foreach(App\Enums\StatusLahan::cases() as $lahanEnum)
<option value="{{ $lahanEnum->value }}" {{ old('status_kepemilikan') == $lahanEnum->value ? 'selected' : '' }}>
{{ ucfirst($lahanEnum->value) }}
</option>
@endforeach
</select>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Luas Lahan (Ha/m2) <span class="text-danger">*</span></label>
<input type="number" step="0.01" name="luas_lahan" class="form-control" value="{{ old('luas_lahan', $lahan->luas_lahan) }}" placeholder="Contoh: 1.5" required />
</div>
</div>
<hr class="my-4">
<h6 class="mb-3 text-primary"><i class="ti tabler-map-pin me-1"></i> Lokasi Wilayah</h6>
@php
$selectedDesa = $lahan->desakelurahan ?? null;
$selectedKec = $selectedDesa ? $selectedDesa->kecamatan : null;
$selectedKab = $selectedKec ? $selectedKec->kabupatenkota : null;
$selectedProv = $selectedKab ? $selectedKab->provinsi : null;
@endphp
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Provinsi <span class="text-danger">*</span></label>
<select name="provinsi_id" id="provinsi_id" class="form-select" required>
<option value="" data-path="">Pilih Provinsi</option>
@foreach($provinsi as $prov)
<option value="{{ $prov->id }}" data-path="{{ is_string($prov->path) ? $prov->path : json_encode($prov->path) }}" {{ ($selectedProv && $selectedProv->id == $prov->id) ? 'selected' : '' }}>
{{ $prov->nama }}
</option>
@endforeach
</select>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Kabupaten/Kota <span class="text-danger">*</span></label>
<select name="kabupatenkota_id" id="kabupatenkota_id" class="form-select" required>
<option value="" data-path="">Pilih Kabupaten/Kota</option>
@if($selectedKab)
<option value="{{ $selectedKab->id }}" selected data-path="{{ is_string($selectedKab->path) ? $selectedKab->path : json_encode($selectedKab->path) }}">{{ $selectedKab->nama }}</option>
@endif
</select>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Kecamatan <span class="text-danger">*</span></label>
<select name="kecamatan_id" id="kecamatan_id" class="form-select" required>
<option value="" data-path="">Pilih Kecamatan</option>
@if($selectedKec)
<option value="{{ $selectedKec->id }}" selected data-path="{{ is_string($selectedKec->path) ? $selectedKec->path : json_encode($selectedKec->path) }}">{{ $selectedKec->nama }}</option>
@endif
</select>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Desa/Kelurahan <span class="text-danger">*</span></label>
<select name="desa_kelurahan_id" id="desa_kelurahan_id" class="form-select" required>
<option value="" data-path="">Pilih Desa/Kelurahan</option>
@if($selectedDesa)
<option value="{{ $selectedDesa->id }}" selected data-path="{{ is_string($selectedDesa->path) ? $selectedDesa->path : json_encode($selectedDesa->path) }}">{{ $selectedDesa->nama }}</option>
@endif
</select>
</div>
</div>
<div class="mt-4">
<label class="form-label">Raw Data Koordinat Lahan (Auto-generated JSON) <span class="text-danger">*</span></label>
<textarea name="path" id="path" class="form-control bg-lighter font-monospace" rows="4" readonly required placeholder="Koordinat akan terisi otomatis setelah Anda menggambar polygon di peta...">{{ old('path', is_string($lahan->path) ? $lahan->path : json_encode($lahan->path)) }}</textarea>
<small class="text-muted">Gunakan tombol edit (pensil) atau hapus (tong sampah) di peta untuk mengubah bentuk lahan.</small>
</div>
</div>
<div class="col-lg-6 mb-4">
<div class="d-flex justify-content-between align-items-center mb-3">
<h6 class="text-primary mb-0"><i class="ti tabler-map me-1"></i> Gambar Area Lahan</h6>
<span class="badge bg-label-warning">Mode Edit Polygon Aktif</span>
</div>
<div id="map" class="border rounded shadow-sm"></div>
</div>
</div>
<div class="row mt-3">
<div class="col-12 text-end">
<a href="{{ route('lahan.index') }}" class="btn btn-label-secondary me-2">Batal</a>
<button type="submit" class="btn btn-primary"><i class="ti tabler-device-floppy me-2"></i> Update Data</button>
</div>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
let map = L.map('map').setView([-0.789275, 113.921327], 5);
L.tileLayer('http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}', {
maxZoom: 22,
subdomains: ['mt0', 'mt1', 'mt2', 'mt3'],
attribution: '&copy; Google Maps Satellite'
}).addTo(map);
let regionBoundaryLayer = L.featureGroup().addTo(map);
function focusToRegionBoundary(selectElement, shouldZoom = true) {
regionBoundaryLayer.clearLayers();
let selectedOption = selectElement.options[selectElement.selectedIndex];
if (!selectedOption || !selectedOption.hasAttribute('data-path')) return;
let pathStr = selectedOption.getAttribute('data-path');
if (!pathStr || pathStr === "null" || pathStr === "") return;
try {
let rawData = typeof pathStr === 'string' ? JSON.parse(pathStr) : pathStr;
if (Array.isArray(rawData) && rawData.length > 0) {
function formatCoordinates(coords) {
if (coords.length === 2 && typeof coords[0] === 'number') {
return [coords[0], coords[1]];
}
return coords.map(formatCoordinates);
}
let latLngs = formatCoordinates(rawData);
let polygon = L.polygon(latLngs, {
color: '#ffc107',
fillColor: '#ffc107',
fillOpacity: 0.15,
weight: 3,
dashArray: '8, 6',
interactive: false
});
regionBoundaryLayer.addLayer(polygon);
if (shouldZoom) map.fitBounds(polygon.getBounds(), { padding: [20, 20] });
}
} catch (error) {
console.error("Format JSON path wilayah tidak valid:", error);
}
}
let drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
let drawControl = new L.Control.Draw({
draw: {
polygon: {
allowIntersection: false,
showArea: true,
shapeOptions: { color: '#28c76f', fillColor: '#28c76f', fillOpacity: 0.4, weight: 3 }
},
polyline: false, circle: false, rectangle: false, marker: false, circlemarker: false
},
edit: {
featureGroup: drawnItems,
remove: true
}
});
map.addControl(drawControl);
let rawLahanPath = document.getElementById('path').value;
if (rawLahanPath) {
try {
let parsedPath = JSON.parse(rawLahanPath);
if (Array.isArray(parsedPath) && parsedPath.length > 0) {
let existingLatLngs = parsedPath.map(function(coord) {
return [coord[1], coord[0]];
});
let existingPolygon = L.polygon(existingLatLngs, {
color: '#28c76f', fillColor: '#28c76f', fillOpacity: 0.4, weight: 3
});
drawnItems.addLayer(existingPolygon);
setTimeout(() => { map.fitBounds(existingPolygon.getBounds(), { padding: [30, 30] }); }, 500);
}
} catch (e) {
console.error("Gagal merender polygon lahan eksisting: ", e);
}
}
map.on(L.Draw.Event.CREATED, function (e) {
let layer = e.layer;
drawnItems.clearLayers();
drawnItems.addLayer(layer);
updatePathTextarea(layer);
});
map.on(L.Draw.Event.EDITED, function (e) {
e.layers.eachLayer(function (layer) {
updatePathTextarea(layer);
});
});
map.on(L.Draw.Event.DELETED, function () {
document.getElementById('path').value = '';
let luasInput = document.querySelector('input[name="luas_lahan"]');
if (luasInput) luasInput.value = '';
});
function updatePathTextarea(layer) {
let latlngs = layer.getLatLngs()[0];
let pathData = latlngs.map(function(latlng) {
return [latlng.lng, latlng.lat];
});
document.getElementById('path').value = JSON.stringify(pathData);
let areaSquareMeters = L.GeometryUtil.geodesicArea(latlngs);
let areaHectares = areaSquareMeters / 10000;
let luasInput = document.querySelector('input[name="luas_lahan"]');
if (luasInput) {
luasInput.value = areaHectares.toFixed(2);
luasInput.style.transition = "background-color 0.5s ease";
luasInput.style.backgroundColor = "#e8fdf0";
setTimeout(() => {
luasInput.style.backgroundColor = "";
}, 1500);
}
}
const provSelect = document.getElementById('provinsi_id');
const kabSelect = document.getElementById('kabupatenkota_id');
const kecSelect = document.getElementById('kecamatan_id');
const desaSelect = document.getElementById('desa_kelurahan_id');
if (desaSelect.value) focusToRegionBoundary(desaSelect, false);
else if (provSelect.value) focusToRegionBoundary(provSelect, false);
function resetDropdown(element, defaultText) {
element.innerHTML = `<option value="" data-path="">${defaultText}</option>`;
element.disabled = true;
}
provSelect.addEventListener('change', function() {
let provId = this.value;
focusToRegionBoundary(this);
resetDropdown(kabSelect, 'Pilih Kabupaten/Kota');
resetDropdown(kecSelect, 'Pilih Kecamatan');
resetDropdown(desaSelect, 'Pilih Desa/Kelurahan');
if (provId) {
kabSelect.innerHTML = '<option value="" data-path="">Memuat...</option>';
fetch(`{{ url('kabupatenkotabyprovinsi') }}/${provId}`)
.then(response => response.json())
.then(data => {
resetDropdown(kabSelect, 'Pilih Kabupaten/Kota');
kabSelect.disabled = false;
data.forEach(item => {
let option = new Option(item.nama, item.id);
if(item.path) {
option.setAttribute('data-path', typeof item.path === 'string' ? item.path : JSON.stringify(item.path));
}
kabSelect.add(option);
});
})
.catch(error => console.error('Error fetching Kabupaten:', error));
}
});
kabSelect.addEventListener('change', function() {
let kabId = this.value;
focusToRegionBoundary(this);
resetDropdown(kecSelect, 'Pilih Kecamatan');
resetDropdown(desaSelect, 'Pilih Desa/Kelurahan');
if (kabId) {
kecSelect.innerHTML = '<option value="" data-path="">Memuat...</option>';
fetch(`{{ url('kecamatanbykabupatenkota') }}/${kabId}`)
.then(response => response.json())
.then(data => {
resetDropdown(kecSelect, 'Pilih Kecamatan');
kecSelect.disabled = false;
data.forEach(item => {
let option = new Option(item.nama, item.id);
if(item.path) {
option.setAttribute('data-path', typeof item.path === 'string' ? item.path : JSON.stringify(item.path));
}
kecSelect.add(option);
});
})
.catch(error => console.error('Error fetching Kecamatan:', error));
}
});
kecSelect.addEventListener('change', function() {
let kecId = this.value;
focusToRegionBoundary(this);
resetDropdown(desaSelect, 'Pilih Desa/Kelurahan');
if (kecId) {
desaSelect.innerHTML = '<option value="" data-path="">Memuat...</option>';
fetch(`{{ url('desakelurahanbykecamatan') }}/${kecId}`)
.then(response => response.json())
.then(data => {
resetDropdown(desaSelect, 'Pilih Desa/Kelurahan');
desaSelect.disabled = false;
data.forEach(item => {
let option = new Option(item.nama, item.id);
if(item.path) {
option.setAttribute('data-path', typeof item.path === 'string' ? item.path : JSON.stringify(item.path));
}
desaSelect.add(option);
});
})
.catch(error => console.error('Error fetching Desa:', error));
}
});
desaSelect.addEventListener('change', function() {
focusToRegionBoundary(this);
});
const formLahanCPCL = document.getElementById('formLahanCPCL');
if(formLahanCPCL) {
formLahanCPCL.addEventListener('submit', function(e) {
e.preventDefault();
let form = this;
let formData = new FormData(form);
let submitBtn = form.querySelector('button[type="submit"]');
let originalBtnText = submitBtn.innerHTML;
submitBtn.disabled = true;
submitBtn.innerHTML = 'Menyimpan...';
fetch(form.action, {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Accept': 'application/json'
}
})
.then(response => response.json())
.then(data => {
submitBtn.disabled = false;
submitBtn.innerHTML = originalBtnText;
if (data.status === 'success') {
Swal.fire({
icon: 'success',
title: 'Berhasil!',
text: data.message,
showConfirmButton: false,
timer: 2000
}).then(() => {
window.location.href = "{{ route('lahan-cpcl.index') }}";
});
} else {
let errorMsg = data.message || 'Terjadi kesalahan saat menyimpan data.';
if (data.errors) {
errorMsg = Object.values(data.errors).map(err => err.join(', ')).join('<br>');
}
Swal.fire({
icon: 'error',
title: 'Gagal Menyimpan!',
html: errorMsg
});
}
})
.catch(error => {
submitBtn.disabled = false;
submitBtn.innerHTML = originalBtnText;
Swal.fire({
icon: 'error',
title: 'Error Sistem',
text: 'Terjadi kesalahan pada server atau koneksi internet.'
});
console.error('Error:', error);
});
});
}
});
</script>
@endpush