diff --git a/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/TanpaTps.cshtml b/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/TanpaTps.cshtml
index 3e3efd0..b76d838 100644
--- a/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/TanpaTps.cshtml
+++ b/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/TanpaTps.cshtml
@@ -1,6 +1,6 @@
@{
Layout = "~/Views/Admin/Transport/SpjDriverUpst/Shared/_Layout.cshtml";
- ViewData["Title"] = "Detail Penjemputan - Tanpa TPS";
+ ViewData["Title"] = "Detail Penjemputan - TPS A";
}
-
- TANPA TPS
+
+ TPS A
Perusahaan
-
CV Tri Berkah Sejahtera
+
CV Tri Berkah Sejahtera
-
SPJ/07-2025/PKM/000476
+
SPJ/07-2025/PKM/000476
-
+
Kp. Pertanian II Rt.004 Rw.001 Kel. Klender Kec, Duren Sawit, Kota Adm. Jakarta Timur 13470
@@ -87,9 +87,8 @@
-
Form Pengangkutan
-
Tanpa TPS
+
TPS A
diff --git a/Views/Admin/Transport/SpjDriverUpst/Home/Index.cshtml b/Views/Admin/Transport/SpjDriverUpst/Home/Index.cshtml
index 6e2d57d..ce9a7f9 100644
--- a/Views/Admin/Transport/SpjDriverUpst/Home/Index.cshtml
+++ b/Views/Admin/Transport/SpjDriverUpst/Home/Index.cshtml
@@ -134,7 +134,25 @@
Jakarta Timur 13470
- Ada 3 TPS
+ 3 TPS
+
+
+
+
+
+
+
+
+ Proses
+
+
+
CV Tri Berkah Sejahtera
+
+
+
Duren Sawit, Jakarta Timur
+
+
+ 1 TPS
@@ -149,7 +167,7 @@
CV Tri Mitra Utama - Shell Radio Dalam
Jakarta Selatan
- Ada 3 TPS
+ 3 TPS
@@ -164,7 +182,7 @@
CV Tri Berkah Sejahtera
Duren Sawit, Jakarta Timur
- Tidak ada TPS
+ 1 TPS
diff --git a/wwwroot/driver/css/watch.css b/wwwroot/driver/css/watch.css
index e68ab2c..c8ae70d 100644
--- a/wwwroot/driver/css/watch.css
+++ b/wwwroot/driver/css/watch.css
@@ -109,8 +109,6 @@
--text-xl--line-height: calc(1.75 / 1.25);
--text-2xl: 1.5rem;
--text-2xl--line-height: calc(2 / 1.5);
- --text-5xl: 3rem;
- --text-5xl--line-height: 1;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
@@ -569,12 +567,6 @@
.col-auto {
grid-column: auto;
}
- .col-span-1 {
- grid-column: span 1 / span 1;
- }
- .col-span-2 {
- grid-column: span 2 / span 2;
- }
.float-end {
float: inline-end;
}
@@ -806,12 +798,6 @@
.ml-auto {
margin-left: auto;
}
- .line-clamp-2 {
- overflow: hidden;
- display: -webkit-box;
- -webkit-box-orient: vertical;
- -webkit-line-clamp: 2;
- }
.line-clamp-3 {
overflow: hidden;
display: -webkit-box;
@@ -875,9 +861,6 @@
.h-3 {
height: calc(var(--spacing) * 3);
}
- .h-3\.5 {
- height: calc(var(--spacing) * 3.5);
- }
.h-4 {
height: calc(var(--spacing) * 4);
}
@@ -986,9 +969,6 @@
.w-3 {
width: calc(var(--spacing) * 3);
}
- .w-3\.5 {
- width: calc(var(--spacing) * 3.5);
- }
.w-4 {
width: calc(var(--spacing) * 4);
}
@@ -1235,9 +1215,6 @@
.gap-1 {
gap: calc(var(--spacing) * 1);
}
- .gap-1\.5 {
- gap: calc(var(--spacing) * 1.5);
- }
.gap-2 {
gap: calc(var(--spacing) * 2);
}
@@ -1691,6 +1668,9 @@
.bg-gray-200 {
background-color: var(--color-gray-200);
}
+ .bg-gray-300 {
+ background-color: var(--color-gray-300);
+ }
.bg-gray-400 {
background-color: var(--color-gray-400);
}
@@ -2138,9 +2118,6 @@
.py-1 {
padding-block: calc(var(--spacing) * 1);
}
- .py-1\.5 {
- padding-block: calc(var(--spacing) * 1.5);
- }
.py-2 {
padding-block: calc(var(--spacing) * 2);
}
@@ -2159,9 +2136,6 @@
.py-6 {
padding-block: calc(var(--spacing) * 6);
}
- .py-10 {
- padding-block: calc(var(--spacing) * 10);
- }
.py-12 {
padding-block: calc(var(--spacing) * 12);
}
@@ -2436,12 +2410,6 @@
.text-blue-700 {
color: var(--color-blue-700);
}
- .text-blue-700\/60 {
- color: color-mix(in srgb, oklch(48.8% 0.243 264.376) 60%, transparent);
- @supports (color: color-mix(in lab, red, red)) {
- color: color-mix(in oklab, var(--color-blue-700) 60%, transparent);
- }
- }
.text-blue-800 {
color: var(--color-blue-800);
}
@@ -2859,13 +2827,6 @@
}
}
}
- .group-hover\:border-gray-200 {
- &:is(:where(.group):hover *) {
- @media (hover: hover) {
- border-color: var(--color-gray-200);
- }
- }
- }
.group-hover\:text-gray-500 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
@@ -2887,14 +2848,6 @@
}
}
}
- .group-hover\:shadow {
- &:is(:where(.group):hover *) {
- @media (hover: hover) {
- --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
- box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
- }
- }
- }
.group-hover\:shadow-md {
&:is(:where(.group):hover *) {
@media (hover: hover) {
@@ -3021,13 +2974,6 @@
}
}
}
- .hover\:border-gray-200 {
- &:hover {
- @media (hover: hover) {
- border-color: var(--color-gray-200);
- }
- }
- }
.hover\:border-orange-200 {
&:hover {
@media (hover: hover) {
@@ -3346,11 +3292,6 @@
scale: var(--tw-scale-x) var(--tw-scale-y);
}
}
- .sm\:grid-cols-4 {
- @media (width >= 40rem) {
- grid-template-columns: repeat(4, minmax(0, 1fr));
- }
- }
.lg\:max-w-sm {
@media (width >= 64rem) {
max-width: var(--container-sm);
diff --git a/wwwroot/driver/js/detail-penjemputan-non-tps.js b/wwwroot/driver/js/detail-penjemputan-non-tps.js
index 23ee36d..e0be3c2 100644
--- a/wwwroot/driver/js/detail-penjemputan-non-tps.js
+++ b/wwwroot/driver/js/detail-penjemputan-non-tps.js
@@ -16,10 +16,12 @@ document.addEventListener('DOMContentLoaded', function() {
];
const JENIS_SAMPAH = ['Organik', 'Anorganik', 'Residu'];
const DEFAULT_JENIS = 'Residu';
+ const DETAIL_DATA_URL = '/driver/json/detail-penjemputan-non-tps.json';
+ const DEFAULT_TPS_NAME = 'Lokasi Pengangkutan 1';
function initializeLocation() {
tpsData = [{
- name: '',
+ name: DEFAULT_TPS_NAME,
index: 0,
lokasiAngkutId: '',
spjDetailId: '',
@@ -43,6 +45,53 @@ document.addEventListener('DOMContentLoaded', function() {
renderTpsForm();
}
+ async function loadDetailData() {
+ try {
+ const response = await fetch(DETAIL_DATA_URL, { cache: 'no-store' });
+ if (!response.ok) {
+ return;
+ }
+
+ const payload = await response.json();
+ const detail = payload.detailPenjemputan || payload;
+ const namaTps = detail.namaTps || detail.tpsName || detail.name || DEFAULT_TPS_NAME;
+ const namaPerusahaan = detail.namaPerusahaan || detail.companyName || '';
+
+ if (tpsData[0]) {
+ tpsData[0].name = namaTps;
+ tpsData[0].lokasiAngkutId = detail.lokasiAngkutId || detail.LokasiAngkutID || tpsData[0].lokasiAngkutId;
+ tpsData[0].spjDetailId = detail.spjDetailId || detail.SpjDetailID || tpsData[0].spjDetailId;
+ }
+
+ nomorSpj = detail.nomorSpj || nomorSpj;
+ applyDetailDataToView(detail, namaTps, namaPerusahaan);
+ renderTpsForm();
+ } catch (error) {
+ console.warn('Gagal memuat detail penjemputan non-TPS:', error);
+ }
+ }
+
+ function applyDetailDataToView(detail, namaTps, namaPerusahaan) {
+ const titleEl = document.getElementById('detail-page-title');
+ const badgeEl = document.getElementById('detail-tps-badge');
+ const formBadgeEl = document.getElementById('detail-form-badge');
+ const companyEl = document.getElementById('detail-company-name');
+ const spjEl = document.getElementById('detail-spj-number');
+ const addressEl = document.getElementById('detail-address');
+ const platEl = document.getElementById('plat-nomor');
+ const doorEl = document.getElementById('detail-nomor-pintu');
+
+ if (titleEl) titleEl.textContent = namaTps;
+ if (badgeEl) badgeEl.textContent = namaTps;
+ if (formBadgeEl) formBadgeEl.textContent = namaTps;
+ if (companyEl && namaPerusahaan) companyEl.textContent = namaPerusahaan;
+ if (spjEl && detail.nomorSpj) spjEl.textContent = detail.nomorSpj;
+ if (addressEl && detail.alamat) addressEl.textContent = detail.alamat;
+ if (platEl && detail.platNomor) platEl.textContent = detail.platNomor;
+ if (doorEl && detail.nomorPintu) doorEl.textContent = detail.nomorPintu;
+ document.title = `Detail Penjemputan - ${namaTps}`;
+ }
+
function renderTpsForm() {
const tps = tpsData[activeTpsIndex];
@@ -62,7 +111,7 @@ document.addEventListener('DOMContentLoaded', function() {
1
-
Foto Kedatangan
+
Foto Kedatangan
Upload foto kedatangan
@@ -102,7 +151,7 @@ document.addEventListener('DOMContentLoaded', function() {
2
-
Foto Timbang Sampah
+
Foto Timbang Sampah
Upload foto timbangan, berat auto terisi
@@ -118,7 +167,7 @@ document.addEventListener('DOMContentLoaded', function() {
3
-
Foto Petugas
+
Foto Petugas
Upload dokumentasi petugas
@@ -127,15 +176,7 @@ document.addEventListener('DOMContentLoaded', function() {
- ${tps.fotoPetugas.length > 0 && !tps.fotoPetugasUploaded ? `
-
- ` : tps.fotoPetugasUploaded ? `
-
- ✓ Foto petugas sudah diupload
-
- ` : ''}
+
${getPetugasUploadStateMarkup(tps)}
@@ -227,6 +268,7 @@ document.addEventListener('DOMContentLoaded', function() {
namaPetugasInput.addEventListener('input', function() {
tps.namaPetugas = this.value;
+ refreshPetugasUploadState(form);
});
btnAddTimbangan.addEventListener('click', function() {
@@ -526,7 +568,7 @@ document.addEventListener('DOMContentLoaded', function() {
async function autoFillWeight(file, weightInput, ocrInfoEl) {
let guessedWeight = 0;
weightInput.placeholder = 'Membaca angka dari foto...';
- if (ocrInfoEl) ocrInfoEl.textContent = 'AI OCR: memproses gambar...';
+ if (ocrInfoEl) ocrInfoEl.textContent = 'AI: memproses gambar...';
try {
const img = await readFileAsImage(file);
@@ -551,12 +593,12 @@ document.addEventListener('DOMContentLoaded', function() {
if (ocrInfoEl) {
const cleaned = (bestRawText || '').replace(/\s+/g, ' ').trim();
ocrInfoEl.textContent = isSuccess
- ? `AI OCR terbaca: ${cleaned}`
- : (cleaned ? `AI OCR tidak valid: ${cleaned}` : 'AI OCR tidak menemukan angka valid.');
+ ? `AI terbaca: ${cleaned}`
+ : (cleaned ? `AI tidak valid: ${cleaned}` : 'AI tidak menemukan angka valid.');
}
} catch (_) {
guessedWeight = 0;
- if (ocrInfoEl) ocrInfoEl.textContent = 'AI OCR gagal diproses.';
+ if (ocrInfoEl) ocrInfoEl.textContent = 'AI gagal diproses.';
}
if (guessedWeight > 0) {
@@ -606,18 +648,119 @@ document.addEventListener('DOMContentLoaded', function() {
if (grandTotalResiduDisplay) grandTotalResiduDisplay.textContent = formatWeightDisplay(totalResidu);
}
+ function getTimbanganUploadStateMarkup(hasFile, isUploaded, hasValidWeight) {
+ if (!hasFile) {
+ return '
Pilih foto timbangan terlebih dahulu
';
+ }
+
+ if (isUploaded) {
+ return `
+
✓ Foto timbangan sudah diupload
+
Kalau mau revisi, pilih file baru di atas. Status upload akan direset otomatis.
+ `;
+ }
+
+ if (!hasValidWeight) {
+ return `
+
+
Isi berat manual dulu sebelum upload jika berat tidak terbaca.
+ `;
+ }
+
+ return `
+
+
Foto siap diupload.
+ `;
+ }
+
+ function getPetugasUploadStateMarkup(tps) {
+ if (tps.fotoPetugasUploaded) {
+ return '
✓ Foto petugas sudah diupload
';
+ }
+
+ if (!tps.fotoPetugas.length) {
+ return '';
+ }
+
+ if (!tps.namaPetugas.trim()) {
+ return `
+
+
Isi nama petugas terlebih dahulu
+ `;
+ }
+
+ return `
`;
+ }
+
+ function refreshPetugasUploadState(form) {
+ const stateContainer = form.querySelector('.petugas-upload-state');
+ if (!stateContainer) return;
+
+ const tps = tpsData[activeTpsIndex];
+ stateContainer.innerHTML = getPetugasUploadStateMarkup(tps);
+
+ const btnUploadPetugas = stateContainer.querySelector('.tps-btn-upload-petugas:not([disabled])');
+ if (btnUploadPetugas) {
+ btnUploadPetugas.addEventListener('click', uploadFotoPetugas);
+ }
+ }
+
+ function refreshTimbanganUploadState(item) {
+ const stateContainer = item.querySelector('.timbangan-upload-state');
+ if (!stateContainer) return;
+
+ const repeater = item.parentElement;
+ const itemIndex = repeater ? Array.from(repeater.children).indexOf(item) : -1;
+ const tps = tpsData[activeTpsIndex];
+ const currentData = itemIndex >= 0 ? tps.timbangan[itemIndex] : null;
+ const fileInput = item.querySelector('.input-foto-timbangan');
+ const hasFile = Boolean(currentData?.file || fileInput?.files?.[0]);
+ const isUploaded = Boolean(currentData?.uploaded);
+ const weightInputValue = item.querySelector('.input-berat-timbangan-value');
+ const currentWeight = currentData?.berat && currentData.berat.length > 0
+ ? currentData.berat[0]
+ : parseWeightInput(weightInputValue?.value || '0');
+ const hasValidWeight = currentWeight > 0;
+
+ stateContainer.innerHTML = getTimbanganUploadStateMarkup(hasFile, isUploaded, hasValidWeight);
+
+ const uploadBtn = stateContainer.querySelector('.btn-upload-timbangan');
+ if (uploadBtn) {
+ uploadBtn.addEventListener('click', function() {
+ const latestIndex = repeater ? Array.from(repeater.children).indexOf(item) : -1;
+ uploadSingleFotoTimbangan(latestIndex, item);
+ });
+ }
+ }
+
+ function renumberTimbanganItems(repeater) {
+ const items = repeater.querySelectorAll('.timbangan-item');
+ items.forEach((item, index) => {
+ const newNumber = index + 1;
+ item.dataset.photoNumber = newNumber;
+
+ const label = item.querySelector('.text-xs.font-bold.text-gray-600');
+ if (label) {
+ label.textContent = `Item Timbangan #${newNumber}`;
+ }
+ });
+ }
+
function createTimbanganItem(repeater, existingData = null) {
+ const photoNumber = repeater.children.length + 1;
const item = document.createElement('div');
item.className = 'timbangan-item rounded-2xl border border-gray-200 p-3 space-y-2 bg-gray-50';
+ item.dataset.photoNumber = photoNumber;
const weight = existingData ? (existingData.berat && existingData.berat.length > 0 ? existingData.berat[0] : 0) : 0;
const jenisSampah = existingData ? (existingData.jenisSampah && existingData.jenisSampah.length > 0 ? existingData.jenisSampah[0] : DEFAULT_JENIS) : DEFAULT_JENIS;
const hasFile = existingData && existingData.file;
const isUploaded = existingData && existingData.uploaded;
+ const ocrInfoText = existingData && existingData.ocrInfo ? existingData.ocrInfo : (hasFile ? 'OCR: diproses.' : 'OCR: belum diproses.');
item.innerHTML = `
-
Item Timbangan
+
Item Timbangan #${photoNumber}
@@ -625,10 +768,8 @@ document.addEventListener('DOMContentLoaded', function() {
-
${hasFile ? 'OCR: diproses.' : 'OCR: belum diproses.'}
- ${hasFile && !isUploaded ? `
-
- ` : isUploaded ? `
✓ Foto timbangan sudah diupload
` : ''}
+
${ocrInfoText}
+
${getTimbanganUploadStateMarkup(hasFile, isUploaded, weight > 0)}
@@ -662,7 +803,7 @@ document.addEventListener('DOMContentLoaded', function() {
fileInput.addEventListener('change', async function() {
if (fileInput.files && fileInput.files[0]) {
const originalFile = fileInput.files[0];
- const photoNumber = Array.from(repeater.children).indexOf(item) + 1;
+ const photoNumber = Number(item.dataset.photoNumber || (Array.from(repeater.children).indexOf(item) + 1));
const watermarkedFile = await applyWatermark(originalFile, photoNumber);
const dataTransfer = new DataTransfer();
@@ -684,16 +825,7 @@ document.addEventListener('DOMContentLoaded', function() {
const itemIndex = Array.from(repeater.children).indexOf(item);
if (itemIndex >= 0 && tps.timbangan[itemIndex]) {
tps.timbangan[itemIndex].uploaded = false;
- const existingUploadBtn = item.querySelector('.btn-upload-timbangan');
- if (!existingUploadBtn) {
- const ocrInfo = item.querySelector('.input-ocr-info');
- const uploadBtn = document.createElement('button');
- uploadBtn.type = 'button';
- uploadBtn.className = 'btn-upload-timbangan w-full bg-blue-500 text-white py-2 rounded-xl font-bold text-xs hover:brightness-110';
- uploadBtn.textContent = 'Upload Foto Timbangan Ini';
- uploadBtn.addEventListener('click', function() { uploadSingleFotoTimbangan(itemIndex); });
- ocrInfo.parentNode.insertBefore(uploadBtn, ocrInfo.nextSibling);
- }
+ refreshTimbanganUploadState(item);
}
}
});
@@ -705,6 +837,7 @@ document.addEventListener('DOMContentLoaded', function() {
weightInputValue.value = parsed.toFixed(2);
updateTpsTotalTimbangan();
syncTimbanganToTpsData();
+ refreshTimbanganUploadState(item);
});
weightInputDisplay.addEventListener('blur', function() {
@@ -718,6 +851,7 @@ document.addEventListener('DOMContentLoaded', function() {
}
updateTpsTotalTimbangan();
syncTimbanganToTpsData();
+ refreshTimbanganUploadState(item);
});
jenisSampahSelect.addEventListener('change', function() {
@@ -729,20 +863,16 @@ document.addEventListener('DOMContentLoaded', function() {
item.remove();
const form = tpsContentContainer.querySelector('form');
const rep = form ? form.querySelector('.tps-timbangan-repeater') : null;
- if (rep && rep.children.length === 0) createTimbanganItem(rep);
+ if (rep) {
+ renumberTimbanganItems(rep);
+ if (rep.children.length === 0) createTimbanganItem(rep);
+ }
updateTpsTotalTimbangan();
syncTimbanganToTpsData();
});
- const btnUploadTimbangan = item.querySelector('.btn-upload-timbangan');
- if (btnUploadTimbangan) {
- btnUploadTimbangan.addEventListener('click', function() {
- const itemIndex = Array.from(repeater.children).indexOf(item);
- uploadSingleFotoTimbangan(itemIndex);
- });
- }
-
repeater.appendChild(item);
+ refreshTimbanganUploadState(item);
return item;
}
@@ -753,20 +883,23 @@ document.addEventListener('DOMContentLoaded', function() {
const repeater = form.querySelector('.tps-timbangan-repeater');
const items = repeater.querySelectorAll('.timbangan-item');
+ const previousTimbangan = [...tps.timbangan];
tps.timbangan = [];
- items.forEach(item => {
+ items.forEach((item, index) => {
const fileInput = item.querySelector('.input-foto-timbangan');
const weightValue = item.querySelector('.input-berat-timbangan-value');
const weight = parseWeightInput(weightValue.value);
const jenisSampah = item.querySelector('.input-jenis-sampah').value;
+ const ocrInfo = item.querySelector('.input-ocr-info')?.textContent || 'OCR: belum diproses.';
tps.timbangan.push({
file: fileInput.files[0] || null,
berat: [weight],
jenisSampah: [jenisSampah],
lokasiAngkut: [],
- uploaded: false
+ uploaded: previousTimbangan[index]?.uploaded ?? false,
+ ocrInfo
});
});
}
@@ -803,14 +936,32 @@ document.addEventListener('DOMContentLoaded', function() {
return formData;
}
- function uploadSingleFotoTimbangan(itemIndex) {
+ function uploadSingleFotoTimbangan(itemIndex, targetItem = null) {
const tps = tpsData[activeTpsIndex];
if (!tps.timbangan[itemIndex] || !tps.timbangan[itemIndex].file) {
alert('Belum ada foto timbangan yang dipilih!');
return;
}
- alert(`Upload foto timbangan #${itemIndex + 1}\nBerat: ${tps.timbangan[itemIndex].weight} kg\n(Implementasi upload ke server)`);
+ const weight = tps.timbangan[itemIndex].berat && tps.timbangan[itemIndex].berat.length > 0
+ ? tps.timbangan[itemIndex].berat[0]
+ : 0;
+ if (weight <= 0) {
+ alert('Berat belum valid. Isi manual dulu sebelum upload foto timbangan.');
+ return;
+ }
+ alert(`Upload foto timbangan #${itemIndex + 1}\nBerat: ${formatWeightDisplay(weight)} kg\n(Implementasi upload ke server)`);
tps.timbangan[itemIndex].uploaded = true;
+
+ if (!targetItem) {
+ const form = tpsContentContainer.querySelector('form');
+ const repeater = form ? form.querySelector('.tps-timbangan-repeater') : null;
+ const items = repeater ? repeater.querySelectorAll('.timbangan-item') : [];
+ targetItem = items[itemIndex] || null;
+ }
+
+ if (targetItem) {
+ refreshTimbanganUploadState(targetItem);
+ }
}
function uploadFotoKedatangan() {
@@ -830,7 +981,11 @@ document.addEventListener('DOMContentLoaded', function() {
alert('Belum ada foto petugas yang dipilih!');
return;
}
- alert(`Upload ${tps.fotoPetugas.length} foto petugas\n(Implementasi upload ke server)`);
+ if (!tps.namaPetugas.trim()) {
+ alert('Nama petugas wajib diisi sebelum upload foto petugas!');
+ return;
+ }
+ alert(`Upload ${tps.fotoPetugas.length} foto petugas untuk ${tps.name}\n(Implementasi upload ke server)`);
tps.fotoPetugasUploaded = true;
renderTpsForm();
}
@@ -842,7 +997,7 @@ document.addEventListener('DOMContentLoaded', function() {
if (!tps.fotoPetugas.length) return alert('Foto petugas belum diupload!');
if (!tps.namaPetugas.trim()) return alert('Nama petugas belum diisi!');
- alert(`Validasi OK (Tanpa TPS).\n- Organik: ${formatWeightDisplay(tps.totalOrganik)} kg\n- Anorganik: ${formatWeightDisplay(tps.totalAnorganik)} kg\n- Residu: ${formatWeightDisplay(tps.totalResidu)} kg\n- Total: ${formatWeightDisplay(tps.totalTimbangan)} kg\n- Petugas: ${tps.namaPetugas}`);
+ alert(`Validasi OK (${tps.name}).\n- Organik: ${formatWeightDisplay(tps.totalOrganik)} kg\n- Anorganik: ${formatWeightDisplay(tps.totalAnorganik)} kg\n- Residu: ${formatWeightDisplay(tps.totalResidu)} kg\n- Total: ${formatWeightDisplay(tps.totalTimbangan)} kg\n- Petugas: ${tps.namaPetugas}`);
tps.submitted = true;
/*
@@ -857,4 +1012,5 @@ document.addEventListener('DOMContentLoaded', function() {
}
initializeLocation();
+ loadDetailData();
});
diff --git a/wwwroot/driver/js/detail-penjemputan-tps.js b/wwwroot/driver/js/detail-penjemputan-tps.js
index bc961a3..fe86162 100644
--- a/wwwroot/driver/js/detail-penjemputan-tps.js
+++ b/wwwroot/driver/js/detail-penjemputan-tps.js
@@ -312,15 +312,7 @@ const DetailPenjemputan = (function() {
- ${tps.fotoPetugas.length > 0 && !tps.fotoPetugasUploaded ? `
-
- ` : tps.fotoPetugasUploaded ? `
-
- ✓ Foto petugas sudah diupload
-
- ` : ''}
+
${getPetugasUploadStateMarkup(tps)}
@@ -356,6 +348,7 @@ const DetailPenjemputan = (function() {
namaPetugasInput.addEventListener('input', function() {
tps.namaPetugas = this.value;
+ refreshPetugasUploadState(form);
});
btnAddTimbangan.addEventListener('click', function() {
@@ -546,6 +539,7 @@ const DetailPenjemputan = (function() {
const jenisSampah = existingData ? existingData.jenisSampah : CONFIG.DEFAULT_JENIS;
const hasFile = existingData && existingData.file;
const isUploaded = existingData && existingData.uploaded;
+ const ocrInfoText = existingData && existingData.ocrInfo ? existingData.ocrInfo : (hasFile ? 'OCR: diproses.' : 'OCR: belum diproses.');
item.innerHTML = `
@@ -556,16 +550,8 @@ const DetailPenjemputan = (function() {
-
${hasFile ? 'OCR: diproses.' : 'OCR: belum diproses.'}
- ${hasFile && !isUploaded ? `
-
- ` : isUploaded ? `
-
- ✓ Foto timbangan sudah diupload
-
- ` : ''}
+
${ocrInfoText}
+
${getTimbanganUploadStateMarkup(hasFile, isUploaded, weight > 0)}
@@ -625,19 +611,7 @@ const DetailPenjemputan = (function() {
const itemIndex = Array.from(repeater.children).indexOf(item);
if (itemIndex >= 0 && tps.timbangan[itemIndex]) {
tps.timbangan[itemIndex].uploaded = false;
-
- const existingUploadBtn = item.querySelector('.btn-upload-timbangan');
- if (!existingUploadBtn) {
- const ocrInfo = item.querySelector('.input-ocr-info');
- const uploadBtn = document.createElement('button');
- uploadBtn.type = 'button';
- uploadBtn.className = 'btn-upload-timbangan w-full bg-blue-500 text-white py-2 rounded-xl font-bold text-xs hover:brightness-110';
- uploadBtn.textContent = 'Upload Foto Timbangan Ini';
- uploadBtn.addEventListener('click', function() {
- uploadSingleFotoTimbangan(itemIndex);
- });
- ocrInfo.parentNode.insertBefore(uploadBtn, ocrInfo.nextSibling);
- }
+ refreshTimbanganUploadState(item);
}
}
});
@@ -649,6 +623,7 @@ const DetailPenjemputan = (function() {
weightInputValue.value = parsed.toFixed(2);
updateTpsTotalTimbangan();
syncTimbanganToTpsData();
+ refreshTimbanganUploadState(item);
});
weightInputDisplay.addEventListener('blur', function() {
@@ -662,6 +637,7 @@ const DetailPenjemputan = (function() {
}
updateTpsTotalTimbangan();
syncTimbanganToTpsData();
+ refreshTimbanganUploadState(item);
});
jenisSampahSelect.addEventListener('change', function() {
@@ -685,16 +661,92 @@ const DetailPenjemputan = (function() {
syncTimbanganToTpsData();
});
- const btnUploadTimbangan = item.querySelector('.btn-upload-timbangan');
- if (btnUploadTimbangan) {
- btnUploadTimbangan.addEventListener('click', function() {
- const itemIndex = Array.from(repeater.children).indexOf(item);
- uploadSingleFotoTimbangan(itemIndex);
- });
+ repeater.appendChild(item);
+ refreshTimbanganUploadState(item);
+ return item;
+ }
+
+ function getTimbanganUploadStateMarkup(hasFile, isUploaded, hasValidWeight) {
+ if (!hasFile) {
+ return '
Pilih foto timbangan terlebih dahulu
';
}
- repeater.appendChild(item);
- return item;
+ if (isUploaded) {
+ return `
+
✓ Foto timbangan sudah diupload
+
Kalau mau revisi, pilih file baru di atas. Status upload akan direset otomatis.
+ `;
+ }
+
+ if (!hasValidWeight) {
+ return `
+
+
Isi berat manual dulu sebelum upload jika berat tidak terbaca.
+ `;
+ }
+
+ return `
+
+
Foto siap diupload.
+ `;
+ }
+
+ function getPetugasUploadStateMarkup(tps) {
+ if (tps.fotoPetugasUploaded) {
+ return '
✓ Foto petugas sudah diupload
';
+ }
+
+ if (!tps.fotoPetugas.length) {
+ return '';
+ }
+
+ if (!tps.namaPetugas.trim()) {
+ return `
+
+
Isi nama petugas terlebih dahulu
+ `;
+ }
+
+ return `
`;
+ }
+
+ function refreshPetugasUploadState(form) {
+ const stateContainer = form.querySelector('.petugas-upload-state');
+ if (!stateContainer) return;
+
+ const tps = state.tpsData[state.activeTpsIndex];
+ stateContainer.innerHTML = getPetugasUploadStateMarkup(tps);
+
+ const btnUploadPetugas = stateContainer.querySelector('.tps-btn-upload-petugas:not([disabled])');
+ if (btnUploadPetugas) {
+ btnUploadPetugas.addEventListener('click', uploadFotoPetugas);
+ }
+ }
+
+ function refreshTimbanganUploadState(item) {
+ const stateContainer = item.querySelector('.timbangan-upload-state');
+ if (!stateContainer) return;
+
+ const repeater = item.parentElement;
+ const itemIndex = repeater ? Array.from(repeater.children).indexOf(item) : -1;
+ const tps = state.tpsData[state.activeTpsIndex];
+ const currentData = itemIndex >= 0 ? tps.timbangan[itemIndex] : null;
+ const fileInput = item.querySelector('.input-foto-timbangan');
+ const hasFile = Boolean(currentData?.file || fileInput?.files?.[0]);
+ const isUploaded = Boolean(currentData?.uploaded);
+ const weightInputValue = item.querySelector('.input-berat-timbangan-value');
+ const currentWeight = currentData?.weight ?? parseWeightInput(weightInputValue?.value || '0');
+ const hasValidWeight = currentWeight > 0;
+
+ stateContainer.innerHTML = getTimbanganUploadStateMarkup(hasFile, isUploaded, hasValidWeight);
+
+ const uploadBtn = stateContainer.querySelector('.btn-upload-timbangan');
+ if (uploadBtn) {
+ uploadBtn.addEventListener('click', function() {
+ const latestIndex = repeater ? Array.from(repeater.children).indexOf(item) : -1;
+ uploadSingleFotoTimbangan(latestIndex, item);
+ });
+ }
}
function renumberTimbanganItems(repeater) {
@@ -1023,26 +1075,27 @@ async function applyWatermark(file, photoNumber) {
const repeater = form.querySelector('.tps-timbangan-repeater');
const items = repeater.querySelectorAll('.timbangan-item');
+ const previousTimbangan = [...tps.timbangan];
tps.timbangan = [];
- items.forEach(item => {
+ items.forEach((item, index) => {
const fileInput = item.querySelector('.input-foto-timbangan');
const weightValue = item.querySelector('.input-berat-timbangan-value');
const jenisSampahSelect = item.querySelector('.input-jenis-sampah');
-
- const existingIndex = tps.timbangan.length;
- const existingData = tps.timbangan[existingIndex];
+ const ocrInfo = item.querySelector('.input-ocr-info')?.textContent || 'OCR: belum diproses.';
+ const existingData = previousTimbangan[index];
tps.timbangan.push({
file: fileInput.files[0] || (existingData ? existingData.file : null),
weight: parseWeightInput(weightValue.value),
jenisSampah: jenisSampahSelect.value,
- uploaded: existingData ? existingData.uploaded : false
+ uploaded: existingData ? existingData.uploaded : false,
+ ocrInfo
});
});
}
- function uploadSingleFotoTimbangan(itemIndex) {
+ function uploadSingleFotoTimbangan(itemIndex, targetItem = null) {
const tps = state.tpsData[state.activeTpsIndex];
if (!tps.timbangan[itemIndex] || !tps.timbangan[itemIndex].file) {
@@ -1051,29 +1104,24 @@ async function applyWatermark(file, photoNumber) {
}
const timbanganItem = tps.timbangan[itemIndex];
+ if (timbanganItem.weight <= 0) {
+ alert('Berat belum valid. Isi manual dulu sebelum upload foto timbangan.');
+ return;
+ }
alert(`Upload foto timbangan #${itemIndex + 1} untuk ${tps.name}\nJenis: ${timbanganItem.jenisSampah}\nBerat: ${timbanganItem.weight} kg\n(Implementasi upload ke server)`);
timbanganItem.uploaded = true;
-
- const form = elements.tpsContentContainer.querySelector('form');
- const repeater = form.querySelector('.tps-timbangan-repeater');
- const items = repeater.querySelectorAll('.timbangan-item');
- const targetItem = items[itemIndex];
-
+
+ if (!targetItem) {
+ const form = elements.tpsContentContainer.querySelector('form');
+ const repeater = form ? form.querySelector('.tps-timbangan-repeater') : null;
+ const items = repeater ? repeater.querySelectorAll('.timbangan-item') : [];
+ targetItem = items[itemIndex] || null;
+ }
+
if (targetItem) {
- const uploadBtn = targetItem.querySelector('.btn-upload-timbangan');
- if (uploadBtn) {
- uploadBtn.remove();
- }
-
- const ocrInfo = targetItem.querySelector('.input-ocr-info');
- if (ocrInfo && !targetItem.querySelector('.upload-success-message')) {
- const successMsg = document.createElement('div');
- successMsg.className = 'text-center text-xs text-green-600 font-bold py-2 upload-success-message';
- successMsg.textContent = '✓ Foto timbangan sudah diupload';
- ocrInfo.parentNode.insertBefore(successMsg, ocrInfo.nextSibling);
- }
+ refreshTimbanganUploadState(targetItem);
}
}
@@ -1096,6 +1144,10 @@ async function applyWatermark(file, photoNumber) {
alert('Belum ada foto petugas yang dipilih!');
return;
}
+ if (!tps.namaPetugas.trim()) {
+ alert('Nama petugas wajib diisi sebelum upload foto petugas!');
+ return;
+ }
alert(`Upload ${tps.fotoPetugas.length} foto petugas untuk ${tps.name}\n(Implementasi upload ke server)`);
diff --git a/wwwroot/driver/json/detail-penjemputan-non-tps.json b/wwwroot/driver/json/detail-penjemputan-non-tps.json
new file mode 100644
index 0000000..c2f91f5
--- /dev/null
+++ b/wwwroot/driver/json/detail-penjemputan-non-tps.json
@@ -0,0 +1,12 @@
+{
+ "detailPenjemputan": {
+ "namaTps": "TPS A",
+ "namaPerusahaan": "CV Tri Berkah Sejahtera",
+ "nomorSpj": "SPJ/07-2025/PKM/000476",
+ "platNomor": "B 9632 TOR",
+ "nomorPintu": "JRC 005",
+ "alamat": "Kp. Pertanian II Rt.004 Rw.001 Kel. Klender Kec, Duren Sawit, Kota Adm. Jakarta Timur 13470",
+ "lokasiAngkutId": "",
+ "spjDetailId": ""
+ }
+}
\ No newline at end of file