diff --git a/wwwroot/driver/js/detail-penjemputan-non-tps.js b/wwwroot/driver/js/detail-penjemputan-non-tps.js index e0be3c2..a3d6e9a 100644 --- a/wwwroot/driver/js/detail-penjemputan-non-tps.js +++ b/wwwroot/driver/js/detail-penjemputan-non-tps.js @@ -94,6 +94,7 @@ document.addEventListener('DOMContentLoaded', function() { function renderTpsForm() { const tps = tpsData[activeTpsIndex]; + const submitState = getSubmitState(tps); tpsContentContainer.innerHTML = `
`; @@ -703,6 +705,64 @@ document.addEventListener('DOMContentLoaded', function() { if (btnUploadPetugas) { btnUploadPetugas.addEventListener('click', uploadFotoPetugas); } + + refreshSubmitButtonState(form); + } + + function isTimbanganItemReady(timbanganItem) { + const weight = timbanganItem?.berat && timbanganItem.berat.length > 0 ? timbanganItem.berat[0] : 0; + return Boolean(timbanganItem?.file) && Boolean(timbanganItem?.uploaded) && weight > 0; + } + + function getSubmitState(tps) { + if (!tps.fotoKedatangan.length || !tps.fotoKedatanganUploaded) { + return { canSubmit: false, message: 'Upload foto kedatangan dulu sebelum submit.' }; + } + + if (!tps.timbangan.length) { + return { canSubmit: false, message: 'Tambahkan minimal 1 data timbangan sebelum submit.' }; + } + + if (tps.timbangan.some(item => !isTimbanganItemReady(item))) { + return { canSubmit: false, message: 'Pastikan semua foto timbangan sudah diupload dan beratnya valid.' }; + } + + if (!tps.fotoPetugas.length || !tps.fotoPetugasUploaded) { + return { canSubmit: false, message: 'Upload foto petugas dulu sebelum submit.' }; + } + + if (!tps.namaPetugas.trim()) { + return { canSubmit: false, message: 'Isi nama petugas dulu sebelum submit.' }; + } + + return { canSubmit: true, message: '' }; + } + + function refreshSubmitButtonState(form) { + const submitButton = form.querySelector('button[type="submit"]'); + if (!submitButton) return; + + const helperText = form.querySelector('.submit-state-message'); + const tps = tpsData[activeTpsIndex]; + const submitState = getSubmitState(tps); + + submitButton.disabled = !submitState.canSubmit; + submitButton.className = `w-2/3 py-3 rounded-xl font-bold text-sm transition ${submitState.canSubmit ? 'bg-upst text-white hover:brightness-110' : 'bg-gray-300 text-gray-500 cursor-not-allowed'}`; + + let messageEl = helperText; + if (!messageEl) { + messageEl = document.createElement('p'); + messageEl.className = 'submit-state-message text-[11px] text-center text-red-500 font-medium'; + submitButton.closest('.flex.gap-3')?.insertAdjacentElement('afterend', messageEl); + } + + if (submitState.canSubmit) { + messageEl.textContent = ''; + messageEl.classList.add('hidden'); + } else { + messageEl.textContent = submitState.message; + messageEl.classList.remove('hidden'); + } } function refreshTimbanganUploadState(item) { @@ -731,6 +791,11 @@ document.addEventListener('DOMContentLoaded', function() { uploadSingleFotoTimbangan(latestIndex, item); }); } + + const form = tpsContentContainer.querySelector('form'); + if (form) { + refreshSubmitButtonState(form); + } } function renumberTimbanganItems(repeater) { @@ -838,6 +903,8 @@ document.addEventListener('DOMContentLoaded', function() { updateTpsTotalTimbangan(); syncTimbanganToTpsData(); refreshTimbanganUploadState(item); + const form = tpsContentContainer.querySelector('form'); + if (form) refreshSubmitButtonState(form); }); weightInputDisplay.addEventListener('blur', function() { @@ -852,11 +919,15 @@ document.addEventListener('DOMContentLoaded', function() { updateTpsTotalTimbangan(); syncTimbanganToTpsData(); refreshTimbanganUploadState(item); + const form = tpsContentContainer.querySelector('form'); + if (form) refreshSubmitButtonState(form); }); jenisSampahSelect.addEventListener('change', function() { updateTpsTotalTimbangan(); syncTimbanganToTpsData(); + const form = tpsContentContainer.querySelector('form'); + if (form) refreshSubmitButtonState(form); }); removeBtn.addEventListener('click', function() { @@ -869,6 +940,7 @@ document.addEventListener('DOMContentLoaded', function() { } updateTpsTotalTimbangan(); syncTimbanganToTpsData(); + if (form) refreshSubmitButtonState(form); }); repeater.appendChild(item); @@ -962,6 +1034,9 @@ document.addEventListener('DOMContentLoaded', function() { if (targetItem) { refreshTimbanganUploadState(targetItem); } + + const form = tpsContentContainer.querySelector('form'); + if (form) refreshSubmitButtonState(form); } function uploadFotoKedatangan() { @@ -992,10 +1067,8 @@ document.addEventListener('DOMContentLoaded', function() { function submitTpsData() { const tps = tpsData[activeTpsIndex]; - if (!tps.fotoKedatangan.length) return alert('Foto kedatangan belum diupload!'); - if (!tps.timbangan.length) return alert('Belum ada data timbangan!'); - if (!tps.fotoPetugas.length) return alert('Foto petugas belum diupload!'); - if (!tps.namaPetugas.trim()) return alert('Nama petugas belum diisi!'); + const submitState = getSubmitState(tps); + if (!submitState.canSubmit) return alert(submitState.message); 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; diff --git a/wwwroot/driver/js/detail-penjemputan-tps.js b/wwwroot/driver/js/detail-penjemputan-tps.js index fe86162..32ab695 100644 --- a/wwwroot/driver/js/detail-penjemputan-tps.js +++ b/wwwroot/driver/js/detail-penjemputan-tps.js @@ -204,6 +204,7 @@ const DetailPenjemputan = (function() { function renderTpsForm() { const tps = state.tpsData[state.activeTpsIndex]; const showTpsName = state.selectedTpsList.length > 1 || state.availableTpsList.length > 0; + const submitState = getSubmitState(tps); elements.tpsContentContainer.innerHTML = ` `; @@ -624,6 +626,8 @@ const DetailPenjemputan = (function() { updateTpsTotalTimbangan(); syncTimbanganToTpsData(); refreshTimbanganUploadState(item); + const form = elements.tpsContentContainer.querySelector('form'); + if (form) refreshSubmitButtonState(form); }); weightInputDisplay.addEventListener('blur', function() { @@ -638,11 +642,15 @@ const DetailPenjemputan = (function() { updateTpsTotalTimbangan(); syncTimbanganToTpsData(); refreshTimbanganUploadState(item); + const form = elements.tpsContentContainer.querySelector('form'); + if (form) refreshSubmitButtonState(form); }); jenisSampahSelect.addEventListener('change', function() { updateTpsTotalTimbangan(); syncTimbanganToTpsData(); + const form = elements.tpsContentContainer.querySelector('form'); + if (form) refreshSubmitButtonState(form); }); removeBtn.addEventListener('click', function() { @@ -659,6 +667,7 @@ const DetailPenjemputan = (function() { updateTpsTotalTimbangan(); syncTimbanganToTpsData(); + if (form) refreshSubmitButtonState(form); }); repeater.appendChild(item); @@ -721,6 +730,62 @@ const DetailPenjemputan = (function() { if (btnUploadPetugas) { btnUploadPetugas.addEventListener('click', uploadFotoPetugas); } + + refreshSubmitButtonState(form); + } + + function isTimbanganItemReady(timbanganItem) { + return Boolean(timbanganItem?.file) && Boolean(timbanganItem?.uploaded) && (timbanganItem?.weight || 0) > 0; + } + + function getSubmitState(tps) { + if (!tps.fotoKedatangan.length || !tps.fotoKedatanganUploaded) { + return { canSubmit: false, message: 'Upload foto kedatangan dulu sebelum submit.' }; + } + + if (!tps.timbangan.length) { + return { canSubmit: false, message: 'Tambahkan minimal 1 data timbangan sebelum submit.' }; + } + + if (tps.timbangan.some(item => !isTimbanganItemReady(item))) { + return { canSubmit: false, message: 'Pastikan semua foto timbangan sudah diupload dan beratnya valid.' }; + } + + if (!tps.fotoPetugas.length || !tps.fotoPetugasUploaded) { + return { canSubmit: false, message: 'Upload foto petugas dulu sebelum submit.' }; + } + + if (!tps.namaPetugas.trim()) { + return { canSubmit: false, message: 'Isi nama petugas dulu sebelum submit.' }; + } + + return { canSubmit: true, message: '' }; + } + + function refreshSubmitButtonState(form) { + const submitButton = form.querySelector('button[type="submit"]'); + if (!submitButton) return; + + let messageEl = form.querySelector('.submit-state-message'); + const tps = state.tpsData[state.activeTpsIndex]; + const submitState = getSubmitState(tps); + + submitButton.disabled = !submitState.canSubmit; + submitButton.className = `w-2/3 py-3 rounded-xl font-bold text-sm transition ${submitState.canSubmit ? 'bg-upst text-white hover:brightness-110' : 'bg-gray-300 text-gray-500 cursor-not-allowed'}`; + + if (!messageEl) { + messageEl = document.createElement('p'); + messageEl.className = 'submit-state-message text-[11px] text-center text-red-500 font-medium'; + submitButton.closest('.flex.gap-3')?.insertAdjacentElement('afterend', messageEl); + } + + if (submitState.canSubmit) { + messageEl.textContent = ''; + messageEl.classList.add('hidden'); + } else { + messageEl.textContent = submitState.message; + messageEl.classList.remove('hidden'); + } } function refreshTimbanganUploadState(item) { @@ -747,6 +812,11 @@ const DetailPenjemputan = (function() { uploadSingleFotoTimbangan(latestIndex, item); }); } + + const form = elements.tpsContentContainer.querySelector('form'); + if (form) { + refreshSubmitButtonState(form); + } } function renumberTimbanganItems(repeater) { @@ -1123,6 +1193,9 @@ async function applyWatermark(file, photoNumber) { if (targetItem) { refreshTimbanganUploadState(targetItem); } + + const form = elements.tpsContentContainer.querySelector('form'); + if (form) refreshSubmitButtonState(form); } function uploadFotoKedatangan() { @@ -1201,21 +1274,9 @@ async function applyWatermark(file, photoNumber) { function submitTpsData() { const tps = state.tpsData[state.activeTpsIndex]; - - if (!tps.fotoKedatangan.length) { - alert('Foto kedatangan belum diupload!'); - return; - } - if (!tps.timbangan.length) { - alert('Belum ada data timbangan!'); - return; - } - if (!tps.fotoPetugas.length) { - alert('Foto petugas belum diupload!'); - return; - } - if (!tps.namaPetugas.trim()) { - alert('Nama petugas belum diisi!'); + const submitState = getSubmitState(tps); + if (!submitState.canSubmit) { + alert(submitState.message); return; }