Merge branch 'main' of https://git.probindo.com/Probindo/database-pertani-web
This commit is contained in:
@@ -2011,7 +2011,11 @@
|
||||
series: data.series,
|
||||
colors: colors,
|
||||
stroke: { width: 0 },
|
||||
dataLabels: { enabled: false },
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
style: { colors: colors.map(config.chartTextColor) },
|
||||
dropShadow: { enabled: false },
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
position: 'bottom',
|
||||
@@ -2051,7 +2055,7 @@
|
||||
<div
|
||||
style="
|
||||
background: ${color};
|
||||
color: #fff;
|
||||
color: ${config.chartTextColor(color)};
|
||||
padding: 8px 12px;
|
||||
border-radius: 5px;
|
||||
font-size: 13px;
|
||||
|
||||
@@ -1713,6 +1713,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const totalPetani = lakiLaki + perempuan;
|
||||
|
||||
if (genderChartEl) {
|
||||
const genderColors = [pastelSemantic.info || '#5FC7D6', pastelSemantic.pink || '#F47C86'];
|
||||
const genderChartConfig = {
|
||||
chart: {
|
||||
height: 365,
|
||||
@@ -1732,7 +1733,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
},
|
||||
labels: ['Laki-laki', 'Perempuan'],
|
||||
series: [lakiLaki, perempuan],
|
||||
colors: [pastelSemantic.info || '#5FC7D6', pastelSemantic.pink || '#F47C86'],
|
||||
colors: genderColors,
|
||||
stroke: { width: 0 },
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
@@ -1748,15 +1749,9 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
fontSize: '13px',
|
||||
fontFamily: fontFamily,
|
||||
fontWeight: 600,
|
||||
colors: ['#fff']
|
||||
colors: genderColors.map(config.chartTextColor)
|
||||
},
|
||||
dropShadow: {
|
||||
enabled: true,
|
||||
top: 1,
|
||||
left: 1,
|
||||
blur: 2,
|
||||
opacity: 0.45
|
||||
}
|
||||
dropShadow: { enabled: false }
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
@@ -2120,6 +2115,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const farmerGroupFilters = ['terdaftar', 'tidak_terdaftar', 'belum_terisi'];
|
||||
const totalFarmerGroup = farmerGroupData.reduce((total, value) => total + value, 0);
|
||||
|
||||
const farmerGroupColors = [pastelSemantic.success || '#6FD68F', pastelSemantic.warning || '#FFB46F', pastelSemantic.secondary || '#9EA6B0'];
|
||||
const farmerGroupChartConfig = {
|
||||
chart: {
|
||||
height: 365,
|
||||
@@ -2139,7 +2135,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
},
|
||||
labels: ['Terdaftar', 'Tidak Terdaftar', 'Belum Terisi'],
|
||||
series: farmerGroupData,
|
||||
colors: [pastelSemantic.success || '#6FD68F', pastelSemantic.warning || '#FFB46F', pastelSemantic.secondary || '#9EA6B0'],
|
||||
colors: farmerGroupColors,
|
||||
stroke: { width: 0 },
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
@@ -2155,15 +2151,9 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
fontSize: '13px',
|
||||
fontFamily: fontFamily,
|
||||
fontWeight: 600,
|
||||
colors: ['#fff']
|
||||
colors: farmerGroupColors.map(config.chartTextColor)
|
||||
},
|
||||
dropShadow: {
|
||||
enabled: true,
|
||||
top: 1,
|
||||
left: 1,
|
||||
blur: 2,
|
||||
opacity: 0.45
|
||||
}
|
||||
dropShadow: { enabled: false }
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
@@ -2219,6 +2209,14 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const commoditySeries = @json($data['komoditas_utama']['series'] ?? []);
|
||||
const totalCommodityFarmers = commoditySeries.reduce((total, value) => total + Number(value), 0);
|
||||
|
||||
const commodityColors = [
|
||||
pastelSemantic.primary || '#9D8EF0',
|
||||
pastelSemantic.warning || '#FFB46F',
|
||||
pastelSemantic.success || '#6FD68F',
|
||||
pastelSemantic.info || '#5FC7D6',
|
||||
pastelSemantic.danger || '#F47C86',
|
||||
pastelSemantic.secondary || '#9EA6B0'
|
||||
];
|
||||
const commodityChartConfig = {
|
||||
chart: {
|
||||
height: 365,
|
||||
@@ -2237,14 +2235,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
},
|
||||
labels: commodityLabels,
|
||||
series: commoditySeries.map(Number),
|
||||
colors: [
|
||||
pastelSemantic.primary || '#9D8EF0',
|
||||
pastelSemantic.warning || '#FFB46F',
|
||||
pastelSemantic.success || '#6FD68F',
|
||||
pastelSemantic.info || '#5FC7D6',
|
||||
pastelSemantic.danger || '#F47C86',
|
||||
pastelSemantic.secondary || '#9EA6B0'
|
||||
],
|
||||
colors: commodityColors,
|
||||
stroke: { width: 0 },
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
@@ -2260,15 +2251,9 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
fontSize: '13px',
|
||||
fontFamily: fontFamily,
|
||||
fontWeight: 600,
|
||||
colors: ['#fff']
|
||||
colors: commodityColors.map(config.chartTextColor)
|
||||
},
|
||||
dropShadow: {
|
||||
enabled: true,
|
||||
top: 1,
|
||||
left: 1,
|
||||
blur: 2,
|
||||
opacity: 0.45
|
||||
}
|
||||
dropShadow: { enabled: false }
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
@@ -2293,7 +2278,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const percentage = totalCommodityFarmers > 0 ? ((value / totalCommodityFarmers) * 100).toFixed(1) : '0.0';
|
||||
const color = w.globals.colors[seriesIndex];
|
||||
return `
|
||||
<div style="background:${color}; color:${headingColor}; padding:8px 12px; border-radius:5px; font-size:13px; font-weight:500; font-family:${fontFamily}; box-shadow:0 4px 12px rgba(0,0,0,.15);">
|
||||
<div style="background:${color}; color:${config.chartTextColor(color)}; padding:8px 12px; border-radius:5px; font-size:13px; font-weight:500; font-family:${fontFamily}; box-shadow:0 4px 12px rgba(0,0,0,.15);">
|
||||
${label}: <strong>${value} petani (${percentage}%)</strong>
|
||||
</div>
|
||||
`;
|
||||
@@ -2433,6 +2418,12 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const landOwnershipStatusSeries = (@json($data['status_kepemilikan_lahan']['series'] ?? [])).map(Number);
|
||||
const totalLandOwnershipStatusFarmers = landOwnershipStatusSeries.reduce((total, value) => total + value, 0);
|
||||
|
||||
const landOwnershipStatusColors = [
|
||||
pastelSemantic.success || '#6FD68F',
|
||||
pastelSemantic.warning || '#FFB46F',
|
||||
pastelSemantic.info || '#5FC7D6',
|
||||
pastelSemantic.secondary || '#9EA6B0'
|
||||
];
|
||||
const landOwnershipStatusChartConfig = {
|
||||
chart: {
|
||||
height: 365,
|
||||
@@ -2452,12 +2443,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
},
|
||||
labels: landOwnershipStatusLabels,
|
||||
series: landOwnershipStatusSeries,
|
||||
colors: [
|
||||
pastelSemantic.success || '#6FD68F',
|
||||
pastelSemantic.warning || '#FFB46F',
|
||||
pastelSemantic.info || '#5FC7D6',
|
||||
pastelSemantic.secondary || '#9EA6B0'
|
||||
],
|
||||
colors: landOwnershipStatusColors,
|
||||
stroke: { width: 0 },
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
@@ -2473,15 +2459,9 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
fontSize: '13px',
|
||||
fontFamily: fontFamily,
|
||||
fontWeight: 600,
|
||||
colors: ['#fff']
|
||||
colors: landOwnershipStatusColors.map(config.chartTextColor)
|
||||
},
|
||||
dropShadow: {
|
||||
enabled: true,
|
||||
top: 1,
|
||||
left: 1,
|
||||
blur: 2,
|
||||
opacity: 0.45
|
||||
}
|
||||
dropShadow: { enabled: false }
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
@@ -2918,6 +2898,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
style: { colors: segmentPalette.map(config.chartTextColor) },
|
||||
dropShadow: { enabled: false },
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
|
||||
@@ -758,7 +758,7 @@
|
||||
<div class="card-body d-flex justify-content-between align-items-center gap-3">
|
||||
<div>
|
||||
<h5>Peta Sebaran</h5>
|
||||
<p class="text-body-secondary mb-0">Lahan, tanaman, dan OPT berdasarkan filter wilayah.</p>
|
||||
<p class="text-body-secondary mb-0">Lahan, tanaman, OPT, dan praktik budidaya berdasarkan filter wilayah.</p>
|
||||
</div>
|
||||
<span class="btn btn-icon btn-label-secondary btn-sm chart-group-icon-toggle" aria-hidden="true">
|
||||
<i class="icon-base ti tabler-chevron-down"></i>
|
||||
@@ -773,8 +773,8 @@
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap mb-2">
|
||||
<div>
|
||||
<h6 class="mb-0">Peta Sebaran Lahan & Tanaman</h6>
|
||||
<small class="text-body-secondary">Lahan dan tanaman berdasarkan filter wilayah, komoditas, dan segmen</small>
|
||||
<h6 class="mb-0">Peta Sebaran Lahan, Tanaman & Praktik Budidaya</h6>
|
||||
<small class="text-body-secondary">Lahan, tanaman, OPT, pemangkasan, pemupukan, dan praktik baik berdasarkan filter wilayah, komoditas, dan segmen</small>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button type="button" class="btn btn-outline-secondary active produksi-map-layer-btn" data-map-layer="satellite">Satellite</button>
|
||||
@@ -795,34 +795,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card h-100 produksi-chart-card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap mb-2">
|
||||
<div>
|
||||
<h6 class="mb-0">Peta Praktik Budidaya</h6>
|
||||
<small class="text-body-secondary">Intensitas pemangkasan, pemupukan, dan kebiasaan praktik baik</small>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button type="button" class="btn btn-outline-secondary active produksi-cultivation-map-layer-btn" data-map-layer="satellite">Satellite</button>
|
||||
<button type="button" class="btn btn-outline-secondary produksi-cultivation-map-layer-btn" data-map-layer="topo">Topographic</button>
|
||||
<button type="button" class="btn btn-outline-secondary produksi-cultivation-map-layer-btn" data-map-layer="parcels">Parcels</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="produksi-budidaya-map" class="produksi-map">
|
||||
<button type="button" id="produksi-budidaya-map-back" class="btn btn-sm btn-dark shadow produksi-map-back">
|
||||
<i class="icon-base ti tabler-arrow-left me-1"></i>
|
||||
Kembali ke Atas
|
||||
</button>
|
||||
<div id="produksi-budidaya-map-empty" class="produksi-map-empty">Belum ada poligon lahan untuk filter ini.</div>
|
||||
<div class="produksi-map-information-overlay" tabindex="0" role="region" aria-label="Informasi peta praktik budidaya">
|
||||
<div class="produksi-map-information" id="produksi-budidaya-map-information"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1044,8 +1016,8 @@
|
||||
<div class="card h-100 produksi-chart-card">
|
||||
<div class="card-header d-flex align-items-start justify-content-between gap-2">
|
||||
<div class="card-title mb-0">
|
||||
<h5 class="m-0 me-2">Praktik Fermentasi atau Pengolahan Pascapanen</h5>
|
||||
<small class="text-body-secondary">Apakah sudah ada praktik fermentasi atau pengolahan pascapanen yang dilakukan</small>
|
||||
<h5 class="m-0 me-2">Praktik Fermentasi atau Pengolahan Pascapanen per Komoditas</h5>
|
||||
<small class="text-body-secondary">Jumlah petani per komoditas berdasarkan praktik fermentasi atau pengolahan pascapanen.</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@@ -1079,11 +1051,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const mapData = @json($mapData);
|
||||
const dashboardFilters = @json($dashboardFilters);
|
||||
const mapInformationUrl = @json(route('dashboard.produktivitas.map-information'));
|
||||
const initialMapInformation = mapData.information || {};
|
||||
const mapInformation = {
|
||||
production: { ...initialMapInformation },
|
||||
cultivation: { ...initialMapInformation },
|
||||
};
|
||||
const mapInformation = { ...(mapData.information || {}) };
|
||||
const wilayah = @json($wilayah);
|
||||
const headingColor = config.colors.headingColor;
|
||||
const legendColor = config.colors.bodyColor;
|
||||
@@ -1094,9 +1062,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const labelColor = legendColor;
|
||||
const borderColor = pastelChart.grid || 'rgba(128, 128, 128, .18)';
|
||||
let productionMapRendered = false;
|
||||
let cultivationMapRendered = false;
|
||||
let actualProductivityRendered = false;
|
||||
const mapInformationRequestIds = { production: 0, cultivation: 0 };
|
||||
let mapInformationRequestId = 0;
|
||||
|
||||
function hasData(data) {
|
||||
return data && Array.isArray(data.series) && data.series.some(function (value) {
|
||||
@@ -1114,7 +1081,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
});
|
||||
}
|
||||
|
||||
function renderProductionMapInformation(elementId, information, includeOpt = true) {
|
||||
function renderProductionMapInformation(elementId, information) {
|
||||
const element = document.getElementById(elementId);
|
||||
|
||||
if (!element) return;
|
||||
@@ -1193,17 +1160,15 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
<span class="produksi-map-information-section-title">Jumlah Petani / Komoditas</span>
|
||||
<div class="produksi-map-information-bars">${renderBars(commodityRows, 'Belum ada data komoditas.', 'petani')}</div>
|
||||
</section>
|
||||
${includeOpt ? `
|
||||
<section>
|
||||
<span class="produksi-map-information-section-title">OPT (Organisme Pengganggu Tanaman)</span>
|
||||
<div class="produksi-map-information-bars">${renderBars(optRows, 'Belum ada data OPT.', 'lahan')}</div>
|
||||
</section>
|
||||
` : ''}
|
||||
<section>
|
||||
<span class="produksi-map-information-section-title">OPT (Organisme Pengganggu Tanaman)</span>
|
||||
<div class="produksi-map-information-bars">${renderBars(optRows, 'Belum ada data OPT.', 'lahan')}</div>
|
||||
</section>
|
||||
`;
|
||||
}
|
||||
|
||||
async function loadProductionMapInformation(mapType, level = null, id = null) {
|
||||
const requestId = ++mapInformationRequestIds[mapType];
|
||||
async function loadProductionMapInformation(level = null, id = null) {
|
||||
const requestId = ++mapInformationRequestId;
|
||||
const params = new URLSearchParams();
|
||||
|
||||
Object.entries(dashboardFilters || {}).forEach(function ([key, value]) {
|
||||
@@ -1225,14 +1190,10 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
if (!response.ok) return;
|
||||
|
||||
const information = await response.json();
|
||||
if (requestId !== mapInformationRequestIds[mapType]) return;
|
||||
if (requestId !== mapInformationRequestId) return;
|
||||
|
||||
Object.assign(mapInformation[mapType], information);
|
||||
if (mapType === 'production') {
|
||||
renderProductionMapInformation('produksi-map-information', mapInformation.production);
|
||||
} else {
|
||||
renderProductionMapInformation('produksi-budidaya-map-information', mapInformation.cultivation, false);
|
||||
}
|
||||
Object.assign(mapInformation, information);
|
||||
renderProductionMapInformation('produksi-map-information', mapInformation);
|
||||
} catch (error) {
|
||||
console.error('Gagal memuat informasi wilayah pada peta.', error);
|
||||
}
|
||||
@@ -1290,13 +1251,13 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function produksiChartTooltip(color, label, value, unit = '', total = null, digits = 0) {
|
||||
function produksiChartTooltip(color, label, value, unit = '', total = null, digits = 0, textColor = headingColor) {
|
||||
const numericValue = Number(value || 0);
|
||||
const unitText = unit ? ` ${escapeHtml(unit)}` : '';
|
||||
const percentageText = total === null ? '' : ` (${chartPercentage(numericValue, total)}%)`;
|
||||
|
||||
return `
|
||||
<div class="produksi-apex-tooltip" style="background:${escapeHtml(color)}; color:${escapeHtml(headingColor)}; font-family:${fontFamily};">
|
||||
<div class="produksi-apex-tooltip" style="background:${escapeHtml(color)}; color:${escapeHtml(textColor)}; font-family:${fontFamily};">
|
||||
${escapeHtml(label)}: <strong>${formatNumber(numericValue, digits)}${unitText}${percentageText}</strong>
|
||||
</div>
|
||||
`;
|
||||
@@ -1425,6 +1386,9 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const opt = Array.isArray(item.opt) && item.opt.length
|
||||
? item.opt.map(value => `<span class="produksi-opt-chip">${escapeHtml(value)}</span>`).join('')
|
||||
: '<span class="text-body-secondary small">Belum ada data OPT</span>';
|
||||
const praktikBaik = Array.isArray(item.praktik_baik) && item.praktik_baik.length
|
||||
? item.praktik_baik.map(value => `<li>${escapeHtml(value)}</li>`).join('')
|
||||
: '<li>Belum ada data praktik baik</li>';
|
||||
|
||||
return `
|
||||
<div class="produksi-lahan-popup">
|
||||
@@ -1449,6 +1413,19 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
<span class="produksi-popup-label">OPT</span>
|
||||
<div class="produksi-opt-list">${opt}</div>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<span class="produksi-popup-label">Praktik Budidaya</span>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<span class="produksi-popup-label">Intensitas Pemangkasan</span>
|
||||
<span class="produksi-popup-value">${escapeHtml(item.pemangkasan || 'Belum ada data')}</span>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<span class="produksi-popup-label">Intensitas Pemupukan</span>
|
||||
<span class="produksi-popup-value">${escapeHtml(item.pemupukan || 'Belum ada data')}</span>
|
||||
</div>
|
||||
<span class="produksi-popup-label">Kebiasaan praktik baik</span>
|
||||
<ul class="produksi-praktik-list">${praktikBaik}</ul>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -1513,7 +1490,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
renderProductionMapLevel(previous.level, previous.parentId);
|
||||
productionMapState.informationLevel = previous.informationLevel;
|
||||
productionMapState.informationId = previous.informationId;
|
||||
loadProductionMapInformation('production', previous.informationLevel, previous.informationId);
|
||||
loadProductionMapInformation(previous.informationLevel, previous.informationId);
|
||||
|
||||
if (previous.bounds?.isValid()) {
|
||||
productionMapState.map.fitBounds(previous.bounds, { padding: [30, 30] });
|
||||
@@ -1585,7 +1562,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
layer.bindPopup(landPopup(item), {
|
||||
className: 'produksi-map-popup',
|
||||
closeButton: true,
|
||||
maxWidth: 320,
|
||||
maxWidth: 340,
|
||||
maxHeight: 360,
|
||||
});
|
||||
} else {
|
||||
layer.bindTooltip(regionTooltip(item), {
|
||||
@@ -1606,7 +1584,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
});
|
||||
productionMapState.informationLevel = nextLevel;
|
||||
productionMapState.informationId = item.id;
|
||||
loadProductionMapInformation('production', nextLevel, item.id);
|
||||
loadProductionMapInformation(nextLevel, item.id);
|
||||
renderProductionMapLevel(nextProductionMapLevel(nextLevel), item.id, event.target.getBounds());
|
||||
});
|
||||
}
|
||||
@@ -1641,234 +1619,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}, 150);
|
||||
}
|
||||
|
||||
function initialCultivationMapLevel() {
|
||||
const levels = mapData.cultivationLevels || {};
|
||||
const filters = mapData.filters || {};
|
||||
|
||||
if (filters.desa && (levels.desa || []).length) return 'desa';
|
||||
if (filters.kecamatan && (levels.kecamatan || []).length) return 'kecamatan';
|
||||
if (filters.kabupaten && (levels.kabupaten || []).length) return 'kabupaten';
|
||||
if ((levels.kabupaten || []).length) return 'kabupaten';
|
||||
if ((levels.kecamatan || []).length) return 'kecamatan';
|
||||
if ((levels.desa || []).length) return 'desa';
|
||||
if ((levels.provinsi || []).length) return 'provinsi';
|
||||
|
||||
return 'lahan';
|
||||
}
|
||||
|
||||
function cultivationPopup(item) {
|
||||
const praktikBaik = Array.isArray(item.praktik_baik) && item.praktik_baik.length
|
||||
? item.praktik_baik.map(value => `<li>${escapeHtml(value)}</li>`).join('')
|
||||
: '<li>Belum ada data praktik baik</li>';
|
||||
|
||||
return `
|
||||
<div class="produksi-lahan-popup">
|
||||
<div class="produksi-lahan-popup-header">
|
||||
<span class="produksi-popup-label">Pemilik Lahan</span>
|
||||
<h6>${escapeHtml(item.nama_petani || 'N/A')}</h6>
|
||||
</div>
|
||||
<div class="produksi-lahan-popup-body">
|
||||
<div class="row g-2 mb-3">
|
||||
<div class="col-6">
|
||||
<span class="produksi-popup-label">Luas Lahan</span>
|
||||
<span class="produksi-popup-value">${formatNumber(item.luas || 0, 2)} Ha</span>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<span class="produksi-popup-label">ID Lahan</span>
|
||||
<span class="produksi-popup-value">TR-${escapeHtml(item.id)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<span class="produksi-popup-label">Intensitas Pemangkasan</span>
|
||||
<span class="produksi-popup-value">${escapeHtml(item.pemangkasan || 'Belum ada data')}</span>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<span class="produksi-popup-label">Intensitas Pemupukan</span>
|
||||
<span class="produksi-popup-value">${escapeHtml(item.pemupukan || 'Belum ada data')}</span>
|
||||
</div>
|
||||
<span class="produksi-popup-label">Kebiasaan praktik baik</span>
|
||||
<ul class="produksi-praktik-list">${praktikBaik}</ul>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
const cultivationMapState = {
|
||||
activeLayer: 'satellite',
|
||||
backButton: null,
|
||||
empty: null,
|
||||
group: null,
|
||||
history: [],
|
||||
informationId: null,
|
||||
informationLevel: null,
|
||||
layers: {},
|
||||
map: null,
|
||||
};
|
||||
|
||||
function initCultivationMap() {
|
||||
const element = document.getElementById('produksi-budidaya-map');
|
||||
|
||||
if (!element || typeof L === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cultivationMapState.map) {
|
||||
return true;
|
||||
}
|
||||
|
||||
cultivationMapState.layers = {
|
||||
satellite: L.tileLayer('https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}', { maxZoom: 22 }),
|
||||
topo: L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png'),
|
||||
parcels: L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png'),
|
||||
};
|
||||
cultivationMapState.map = L.map('produksi-budidaya-map', {
|
||||
center: [-8.67, 121.0],
|
||||
zoom: 10,
|
||||
layers: [cultivationMapState.layers.satellite],
|
||||
zoomControl: false,
|
||||
});
|
||||
cultivationMapState.group = L.featureGroup().addTo(cultivationMapState.map);
|
||||
cultivationMapState.backButton = document.getElementById('produksi-budidaya-map-back');
|
||||
cultivationMapState.empty = document.getElementById('produksi-budidaya-map-empty');
|
||||
enableMapInformationInteraction(element);
|
||||
|
||||
L.control.zoom({ position: 'topleft' }).addTo(cultivationMapState.map);
|
||||
|
||||
cultivationMapState.backButton?.addEventListener('click', function () {
|
||||
const previous = cultivationMapState.history.pop();
|
||||
|
||||
if (previous) {
|
||||
renderCultivationMapLevel(previous.level, previous.parentId);
|
||||
cultivationMapState.informationLevel = previous.informationLevel;
|
||||
cultivationMapState.informationId = previous.informationId;
|
||||
loadProductionMapInformation('cultivation', previous.informationLevel, previous.informationId);
|
||||
|
||||
if (previous.bounds?.isValid()) {
|
||||
cultivationMapState.map.fitBounds(previous.bounds, { padding: [30, 30] });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function setCultivationMapLayer(type, button) {
|
||||
if (!cultivationMapState.map || !cultivationMapState.layers[type]) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object.values(cultivationMapState.layers).forEach(function (layer) {
|
||||
cultivationMapState.map.removeLayer(layer);
|
||||
});
|
||||
cultivationMapState.layers[type].addTo(cultivationMapState.map);
|
||||
cultivationMapState.activeLayer = type;
|
||||
|
||||
document.querySelectorAll('.produksi-cultivation-map-layer-btn').forEach(function (item) {
|
||||
item.classList.toggle('active', item === button);
|
||||
});
|
||||
}
|
||||
|
||||
function renderCultivationMapLevel(level = null, parentId = null, fallbackBounds = null) {
|
||||
if (!initCultivationMap()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const levels = mapData.cultivationLevels || {};
|
||||
const nextLevel = level || initialCultivationMapLevel();
|
||||
let dataToRender = levels[nextLevel] || [];
|
||||
|
||||
if (parentId !== null) {
|
||||
dataToRender = dataToRender.filter(item => String(item.parent_id) === String(parentId));
|
||||
}
|
||||
|
||||
cultivationMapState.group.clearLayers();
|
||||
|
||||
if (nextLevel === 'lahan' && parentId !== null) {
|
||||
const parentDesa = (levels.desa || []).find(item => String(item.id) === String(parentId));
|
||||
const desaLayer = parentDesa
|
||||
? makeLayerFromPolygon(parentDesa.polygon, {
|
||||
color: '#F47C86',
|
||||
dashArray: '5, 8',
|
||||
fillOpacity: 0,
|
||||
interactive: false,
|
||||
weight: 2,
|
||||
})
|
||||
: null;
|
||||
|
||||
if (desaLayer) {
|
||||
cultivationMapState.group.addLayer(desaLayer);
|
||||
}
|
||||
}
|
||||
|
||||
dataToRender.forEach(function (item) {
|
||||
const layer = makeLayerFromPolygon(item.polygon, nextLevel === 'lahan'
|
||||
? { color: '#5FC7D6', fillColor: '#5FC7D6', fillOpacity: .58, weight: 2 }
|
||||
: { color: '#9D8EF0', fillColor: '#9D8EF0', fillOpacity: .3, weight: 2 });
|
||||
|
||||
if (!layer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextLevel === 'lahan') {
|
||||
layer.bindPopup(cultivationPopup(item), {
|
||||
className: 'produksi-map-popup',
|
||||
closeButton: true,
|
||||
maxWidth: 340,
|
||||
});
|
||||
} else {
|
||||
layer.bindTooltip(regionTooltip(item), {
|
||||
className: 'produksi-map-tooltip',
|
||||
direction: 'top',
|
||||
offset: [0, -10],
|
||||
sticky: true,
|
||||
});
|
||||
|
||||
layer.on('click', function (event) {
|
||||
L.DomEvent.stopPropagation(event);
|
||||
cultivationMapState.history.push({
|
||||
level: nextLevel,
|
||||
parentId,
|
||||
bounds: cultivationMapState.group.getBounds(),
|
||||
informationLevel: cultivationMapState.informationLevel,
|
||||
informationId: cultivationMapState.informationId,
|
||||
});
|
||||
cultivationMapState.informationLevel = nextLevel;
|
||||
cultivationMapState.informationId = item.id;
|
||||
loadProductionMapInformation('cultivation', nextLevel, item.id);
|
||||
renderCultivationMapLevel(nextProductionMapLevel(nextLevel), item.id, event.target.getBounds());
|
||||
});
|
||||
}
|
||||
|
||||
cultivationMapState.group.addLayer(layer);
|
||||
});
|
||||
|
||||
if (cultivationMapState.backButton) {
|
||||
cultivationMapState.backButton.style.display = cultivationMapState.history.length > 0 ? 'block' : 'none';
|
||||
}
|
||||
|
||||
const layersCount = cultivationMapState.group.getLayers().length;
|
||||
|
||||
if (cultivationMapState.empty) {
|
||||
cultivationMapState.empty.style.display = layersCount > 0 ? 'none' : 'flex';
|
||||
}
|
||||
|
||||
if (layersCount > 0) {
|
||||
const bounds = cultivationMapState.group.getBounds();
|
||||
|
||||
if (bounds.isValid()) {
|
||||
cultivationMapState.map.fitBounds(bounds, { padding: [30, 30], maxZoom: 18 });
|
||||
}
|
||||
} else if (fallbackBounds?.isValid()) {
|
||||
cultivationMapState.map.fitBounds(fallbackBounds, { padding: [30, 30], maxZoom: 18 });
|
||||
} else {
|
||||
cultivationMapState.map.setView([-8.67, 121.0], 10);
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
cultivationMapState.map.invalidateSize();
|
||||
}, 150);
|
||||
}
|
||||
|
||||
function renderDonut(selector, data, options = {}) {
|
||||
const element = document.querySelector(selector);
|
||||
if (!element) return;
|
||||
@@ -1886,6 +1636,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
stroke: { width: 0 },
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
dropShadow: { enabled: false },
|
||||
formatter: function (value) {
|
||||
return value.toFixed(0) + '%';
|
||||
},
|
||||
@@ -1893,7 +1644,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
fontSize: '13px',
|
||||
fontFamily: fontFamily,
|
||||
fontWeight: 600,
|
||||
colors: ['#fff'],
|
||||
colors: chartColors.map(config.chartTextColor),
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
@@ -1915,7 +1666,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const label = w.globals.labels[seriesIndex] || 'Data';
|
||||
const color = w.globals.colors?.[seriesIndex] || chartColors[seriesIndex % chartColors.length] || '#9D8EF0';
|
||||
|
||||
return produksiChartTooltip(color, label, value, options.unit || 'data', total);
|
||||
return produksiChartTooltip(color, label, value, options.unit || 'data', total, 0, config.chartTextColor(color));
|
||||
},
|
||||
},
|
||||
plotOptions: {
|
||||
@@ -1992,6 +1743,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
legend: { show: false },
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
dropShadow: { enabled: false },
|
||||
formatter: function (value) {
|
||||
return value >= 8 ? value.toFixed(0) + '%' : '';
|
||||
},
|
||||
@@ -1999,7 +1751,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
fontSize: '11px',
|
||||
fontFamily: fontFamily,
|
||||
fontWeight: 600,
|
||||
colors: ['#fff'],
|
||||
colors: colors.map(config.chartTextColor),
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
@@ -2008,7 +1760,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const label = w.globals.labels[seriesIndex] || 'Data';
|
||||
const color = w.globals.colors?.[seriesIndex] || colors[seriesIndex % colors.length] || '#9D8EF0';
|
||||
|
||||
return produksiChartTooltip(color, label, value, options.unit || 'data', total);
|
||||
return produksiChartTooltip(color, label, value, options.unit || 'data', total, 0, config.chartTextColor(color));
|
||||
},
|
||||
},
|
||||
plotOptions: { pie: { expandOnClick: true } },
|
||||
@@ -2231,7 +1983,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
renderGroupedBar('#chart-sumber-air-kebun', chartData.sumberAirKebun, { unit: 'petani', yTitle: 'Jumlah Petani', height: 330 });
|
||||
renderGroupedBar('#chart-kebiasaan-praktik-baik', chartData.kebiasaanPraktikBaik, { unit: 'petani', yTitle: 'Jumlah Petani', height: 330 });
|
||||
renderPieWithLegend('#chart-praktik-sortasi-panen', chartData.praktikSortasiPanen, { unit: 'petani' });
|
||||
renderBar('#chart-praktik-fermentasi-pascapanen', chartData.praktikFermentasiPascapanen, { height: 330, color: pastelSemantic.primary || '#9D8EF0', unit: 'petani' });
|
||||
renderGroupedBar('#chart-praktik-fermentasi-pascapanen', chartData.praktikFermentasiPascapanen, { unit: 'petani', yTitle: 'Jumlah Petani', height: 330 });
|
||||
renderActualProductivityIfVisible();
|
||||
}
|
||||
|
||||
@@ -2261,37 +2013,15 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
productionMapRendered = true;
|
||||
}
|
||||
|
||||
function renderCultivationMapIfOpen() {
|
||||
if (!document.getElementById('peta-sebaran-panel')?.classList.contains('show')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cultivationMapRendered) {
|
||||
renderCultivationMapLevel();
|
||||
cultivationMapRendered = true;
|
||||
return;
|
||||
}
|
||||
|
||||
cultivationMapState.map?.invalidateSize();
|
||||
cultivationMapRendered = true;
|
||||
}
|
||||
|
||||
renderProductionMapInformation('produksi-map-information', mapInformation.production);
|
||||
renderProductionMapInformation('produksi-budidaya-map-information', mapInformation.cultivation, false);
|
||||
renderProductionMapInformation('produksi-map-information', mapInformation);
|
||||
|
||||
if (typeof L === 'undefined') {
|
||||
const mapEmpty = document.getElementById('produksi-map-empty');
|
||||
const cultivationMapEmpty = document.getElementById('produksi-budidaya-map-empty');
|
||||
|
||||
if (mapEmpty) {
|
||||
mapEmpty.textContent = 'Leaflet belum dimuat.';
|
||||
mapEmpty.style.display = 'flex';
|
||||
}
|
||||
|
||||
if (cultivationMapEmpty) {
|
||||
cultivationMapEmpty.textContent = 'Leaflet belum dimuat.';
|
||||
cultivationMapEmpty.style.display = 'flex';
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelectorAll('.produksi-map-layer-btn').forEach(function (button) {
|
||||
@@ -2300,12 +2030,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.produksi-cultivation-map-layer-btn').forEach(function (button) {
|
||||
button.addEventListener('click', function () {
|
||||
setCultivationMapLayer(button.dataset.mapLayer, button);
|
||||
});
|
||||
});
|
||||
|
||||
$('#filter-provinsi, #filter-kabkota, #filter-kecamatan, #filter-desa, #filter-komoditas, #filter-segmen').select2({ width: '100%' });
|
||||
|
||||
$('#filter-provinsi').on('change', function () {
|
||||
@@ -2388,7 +2112,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
if (panel.id === 'peta-sebaran-panel' && typeof L !== 'undefined') {
|
||||
renderProductionMapIfOpen();
|
||||
renderCultivationMapIfOpen();
|
||||
}
|
||||
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
|
||||
@@ -90,6 +90,6 @@
|
||||
|
||||
<script src="{{ asset('assets/vendor/js/template-customizer.js') }}"></script>
|
||||
|
||||
<script src="{{ asset('assets/js/config.js') }}"></script>
|
||||
<script src="{{ asset('assets/js/config.js') }}?v={{ filemtime(public_path('assets/js/config.js')) }}"></script>
|
||||
@stack('scripts-head')
|
||||
</head>
|
||||
@@ -234,7 +234,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
|
||||
<button type="submit" class="btn btn-success data-submit wave-effect wave-light"><i class="ti tabler-device-floppy me-2"></i> Simpan Profil</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -365,6 +365,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-device-floppy me-1_5 icon-sm"></i>Simpan Akses Pasar
|
||||
</button>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
@push('scripts')
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/croppie/2.6.5/croppie.min.js"></script>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
@@ -43,13 +44,18 @@
|
||||
<div class="col-md-3">
|
||||
<div class="user-avatar-section">
|
||||
<div class=" d-flex align-items-center flex-column">
|
||||
<img id="fotoPreview"
|
||||
class="mb-3 shadow-sm rounded-3"
|
||||
<button type="button" class="border-0 bg-transparent p-0 mb-3 rounded-3"
|
||||
data-bs-toggle="modal" data-bs-target="#fotoProfilModal"
|
||||
aria-label="Lihat foto profil petani" title="Lihat foto profil petani">
|
||||
<img id="fotoPreview"
|
||||
class="shadow-sm rounded-3"
|
||||
src="{{ $petani->foto ? route('petani.show-image', ['id' => $petani->id, 'field' => 'foto']) : asset('assets/img/avatars/3.jpg') }}"
|
||||
alt="Foto profil petani"
|
||||
data-bs-toggle="tooltip" data-bs-placement="top"
|
||||
data-bs-original-title="Klik untuk mengganti foto profil petani"
|
||||
style="width: 120px !important; height: 120px !important; cursor:pointer; object-fit:cover; display:block; margin: 0 auto;" />
|
||||
</button>
|
||||
<button type="button" id="btnGantiFoto" class="btn btn-sm btn-outline-primary mb-3">
|
||||
Ganti Foto
|
||||
</button>
|
||||
|
||||
<button type="button" id="btnHapusFoto" class="btn btn-sm btn-outline-danger mb-4" style="display: {{ $petani->foto ? 'block' : 'none' }};">
|
||||
Hapus Foto
|
||||
@@ -113,7 +119,7 @@
|
||||
<select class="form-control @error('pendidikan_terakhir') is-invalid @enderror" id="edit-petani-pendidikan-terakhir" name="pendidikan_terakhir">
|
||||
<option value="">Pilih Pendidikan Terakhir</option>
|
||||
@foreach($pendidikan as $value)
|
||||
<option value="{{ $value['value'] }}" {{ old('pendidikan_terakhir', $petani->pendidikan_terakhir->value) == $value['value'] ? 'selected' : '' }}>{{ $value['label'] }}</option>
|
||||
<option value="{{ $value['value'] }}" {{ old('pendidikan_terakhir', $petani->pendidikan_terakhir?->value) == $value['value'] ? 'selected' : '' }}>{{ $value['label'] }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('pendidikan_terakhir')<div class="error invalid-feedback">{{ $message }}</div>@enderror
|
||||
@@ -123,7 +129,7 @@
|
||||
<select class="form-control @error('status_perkawinan') is-invalid @enderror" id="edit-petani-status-pernikahan" name="status_perkawinan">
|
||||
<option value="">Pilih Status Pernikahan</option>
|
||||
@foreach($pernikahan as $value)
|
||||
<option value="{{ $value['value'] }}" {{ old('status_perkawinan', $petani->status_perkawinan->value) == $value['value'] ? 'selected' : '' }}>{{ $value['label'] }}</option>
|
||||
<option value="{{ $value['value'] }}" {{ old('status_perkawinan', $petani->status_perkawinan?->value) == $value['value'] ? 'selected' : '' }}>{{ $value['label'] }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('status_perkawinan')<div class="error invalid-feedback">{{ $message }}</div>@enderror
|
||||
@@ -159,7 +165,7 @@
|
||||
<select class="form-control @error('provinsi_id') is-invalid @enderror" id="edit-petani-provinsi" name="provinsi_id">
|
||||
<option value="">Pilih Provinsi</option>
|
||||
@foreach($provinsi as $p)
|
||||
<option value="{{ $p->id }}" {{ old('provinsi_id', $petani->desaKelurahan->kecamatan->kabupatenKota->provinsi_id) == $p->id ? 'selected' : '' }}>{{ $p->nama }}</option>
|
||||
<option value="{{ $p->id }}" {{ old('provinsi_id', $petani->desaKelurahan?->kecamatan?->kabupatenKota?->provinsi_id) == $p->id ? 'selected' : '' }}>{{ $p->nama }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('provinsi_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
|
||||
@@ -168,7 +174,9 @@
|
||||
<label class="form-label" for="edit-petani-kabupaten">Kabupaten/Kota<span class="text-danger">*</span></label>
|
||||
<select class="form-control @error('kabupaten_id') is-invalid @enderror" id="edit-petani-kabupaten" name="kabupaten_id" >
|
||||
<option value="">Pilih Kabupaten/Kota</option>
|
||||
@if($petani->desaKelurahan?->kecamatan?->kabupatenKota)
|
||||
<option value="{{ $petani->desaKelurahan->kecamatan->kabupatenKota->id }}" selected>{{ $petani->desaKelurahan->kecamatan->kabupatenKota->nama }}</option>
|
||||
@endif
|
||||
</select>
|
||||
@error('kabupaten_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
@@ -176,7 +184,9 @@
|
||||
<label class="form-label" for="edit-petani-kecamatan">Kecamatan<span class="text-danger">*</span></label>
|
||||
<select class="form-control @error('kecamatan_id') is-invalid @enderror" id="edit-petani-kecamatan" name="kecamatan_id" >
|
||||
<option value="">Pilih Kecamatan</option>
|
||||
@if($petani->desaKelurahan?->kecamatan)
|
||||
<option value="{{ $petani->desaKelurahan->kecamatan->id }}" selected>{{ $petani->desaKelurahan->kecamatan->nama }}</option>
|
||||
@endif
|
||||
</select>
|
||||
@error('kecamatan_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
@@ -184,7 +194,9 @@
|
||||
<label class="form-label" for="edit-petani-desa">Desa/Kelurahan<span class="text-danger">*</span></label>
|
||||
<select class="form-control @error('desa_kelurahan_id') is-invalid @enderror" id="edit-petani-desa" name="desa_kelurahan_id" >
|
||||
<option value="">Pilih Desa/Kelurahan</option>
|
||||
@if($petani->desaKelurahan)
|
||||
<option value="{{ $petani->desaKelurahan->id }}" selected>{{ $petani->desaKelurahan->nama }}</option>
|
||||
@endif
|
||||
</select>
|
||||
@error('desa_kelurahan_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
@@ -242,7 +254,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
|
||||
<button type="submit" class="btn btn-success data-submit wave-effect wave-light"><i class="ti tabler-device-floppy me-2"></i> Simpan Profil</button>
|
||||
</div>
|
||||
|
||||
@@ -253,6 +265,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="fotoProfilModal" tabindex="-1" aria-labelledby="fotoProfilModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="fotoProfilModalLabel">Foto Profil Petani</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Tutup"></button>
|
||||
</div>
|
||||
<div class="modal-body text-center">
|
||||
<img id="fotoProfilBesar" class="img-fluid rounded-3" alt="Foto profil petani" style="max-height: 75vh; object-fit: contain;" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="cropModal" tabindex="-1" aria-labelledby="cropModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
@@ -344,7 +370,11 @@
|
||||
|
||||
let croppieInstance = null;
|
||||
|
||||
$('#fotoPreview').on('click', function () {
|
||||
$('#fotoProfilModal').on('show.bs.modal', function () {
|
||||
$('#fotoProfilBesar').attr('src', $('#fotoPreview').attr('src'));
|
||||
});
|
||||
|
||||
$('#btnGantiFoto').on('click', function () {
|
||||
$('#foto').val('');
|
||||
$('#foto').click();
|
||||
});
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
<hr class="my-2"> <h6 class="mb-1" style="font-size: 0.85rem;">Domisili</h6>
|
||||
<p class="mb-0 text-muted" style="font-size: 0.75rem;">Alamat: {{ isset($petani) ? $petani->alamat : 'Alamat' }}</p>
|
||||
<p class="mb-0 text-muted" style="font-size: 0.75rem; line-height: 1.3;">{{ isset($petani) ? $petani->desaKelurahan->nama : 'Desa/Kelurahan' }}, {{ $petani ? $petani->desaKelurahan->kecamatan->nama : 'Kecamatan' }}, {{ $petani ? $petani->desaKelurahan->kecamatan->kabupatenKota->nama : 'Kabupaten/Kota' }}, {{ $petani ? $petani->desaKelurahan->kecamatan->kabupatenKota->provinsi->nama : 'Provinsi' }}</p>
|
||||
<p class="mb-0 text-muted" style="font-size: 0.75rem; line-height: 1.3;">{{ isset($petani) ? $petani->desaKelurahan?->nama ?? 'Belum diisi' : 'Desa/Kelurahan' }}, {{ $petani ? $petani->desaKelurahan?->kecamatan?->nama ?? 'Belum diisi' : 'Kecamatan' }}, {{ $petani ? $petani->desaKelurahan?->kecamatan?->kabupatenKota?->nama ?? 'Belum diisi' : 'Kabupaten/Kota' }}, {{ $petani ? $petani->desaKelurahan?->kecamatan?->kabupatenKota?->provinsi?->nama ?? 'Belum diisi' : 'Provinsi' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -116,7 +116,7 @@
|
||||
</h5>
|
||||
<p class="mb-0" style="font-size: 0.75rem;">
|
||||
@if(!is_null($skorLahanTanaman))
|
||||
<span class="me-1">{{ number_format($totalTanaman, 0, ',', '.') }} tanaman {{ $petani?->komoditas->nama }}</span>
|
||||
<span class="me-1">{{ number_format($totalTanaman, 0, ',', '.') }} tanaman {{ $petani?->komoditas?->nama ?? 'Belum diisi' }}</span>
|
||||
@else
|
||||
<span class="me-1">Belum terisi</span>
|
||||
@endif
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
|
||||
@push('style')
|
||||
<style>
|
||||
#data-petani {
|
||||
scroll-margin-top: 7rem;
|
||||
}
|
||||
|
||||
.petani-row {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.indicator-filter-row {
|
||||
padding-bottom: 1.5rem;
|
||||
padding-top: 1.5rem;
|
||||
@@ -84,8 +92,8 @@
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid flex-grow-1 container-p-y">
|
||||
<div class="d-flex flex-row gap-3 mb-4">
|
||||
<div class="w-25">
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-12 col-md-4">
|
||||
<x-summary-card
|
||||
title="Petani"
|
||||
count="{{ number_format($totalPetani ?? 0, 0, ',', '.') }}"
|
||||
@@ -94,7 +102,7 @@
|
||||
color="primary"
|
||||
/>
|
||||
</div>
|
||||
<div class="w-25">
|
||||
<div class="col-12 col-md-4">
|
||||
<x-summary-card
|
||||
title="Lahan & Tanaman"
|
||||
count="{{ number_format($totalLuasLahan ?? 0, 2, ',', '.') }} ha"
|
||||
@@ -103,7 +111,7 @@
|
||||
color="success"
|
||||
/>
|
||||
</div>
|
||||
<div class="w-25">
|
||||
<div class="col-12 col-md-4">
|
||||
<x-summary-card
|
||||
title="Segmentasi"
|
||||
count="{{ number_format((int) ($skor->firstWhere('segmen', 'Penggerak')->total ?? 0), 0, ',', '.') }} Penggerak"
|
||||
@@ -265,7 +273,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card" id="data-petani">
|
||||
<div class="card-header border-bottom">
|
||||
<h5 class="card-title mb-0">Data Petani</h5>
|
||||
</div>
|
||||
@@ -315,10 +323,10 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($petani as $index => $item)
|
||||
<tr>
|
||||
<tr class="petani-row">
|
||||
<td>{{ $loop->iteration }}</td>
|
||||
<td>
|
||||
<span class="text-heading d-block">{{ $item->nama }}</span>
|
||||
<a href="{{ route('petani.edit', $item->id) }}" class="text-heading d-block">{{ $item->nama }}</a>
|
||||
<small class="text-muted">
|
||||
{{ $item->jenis_kelamin ? 'Laki-laki' : 'Perempuan' }}
|
||||
@if(! is_null($item->umur))
|
||||
@@ -423,6 +431,14 @@
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.petani-row', function (event) {
|
||||
if ($(event.target).closest('a, button, input, select, textarea, label').length) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.href = this.querySelector('.edit-record').href;
|
||||
});
|
||||
|
||||
$(document).on('click', '.delete-record', function () {
|
||||
const id = $(this).data('id');
|
||||
const name = $(this).data('nama');
|
||||
|
||||
@@ -517,7 +517,7 @@
|
||||
|
||||
<div class="row mt-3">
|
||||
<div class="col-12 text-end">
|
||||
<a href="{{ route('petani.index') }}" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
|
||||
<button type="submit" class="btn btn-success data-submit wave-effect wave-light"><i class="ti tabler-device-floppy me-2"></i> Simpan Lahan</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -406,8 +406,8 @@
|
||||
|
||||
<div class="row mt-3">
|
||||
<div class="col-12 text-end">
|
||||
<a href="{{ route('petani.index') }}" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
|
||||
<button id="delete-lahan"type="button" class="btn btn-danger data-submit wave-effect wave-light"><i class="ti tabler-trash me-2"></i> Hapus Lahan</button>
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2 wave-effect wave-light">Kembali</a>
|
||||
<button type="submit" class="btn btn-success data-submit wave-effect wave-light"><i class="ti tabler-device-floppy me-2"></i> Simpan Lahan</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-primary">Simpan Perubahan</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
</table>
|
||||
</div>
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
|
||||
@@ -167,10 +167,13 @@
|
||||
Tambah Pelatihan
|
||||
</button>
|
||||
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan Riwayat Pelatihan
|
||||
</button>
|
||||
<div class="d-flex flex-wrap justify-content-end gap-2">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan Riwayat Pelatihan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -347,10 +350,13 @@
|
||||
Tambah Sertifikasi
|
||||
</button>
|
||||
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan Sertifikasi Keahlian
|
||||
</button>
|
||||
<div class="d-flex flex-wrap justify-content-end gap-2">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan Sertifikasi Keahlian
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -499,6 +499,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
Simpan
|
||||
</button>
|
||||
|
||||
@@ -530,6 +530,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
@@ -1039,6 +1040,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
@@ -1352,6 +1354,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
@@ -1542,6 +1545,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
@@ -1678,9 +1682,12 @@
|
||||
Tambah Komoditas
|
||||
</button>
|
||||
|
||||
<button type="submit" class="btn btn-success">
|
||||
Simpan Produktivitas
|
||||
</button>
|
||||
<div class="d-flex flex-wrap justify-content-end gap-2">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
Simpan
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -1725,6 +1732,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
|
||||
@@ -399,6 +399,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
@@ -567,6 +568,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
@@ -696,6 +698,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
@@ -915,6 +918,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
@@ -1043,6 +1047,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
|
||||
@@ -398,6 +398,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
@@ -566,6 +567,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
@@ -694,6 +696,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
@@ -912,6 +915,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
@@ -1039,6 +1043,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-secondary me-2">Kembali</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-base ti tabler-check me-1_5 icon-sm"></i>
|
||||
Simpan
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="{{ route('petani.index') }}" class="btn btn-label-secondary me-2">Kembali</a>
|
||||
<a href="{{ route('petani.index') }}#data-petani" class="btn btn-label-secondary me-2">Kembali</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user