diff --git a/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/Index.cshtml b/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/Index.cshtml index 0583751..249de6a 100644 --- a/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/Index.cshtml +++ b/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/Index.cshtml @@ -4,6 +4,10 @@ }
+ +
diff --git a/Views/Admin/Transport/SpjDriverUpst/Shared/_Layout.cshtml b/Views/Admin/Transport/SpjDriverUpst/Shared/_Layout.cshtml index d71bea0..1341a48 100644 --- a/Views/Admin/Transport/SpjDriverUpst/Shared/_Layout.cshtml +++ b/Views/Admin/Transport/SpjDriverUpst/Shared/_Layout.cshtml @@ -31,7 +31,6 @@ - @await RenderSectionAsync("Styles", required: false) diff --git a/package.json b/package.json index 70fea3a..d814c5c 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,7 @@ "tailwindcss": "^4.1.11" }, "scripts": { - "dev": "npx tailwindcss -i ./wwwroot/driver/css/site.css -o ./wwwroot/driver/css/watch.css --watch & dotnet watch run", - "watch": "npx @tailwindcss/cli -i ./wwwroot/driver/css/site.css -o ./wwwroot/driver/css/watch.css --watch", + "dev": "npx @tailwindcss/cli -i ./wwwroot/driver/css/site.css -o ./wwwroot/driver/css/watch.css --watch", "build": "npx @tailwindcss/cli -i ./wwwroot/driver/css/site.css -o ./wwwroot/driver/css/watch.css --minify" } } diff --git a/wwwroot/driver/css/site.css b/wwwroot/driver/css/site.css index e081c4f..8a110ee 100644 --- a/wwwroot/driver/css/site.css +++ b/wwwroot/driver/css/site.css @@ -6,4 +6,8 @@ .bg-upst-light { @apply bg-[#e4f2e3]; +} + +body { + font-family: "Inter Tight", sans-serif; } \ No newline at end of file diff --git a/wwwroot/driver/css/watch.css b/wwwroot/driver/css/watch.css index a0a0d7b..02a4611 100644 --- a/wwwroot/driver/css/watch.css +++ b/wwwroot/driver/css/watch.css @@ -905,6 +905,9 @@ .h-32 { height: calc(var(--spacing) * 32); } + .h-40 { + height: calc(var(--spacing) * 40); + } .h-44 { height: calc(var(--spacing) * 44); } @@ -1157,6 +1160,9 @@ .grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } + .grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } .grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } @@ -1574,6 +1580,9 @@ .border-yellow-200 { border-color: var(--color-yellow-200); } + .border-t-red-500 { + border-top-color: var(--color-red-500); + } .border-t-transparent { border-top-color: transparent; } @@ -2854,11 +2863,21 @@ border-width: 0px; } } + .file\:bg-red-500 { + &::file-selector-button { + background-color: var(--color-red-500); + } + } .file\:px-3 { &::file-selector-button { padding-inline: calc(var(--spacing) * 3); } } + .file\:px-4 { + &::file-selector-button { + padding-inline: calc(var(--spacing) * 4); + } + } .file\:py-2 { &::file-selector-button { padding-block: calc(var(--spacing) * 2); @@ -2979,6 +2998,13 @@ } } } + .hover\:bg-green-200 { + &:hover { + @media (hover: hover) { + background-color: var(--color-green-200); + } + } + } .hover\:bg-green-600 { &:hover { @media (hover: hover) { @@ -3068,6 +3094,14 @@ } } } + .hover\:to-gray-700 { + &:hover { + @media (hover: hover) { + --tw-gradient-to: var(--color-gray-700); + --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position)); + } + } + } .hover\:to-orange-500 { &:hover { @media (hover: hover) { @@ -3151,6 +3185,15 @@ } } } + .hover\:file\:bg-red-600 { + &:hover { + @media (hover: hover) { + &::file-selector-button { + background-color: var(--color-red-600); + } + } + } + } .focus\:border-gray-500 { &:focus { border-color: var(--color-gray-500); @@ -3236,6 +3279,9 @@ .bg-upst-light { background-color: #e4f2e3; } +body { + font-family: "Inter Tight", sans-serif; +} @property --tw-translate-x { syntax: "*"; inherits: false; diff --git a/wwwroot/driver/css/website.css b/wwwroot/driver/css/website.css deleted file mode 100644 index 1fb150f..0000000 --- a/wwwroot/driver/css/website.css +++ /dev/null @@ -1,3 +0,0 @@ -body { - font-family: "Inter Tight", sans-serif; -} diff --git a/wwwroot/driver/js/detail-penjemputan.js b/wwwroot/driver/js/detail-penjemputan.js index 9a1951c..e531fd2 100644 --- a/wwwroot/driver/js/detail-penjemputan.js +++ b/wwwroot/driver/js/detail-penjemputan.js @@ -157,11 +157,19 @@ const DetailPenjemputan = (function() { state.tpsData.forEach((tps, index) => { const tab = document.createElement('button'); tab.type = 'button'; - tab.className = `px-4 py-2 rounded-xl font-bold text-sm whitespace-nowrap transition ${ - index === state.activeTpsIndex - ? 'bg-upst text-white' - : 'bg-gray-100 text-gray-600 hover:bg-gray-200' - }`; + const isActive = index === state.activeTpsIndex; + const isSubmitted = !!tps.submitted; + + let tabClass = 'bg-gray-100 text-gray-600 hover:bg-gray-200'; + if (isSubmitted) { + tabClass = isActive + ? 'bg-green-600 text-white' + : 'bg-green-100 text-green-700 hover:bg-green-200'; + } else if (isActive) { + tabClass = 'bg-upst text-white'; + } + + tab.className = `px-4 py-2 rounded-xl font-bold text-sm whitespace-nowrap transition ${tabClass}`; tab.textContent = tps.name; if (tps.submitted) { tab.innerHTML += ' '; @@ -517,7 +525,6 @@ const DetailPenjemputan = (function() { } function createTimbanganItem(repeater, existingData = null) { - // Calculate photo number dynamically based on position const photoNumber = repeater.children.length + 1; const item = document.createElement('div'); @@ -586,7 +593,6 @@ const DetailPenjemputan = (function() { const watermarkedFile = await applyWatermark(originalFile, photoNumber); - // Update file input dengan watermarked file const dataTransfer = new DataTransfer(); dataTransfer.items.add(watermarkedFile); fileInput.files = dataTransfer.files; @@ -657,7 +663,6 @@ const DetailPenjemputan = (function() { const form = elements.tpsContentContainer.querySelector('form'); const repeater = form ? form.querySelector('.tps-timbangan-repeater') : null; - // Renumber all remaining items if (repeater) { renumberTimbanganItems(repeater); if (repeater.children.length === 0) { @@ -687,7 +692,6 @@ const DetailPenjemputan = (function() { const newNumber = index + 1; item.dataset.photoNumber = newNumber; - // Update label text const label = item.querySelector('.text-xs.font-bold.text-gray-600'); if (label) { label.textContent = `Item Timbangan #${newNumber}`; @@ -769,7 +773,6 @@ async function applyWatermark(file, photoNumber) { ctx.fillStyle = 'rgba(15, 23, 42, 0.85)'; ctx.fill(); - // Garis Aksen Vertikal ctx.beginPath(); const accentWidth = baseFontSize * 0.3; if (ctx.roundRect) { @@ -1089,6 +1092,48 @@ async function applyWatermark(file, photoNumber) { renderTpsForm(); } + function buildSubmitFormData(tps) { + const formData = new FormData(); + formData.append('TpsName', tps.name); + formData.append('Latitude', tps.latitude); + formData.append('Longitude', tps.longitude); + formData.append('AlamatJalan', tps.alamatJalan); + formData.append('WaktuKedatangan', tps.waktuKedatangan); + formData.append('TotalTimbangan', tps.totalTimbangan); + formData.append('TotalOrganik', tps.totalOrganik); + formData.append('TotalAnorganik', tps.totalAnorganik); + formData.append('TotalResidu', tps.totalResidu); + formData.append('NamaPetugas', tps.namaPetugas); + + tps.fotoKedatangan.forEach((file) => { + formData.append('FotoKedatangan', file); + }); + + tps.timbangan.forEach((timb) => { + if (timb.file) formData.append('FotoTimbangan', timb.file); + formData.append('BeratTimbangan', timb.weight); + formData.append('JenisSampahList', timb.jenisSampah); + }); + + tps.fotoPetugas.forEach((file) => { + formData.append('FotoPetugas', file); + }); + + const antiForgeryTokenEl = document.querySelector('#upst-antiforgery input[name="__RequestVerificationToken"]'); + if (antiForgeryTokenEl && antiForgeryTokenEl.value) { + formData.append('__RequestVerificationToken', antiForgeryTokenEl.value); + } + + return formData; + } + + function markTpsSubmitted(tps) { + tps.submitted = true; + if (state.selectedTpsList.length > 1) { + renderTabs(); + } + } + function submitTpsData() { const tps = state.tpsData[state.activeTpsIndex]; @@ -1109,56 +1154,40 @@ async function applyWatermark(file, photoNumber) { return; } - const formData = new FormData(); - formData.append('TpsName', tps.name); - formData.append('Latitude', tps.latitude); - formData.append('Longitude', tps.longitude); - formData.append('AlamatJalan', tps.alamatJalan); - formData.append('WaktuKedatangan', tps.waktuKedatangan); - formData.append('TotalTimbangan', tps.totalTimbangan); - formData.append('TotalOrganik', tps.totalOrganik); - formData.append('TotalAnorganik', tps.totalAnorganik); - formData.append('TotalResidu', tps.totalResidu); - formData.append('NamaPetugas', tps.namaPetugas); - - tps.fotoKedatangan.forEach((file) => { - formData.append(`FotoKedatangan`, file); - }); - - tps.timbangan.forEach((timb) => { - if (timb.file) formData.append(`FotoTimbangan`, timb.file); - formData.append(`BeratTimbangan`, timb.weight); - formData.append(`JenisSampahList`, timb.jenisSampah); - }); - - tps.fotoPetugas.forEach((file) => { - formData.append(`FotoPetugas`, file); - }); + // MODE STATIK (aktif sekarang) + // Cuma validasi + tandai TPS selesai, ga kirim ke backend. + markTpsSubmitted(tps); + alert(`Validasi ${tps.name} OK. Data belum dikirim ke server (mode statik).`); + + // MODE PRODUCTION (aktifkan kalau backend udah ready mas ebik) + /* + const formData = buildSubmitFormData(tps); - // Submit to server fetch('/upst/detail-penjemputan', { method: 'POST', body: formData }) - .then(response => { + .then(async response => { if (response.ok) { - tps.submitted = true; - if (state.selectedTpsList.length > 1) { - renderTabs(); - } + markTpsSubmitted(tps); alert(`Data ${tps.name} berhasil disimpan!`); window.location.reload(); } else { - alert('Gagal menyimpan data. Silakan coba lagi.'); + const errorText = await response.text(); + if (response.status === 400) { + alert('Sesi submit tidak valid. Silakan refresh halaman lalu coba lagi.'); + } else { + alert(errorText || 'Gagal menyimpan data. Silakan coba lagi.'); + } } }) .catch(error => { console.error('Error:', error); alert('Terjadi kesalahan saat menyimpan data.'); }); + */ } - // Utility functions function formatWeightDisplay(value) { if (isNaN(value)) return '0,00'; return value.toFixed(2).replace('.', ','); @@ -1176,7 +1205,6 @@ async function applyWatermark(file, photoNumber) { return `${mb.toFixed(2)} MB`; } - // Public API return { init: init, setNomorSpj: function(nomorSpj) {