update: non tps ganti jadi 1 TPS, fixing js non tps
parent
4e6675d782
commit
8a7ce4a228
|
|
@ -1,6 +1,6 @@
|
||||||
@{
|
@{
|
||||||
Layout = "~/Views/Admin/Transport/SpjDriverUpst/Shared/_Layout.cshtml";
|
Layout = "~/Views/Admin/Transport/SpjDriverUpst/Shared/_Layout.cshtml";
|
||||||
ViewData["Title"] = "Detail Penjemputan - Tanpa TPS";
|
ViewData["Title"] = "Detail Penjemputan - TPS A";
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="w-full lg:max-w-sm mx-auto min-h-screen bg-gray-50 pb-24">
|
<div class="w-full lg:max-w-sm mx-auto min-h-screen bg-gray-50 pb-24">
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
<a href="@Url.Action("Index", "Home")" class="w-10 h-10 flex items-center justify-center bg-white/10 rounded-xl backdrop-blur-md">
|
<a href="@Url.Action("Index", "Home")" class="w-10 h-10 flex items-center justify-center bg-white/10 rounded-xl backdrop-blur-md">
|
||||||
<i class="w-5 h-5" data-lucide="chevron-left"></i>
|
<i class="w-5 h-5" data-lucide="chevron-left"></i>
|
||||||
</a>
|
</a>
|
||||||
<h1 class="text-lg font-black uppercase tracking-tight">Detail Lokasi</h1>
|
<h1 id="detail-page-title" class="text-lg font-black uppercase tracking-tight">TPS A</h1>
|
||||||
<div class="w-10"></div>
|
<div class="w-10"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
<div class="h-8 w-[1px] bg-gray-100"></div>
|
<div class="h-8 w-[1px] bg-gray-100"></div>
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<span class="text-[10px] font-black text-gray-400 uppercase tracking-widest">No. Pintu</span>
|
<span class="text-[10px] font-black text-gray-400 uppercase tracking-widest">No. Pintu</span>
|
||||||
<p class="text-orange-500 font-bold text-sm">JRC 005</p>
|
<p id="detail-nomor-pintu" class="text-orange-500 font-bold text-sm">JRC 005</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -35,24 +35,24 @@
|
||||||
<div class="px-6 space-y-6">
|
<div class="px-6 space-y-6">
|
||||||
<div class="bg-white rounded-[32px] p-6 border border-gray-100 relative overflow-hidden">
|
<div class="bg-white rounded-[32px] p-6 border border-gray-100 relative overflow-hidden">
|
||||||
<div class="absolute top-0 right-0 p-4">
|
<div class="absolute top-0 right-0 p-4">
|
||||||
<span class="px-3 py-1 bg-gray-500 text-white rounded-full text-[10px] font-black tracking-tighter uppercase">
|
<span id="detail-tps-badge" class="px-3 py-1 bg-gray-500 text-white rounded-full text-[10px] font-black tracking-tighter uppercase">
|
||||||
TANPA TPS
|
TPS A
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<p class="text-[10px] text-gray-400 uppercase tracking-widest mb-1">Perusahaan</p>
|
<p class="text-[10px] text-gray-400 uppercase tracking-widest mb-1">Perusahaan</p>
|
||||||
<h2 class="text-xl font-black text-gray-800 leading-tight">CV Tri Berkah Sejahtera</h2>
|
<h2 id="detail-company-name" class="text-xl font-black text-gray-800 leading-tight">CV Tri Berkah Sejahtera</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center justify-center gap-2 bg-gray-50 p-2 rounded-xl">
|
<div class="flex items-center justify-center gap-2 bg-gray-50 p-2 rounded-xl">
|
||||||
<p class="text-gray-600 font-mono text-xl font-bold uppercase tracking-tighter">SPJ/07-2025/PKM/000476</p>
|
<p id="detail-spj-number" class="text-gray-600 font-mono text-xl font-bold uppercase tracking-tighter">SPJ/07-2025/PKM/000476</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pt-2 border-t border-gray-50">
|
<div class="pt-2 border-t border-gray-50">
|
||||||
<div class="flex gap-2 items-start">
|
<div class="flex gap-2 items-start">
|
||||||
<p class="text-gray-500 text-xs font-medium leading-relaxed">
|
<p id="detail-address" class="text-gray-500 text-xs font-medium leading-relaxed">
|
||||||
Kp. Pertanian II Rt.004 Rw.001 Kel. Klender Kec, Duren Sawit, Kota Adm. Jakarta Timur 13470
|
Kp. Pertanian II Rt.004 Rw.001 Kel. Klender Kec, Duren Sawit, Kota Adm. Jakarta Timur 13470
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -87,9 +87,8 @@
|
||||||
|
|
||||||
<div id="tps-tabs-container" class="bg-white rounded-[32px] p-6 border border-gray-100">
|
<div id="tps-tabs-container" class="bg-white rounded-[32px] p-6 border border-gray-100">
|
||||||
<div class="flex items-center gap-2 mb-4">
|
<div class="flex items-center gap-2 mb-4">
|
||||||
<div class="w-2 h-2 rounded-full bg-gray-400"></div>
|
|
||||||
<h3 class="font-black text-gray-800">Form Pengangkutan</h3>
|
<h3 class="font-black text-gray-800">Form Pengangkutan</h3>
|
||||||
<span class="ml-auto text-[10px] font-bold text-gray-500 bg-gray-100 px-3 py-1 rounded-full">Tanpa TPS</span>
|
<span id="detail-form-badge" class="ml-auto text-[10px] font-bold text-gray-500 bg-gray-100 px-3 py-1 rounded-full">TPS A</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="tps-content">
|
<div id="tps-content">
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,25 @@
|
||||||
<p class="text-[10px] truncate italic">Jakarta Timur 13470</p>
|
<p class="text-[10px] truncate italic">Jakarta Timur 13470</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<span class="text-[9px] font-bold text-blue-600 bg-blue-50 px-2 py-1 rounded-lg">Ada 3 TPS</span>
|
<span class="text-[9px] font-bold text-blue-600 bg-blue-50 px-2 py-1 rounded-lg">3 TPS</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="@Url.Action("TanpaTps", "DetailPenjemputan")" class="block relative pl-12 group">
|
||||||
|
<div class="absolute left-4 top-1 w-4 h-4 bg-white border-4 border-gray-400 rounded-full z-10"></div>
|
||||||
|
<div class="bg-white p-4 rounded-3xl border border-gray-100 shadow-sm group-active:bg-gray-50 transition-colors">
|
||||||
|
<div class="flex justify-between items-start mb-2">
|
||||||
|
<span class="text-[9px] font-black text-gray-400 uppercase tracking-widest">Proses</span>
|
||||||
|
<i class="w-4 h-4 text-gray-300" data-lucide="loader"></i>
|
||||||
|
</div>
|
||||||
|
<h4 class="font-bold text-gray-800 text-sm leading-tight">CV Tri Berkah Sejahtera</h4>
|
||||||
|
<div class="flex items-center gap-1 mt-2 text-gray-500">
|
||||||
|
<i class="w-3 h-3" data-lucide="map"></i>
|
||||||
|
<p class="text-[10px] truncate italic">Duren Sawit, Jakarta Timur</p>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2">
|
||||||
|
<span class="text-[9px] font-bold text-gray-600 bg-gray-100 px-2 py-1 rounded-lg">1 TPS</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -149,7 +167,7 @@
|
||||||
<h4 class="font-bold text-gray-800 text-sm leading-tight">CV Tri Mitra Utama - Shell Radio Dalam</h4>
|
<h4 class="font-bold text-gray-800 text-sm leading-tight">CV Tri Mitra Utama - Shell Radio Dalam</h4>
|
||||||
<p class="text-[10px] text-green-700/60 mt-2">Jakarta Selatan</p>
|
<p class="text-[10px] text-green-700/60 mt-2">Jakarta Selatan</p>
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<span class="text-[9px] font-bold text-blue-600 bg-blue-50 px-2 py-1 rounded-lg">Ada 3 TPS</span>
|
<span class="text-[9px] font-bold text-blue-600 bg-blue-50 px-2 py-1 rounded-lg">3 TPS</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -164,7 +182,7 @@
|
||||||
<h4 class="font-bold text-gray-800 text-sm leading-tight">CV Tri Berkah Sejahtera</h4>
|
<h4 class="font-bold text-gray-800 text-sm leading-tight">CV Tri Berkah Sejahtera</h4>
|
||||||
<p class="text-[10px] text-green-700/60 mt-2">Duren Sawit, Jakarta Timur</p>
|
<p class="text-[10px] text-green-700/60 mt-2">Duren Sawit, Jakarta Timur</p>
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<span class="text-[9px] font-bold text-gray-600 bg-gray-100 px-2 py-1 rounded-lg">Tidak ada TPS</span>
|
<span class="text-[9px] font-bold text-gray-600 bg-gray-100 px-2 py-1 rounded-lg">1 TPS</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -109,8 +109,6 @@
|
||||||
--text-xl--line-height: calc(1.75 / 1.25);
|
--text-xl--line-height: calc(1.75 / 1.25);
|
||||||
--text-2xl: 1.5rem;
|
--text-2xl: 1.5rem;
|
||||||
--text-2xl--line-height: calc(2 / 1.5);
|
--text-2xl--line-height: calc(2 / 1.5);
|
||||||
--text-5xl: 3rem;
|
|
||||||
--text-5xl--line-height: 1;
|
|
||||||
--font-weight-medium: 500;
|
--font-weight-medium: 500;
|
||||||
--font-weight-semibold: 600;
|
--font-weight-semibold: 600;
|
||||||
--font-weight-bold: 700;
|
--font-weight-bold: 700;
|
||||||
|
|
@ -569,12 +567,6 @@
|
||||||
.col-auto {
|
.col-auto {
|
||||||
grid-column: 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-end {
|
||||||
float: inline-end;
|
float: inline-end;
|
||||||
}
|
}
|
||||||
|
|
@ -806,12 +798,6 @@
|
||||||
.ml-auto {
|
.ml-auto {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
.line-clamp-2 {
|
|
||||||
overflow: hidden;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
}
|
|
||||||
.line-clamp-3 {
|
.line-clamp-3 {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
|
|
@ -875,9 +861,6 @@
|
||||||
.h-3 {
|
.h-3 {
|
||||||
height: calc(var(--spacing) * 3);
|
height: calc(var(--spacing) * 3);
|
||||||
}
|
}
|
||||||
.h-3\.5 {
|
|
||||||
height: calc(var(--spacing) * 3.5);
|
|
||||||
}
|
|
||||||
.h-4 {
|
.h-4 {
|
||||||
height: calc(var(--spacing) * 4);
|
height: calc(var(--spacing) * 4);
|
||||||
}
|
}
|
||||||
|
|
@ -986,9 +969,6 @@
|
||||||
.w-3 {
|
.w-3 {
|
||||||
width: calc(var(--spacing) * 3);
|
width: calc(var(--spacing) * 3);
|
||||||
}
|
}
|
||||||
.w-3\.5 {
|
|
||||||
width: calc(var(--spacing) * 3.5);
|
|
||||||
}
|
|
||||||
.w-4 {
|
.w-4 {
|
||||||
width: calc(var(--spacing) * 4);
|
width: calc(var(--spacing) * 4);
|
||||||
}
|
}
|
||||||
|
|
@ -1235,9 +1215,6 @@
|
||||||
.gap-1 {
|
.gap-1 {
|
||||||
gap: calc(var(--spacing) * 1);
|
gap: calc(var(--spacing) * 1);
|
||||||
}
|
}
|
||||||
.gap-1\.5 {
|
|
||||||
gap: calc(var(--spacing) * 1.5);
|
|
||||||
}
|
|
||||||
.gap-2 {
|
.gap-2 {
|
||||||
gap: calc(var(--spacing) * 2);
|
gap: calc(var(--spacing) * 2);
|
||||||
}
|
}
|
||||||
|
|
@ -1691,6 +1668,9 @@
|
||||||
.bg-gray-200 {
|
.bg-gray-200 {
|
||||||
background-color: var(--color-gray-200);
|
background-color: var(--color-gray-200);
|
||||||
}
|
}
|
||||||
|
.bg-gray-300 {
|
||||||
|
background-color: var(--color-gray-300);
|
||||||
|
}
|
||||||
.bg-gray-400 {
|
.bg-gray-400 {
|
||||||
background-color: var(--color-gray-400);
|
background-color: var(--color-gray-400);
|
||||||
}
|
}
|
||||||
|
|
@ -2138,9 +2118,6 @@
|
||||||
.py-1 {
|
.py-1 {
|
||||||
padding-block: calc(var(--spacing) * 1);
|
padding-block: calc(var(--spacing) * 1);
|
||||||
}
|
}
|
||||||
.py-1\.5 {
|
|
||||||
padding-block: calc(var(--spacing) * 1.5);
|
|
||||||
}
|
|
||||||
.py-2 {
|
.py-2 {
|
||||||
padding-block: calc(var(--spacing) * 2);
|
padding-block: calc(var(--spacing) * 2);
|
||||||
}
|
}
|
||||||
|
|
@ -2159,9 +2136,6 @@
|
||||||
.py-6 {
|
.py-6 {
|
||||||
padding-block: calc(var(--spacing) * 6);
|
padding-block: calc(var(--spacing) * 6);
|
||||||
}
|
}
|
||||||
.py-10 {
|
|
||||||
padding-block: calc(var(--spacing) * 10);
|
|
||||||
}
|
|
||||||
.py-12 {
|
.py-12 {
|
||||||
padding-block: calc(var(--spacing) * 12);
|
padding-block: calc(var(--spacing) * 12);
|
||||||
}
|
}
|
||||||
|
|
@ -2436,12 +2410,6 @@
|
||||||
.text-blue-700 {
|
.text-blue-700 {
|
||||||
color: var(--color-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 {
|
.text-blue-800 {
|
||||||
color: var(--color-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 {
|
.group-hover\:text-gray-500 {
|
||||||
&:is(:where(.group):hover *) {
|
&:is(:where(.group):hover *) {
|
||||||
@media (hover: 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 {
|
.group-hover\:shadow-md {
|
||||||
&:is(:where(.group):hover *) {
|
&:is(:where(.group):hover *) {
|
||||||
@media (hover: 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\:border-orange-200 {
|
||||||
&:hover {
|
&:hover {
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
|
|
@ -3346,11 +3292,6 @@
|
||||||
scale: var(--tw-scale-x) var(--tw-scale-y);
|
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 {
|
.lg\:max-w-sm {
|
||||||
@media (width >= 64rem) {
|
@media (width >= 64rem) {
|
||||||
max-width: var(--container-sm);
|
max-width: var(--container-sm);
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
];
|
];
|
||||||
const JENIS_SAMPAH = ['Organik', 'Anorganik', 'Residu'];
|
const JENIS_SAMPAH = ['Organik', 'Anorganik', 'Residu'];
|
||||||
const DEFAULT_JENIS = '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() {
|
function initializeLocation() {
|
||||||
tpsData = [{
|
tpsData = [{
|
||||||
name: '',
|
name: DEFAULT_TPS_NAME,
|
||||||
index: 0,
|
index: 0,
|
||||||
lokasiAngkutId: '',
|
lokasiAngkutId: '',
|
||||||
spjDetailId: '',
|
spjDetailId: '',
|
||||||
|
|
@ -43,6 +45,53 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
renderTpsForm();
|
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() {
|
function renderTpsForm() {
|
||||||
const tps = tpsData[activeTpsIndex];
|
const tps = tpsData[activeTpsIndex];
|
||||||
|
|
||||||
|
|
@ -62,7 +111,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<div class="w-8 h-8 rounded-full bg-upst text-white font-black text-sm flex items-center justify-center">1</div>
|
<div class="w-8 h-8 rounded-full bg-upst text-white font-black text-sm flex items-center justify-center">1</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="font-black text-gray-800">Foto Kedatangan</h3>
|
<h3 class="font-black text-gray-800">Foto Kedatangan </h3>
|
||||||
<p class="text-xs text-gray-500">Upload foto kedatangan</p>
|
<p class="text-xs text-gray-500">Upload foto kedatangan</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -102,7 +151,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<div class="w-8 h-8 rounded-full bg-upst text-white font-black text-sm flex items-center justify-center">2</div>
|
<div class="w-8 h-8 rounded-full bg-upst text-white font-black text-sm flex items-center justify-center">2</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="font-black text-gray-800">Foto Timbang Sampah</h3>
|
<h3 class="font-black text-gray-800">Foto Timbang Sampah </h3>
|
||||||
<p class="text-xs text-gray-500">Upload foto timbangan, berat auto terisi</p>
|
<p class="text-xs text-gray-500">Upload foto timbangan, berat auto terisi</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -118,7 +167,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<div class="w-8 h-8 rounded-full bg-upst text-white font-black text-sm flex items-center justify-center">3</div>
|
<div class="w-8 h-8 rounded-full bg-upst text-white font-black text-sm flex items-center justify-center">3</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="font-black text-gray-800">Foto Petugas</h3>
|
<h3 class="font-black text-gray-800">Foto Petugas </h3>
|
||||||
<p class="text-xs text-gray-500">Upload dokumentasi petugas</p>
|
<p class="text-xs text-gray-500">Upload dokumentasi petugas</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -127,15 +176,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
<input type="file" class="tps-foto-petugas block w-full text-sm text-gray-700 border border-gray-200 rounded-xl p-2 file:mr-3 file:rounded-lg file:border-0 file:bg-upst file:px-3 file:py-2 file:text-xs file:font-bold file:text-white" accept="image/*" multiple />
|
<input type="file" class="tps-foto-petugas block w-full text-sm text-gray-700 border border-gray-200 rounded-xl p-2 file:mr-3 file:rounded-lg file:border-0 file:bg-upst file:px-3 file:py-2 file:text-xs file:font-bold file:text-white" accept="image/*" multiple />
|
||||||
<div class="tps-preview-petugas space-y-2"></div>
|
<div class="tps-preview-petugas space-y-2"></div>
|
||||||
|
|
||||||
${tps.fotoPetugas.length > 0 && !tps.fotoPetugasUploaded ? `
|
<div class="petugas-upload-state">${getPetugasUploadStateMarkup(tps)}</div>
|
||||||
<button type="button" class="tps-btn-upload-petugas w-full bg-blue-500 text-white py-2 rounded-xl font-bold text-xs hover:brightness-110">
|
|
||||||
Upload ${tps.fotoPetugas.length} Foto Petugas
|
|
||||||
</button>
|
|
||||||
` : tps.fotoPetugasUploaded ? `
|
|
||||||
<div class="text-center text-xs text-green-600 font-bold py-2">
|
|
||||||
✓ Foto petugas sudah diupload
|
|
||||||
</div>
|
|
||||||
` : ''}
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-gray-600 mb-1">Nama Petugas</label>
|
<label class="block text-xs font-semibold text-gray-600 mb-1">Nama Petugas</label>
|
||||||
|
|
@ -227,6 +268,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
|
||||||
namaPetugasInput.addEventListener('input', function() {
|
namaPetugasInput.addEventListener('input', function() {
|
||||||
tps.namaPetugas = this.value;
|
tps.namaPetugas = this.value;
|
||||||
|
refreshPetugasUploadState(form);
|
||||||
});
|
});
|
||||||
|
|
||||||
btnAddTimbangan.addEventListener('click', function() {
|
btnAddTimbangan.addEventListener('click', function() {
|
||||||
|
|
@ -526,7 +568,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
async function autoFillWeight(file, weightInput, ocrInfoEl) {
|
async function autoFillWeight(file, weightInput, ocrInfoEl) {
|
||||||
let guessedWeight = 0;
|
let guessedWeight = 0;
|
||||||
weightInput.placeholder = 'Membaca angka dari foto...';
|
weightInput.placeholder = 'Membaca angka dari foto...';
|
||||||
if (ocrInfoEl) ocrInfoEl.textContent = 'AI OCR: memproses gambar...';
|
if (ocrInfoEl) ocrInfoEl.textContent = 'AI: memproses gambar...';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const img = await readFileAsImage(file);
|
const img = await readFileAsImage(file);
|
||||||
|
|
@ -551,12 +593,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
if (ocrInfoEl) {
|
if (ocrInfoEl) {
|
||||||
const cleaned = (bestRawText || '').replace(/\s+/g, ' ').trim();
|
const cleaned = (bestRawText || '').replace(/\s+/g, ' ').trim();
|
||||||
ocrInfoEl.textContent = isSuccess
|
ocrInfoEl.textContent = isSuccess
|
||||||
? `AI OCR terbaca: ${cleaned}`
|
? `AI terbaca: ${cleaned}`
|
||||||
: (cleaned ? `AI OCR tidak valid: ${cleaned}` : 'AI OCR tidak menemukan angka valid.');
|
: (cleaned ? `AI tidak valid: ${cleaned}` : 'AI tidak menemukan angka valid.');
|
||||||
}
|
}
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
guessedWeight = 0;
|
guessedWeight = 0;
|
||||||
if (ocrInfoEl) ocrInfoEl.textContent = 'AI OCR gagal diproses.';
|
if (ocrInfoEl) ocrInfoEl.textContent = 'AI gagal diproses.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (guessedWeight > 0) {
|
if (guessedWeight > 0) {
|
||||||
|
|
@ -606,18 +648,119 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
if (grandTotalResiduDisplay) grandTotalResiduDisplay.textContent = formatWeightDisplay(totalResidu);
|
if (grandTotalResiduDisplay) grandTotalResiduDisplay.textContent = formatWeightDisplay(totalResidu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTimbanganUploadStateMarkup(hasFile, isUploaded, hasValidWeight) {
|
||||||
|
if (!hasFile) {
|
||||||
|
return '<p class="text-[11px] text-gray-400">Pilih foto timbangan terlebih dahulu</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isUploaded) {
|
||||||
|
return `
|
||||||
|
<div class="text-center text-xs text-green-600 font-bold py-2">✓ Foto timbangan sudah diupload</div>
|
||||||
|
<p class="text-[11px] text-gray-500 text-center">Kalau mau revisi, pilih file baru di atas. Status upload akan direset otomatis.</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValidWeight) {
|
||||||
|
return `
|
||||||
|
<button type="button" disabled class="btn-upload-timbangan w-full bg-gray-300 text-gray-500 py-2 rounded-xl font-bold text-xs cursor-not-allowed">Upload Foto Timbangan Ini</button>
|
||||||
|
<p class="text-[11px] text-red-500 text-center">Isi berat manual dulu sebelum upload jika berat tidak terbaca.</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `
|
||||||
|
<button type="button" class="btn-upload-timbangan w-full bg-blue-500 text-white py-2 rounded-xl font-bold text-xs hover:brightness-110">Upload Foto Timbangan Ini</button>
|
||||||
|
<p class="text-[11px] text-amber-600 text-center">Foto siap diupload.</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPetugasUploadStateMarkup(tps) {
|
||||||
|
if (tps.fotoPetugasUploaded) {
|
||||||
|
return '<div class="text-center text-xs text-green-600 font-bold py-2">✓ Foto petugas sudah diupload</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tps.fotoPetugas.length) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tps.namaPetugas.trim()) {
|
||||||
|
return `
|
||||||
|
<button type="button" disabled class="tps-btn-upload-petugas w-full bg-gray-300 text-gray-500 py-2 rounded-xl font-bold text-xs cursor-not-allowed">Upload ${tps.fotoPetugas.length} Foto Petugas</button>
|
||||||
|
<p class="text-[11px] text-red-500 text-center">Isi nama petugas terlebih dahulu</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `<button type="button" class="tps-btn-upload-petugas w-full bg-blue-500 text-white py-2 rounded-xl font-bold text-xs hover:brightness-110">Upload ${tps.fotoPetugas.length} Foto Petugas</button>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
function createTimbanganItem(repeater, existingData = null) {
|
||||||
|
const photoNumber = repeater.children.length + 1;
|
||||||
const item = document.createElement('div');
|
const item = document.createElement('div');
|
||||||
item.className = 'timbangan-item rounded-2xl border border-gray-200 p-3 space-y-2 bg-gray-50';
|
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 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 jenisSampah = existingData ? (existingData.jenisSampah && existingData.jenisSampah.length > 0 ? existingData.jenisSampah[0] : DEFAULT_JENIS) : DEFAULT_JENIS;
|
||||||
const hasFile = existingData && existingData.file;
|
const hasFile = existingData && existingData.file;
|
||||||
const isUploaded = existingData && existingData.uploaded;
|
const isUploaded = existingData && existingData.uploaded;
|
||||||
|
const ocrInfoText = existingData && existingData.ocrInfo ? existingData.ocrInfo : (hasFile ? 'OCR: diproses.' : 'OCR: belum diproses.');
|
||||||
|
|
||||||
item.innerHTML = `
|
item.innerHTML = `
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<p class="text-xs font-bold text-gray-600">Item Timbangan</p>
|
<p class="text-xs font-bold text-gray-600">Item Timbangan #${photoNumber}</p>
|
||||||
<button type="button" class="btn-remove-timbangan text-[11px] font-bold text-red-500">Hapus</button>
|
<button type="button" class="btn-remove-timbangan text-[11px] font-bold text-red-500">Hapus</button>
|
||||||
</div>
|
</div>
|
||||||
<input type="file" name="FotoTimbangan" accept="image/*" class="input-foto-timbangan block w-full text-sm text-gray-700 border border-gray-200 rounded-xl p-2 file:mr-3 file:rounded-lg file:border-0 file:bg-upst file:px-3 file:py-2 file:text-xs file:font-bold file:text-white" />
|
<input type="file" name="FotoTimbangan" accept="image/*" class="input-foto-timbangan block w-full text-sm text-gray-700 border border-gray-200 rounded-xl p-2 file:mr-3 file:rounded-lg file:border-0 file:bg-upst file:px-3 file:py-2 file:text-xs file:font-bold file:text-white" />
|
||||||
|
|
@ -625,10 +768,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
<img class="input-preview-image w-full h-44 object-contain" alt="Preview foto timbangan" />
|
<img class="input-preview-image w-full h-44 object-contain" alt="Preview foto timbangan" />
|
||||||
<div class="input-crop-overlay absolute inset-0 pointer-events-none"></div>
|
<div class="input-crop-overlay absolute inset-0 pointer-events-none"></div>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-[11px] text-gray-500 input-ocr-info">${hasFile ? 'OCR: diproses.' : 'OCR: belum diproses.'}</p>
|
<p class="text-[11px] text-gray-500 input-ocr-info">${ocrInfoText}</p>
|
||||||
${hasFile && !isUploaded ? `
|
<div class="timbangan-upload-state">${getTimbanganUploadStateMarkup(hasFile, isUploaded, weight > 0)}</div>
|
||||||
<button type="button" class="btn-upload-timbangan w-full bg-blue-500 text-white py-2 rounded-xl font-bold text-xs hover:brightness-110">Upload Foto Timbangan Ini</button>
|
|
||||||
` : isUploaded ? `<div class="text-center text-xs text-green-600 font-bold py-2">✓ Foto timbangan sudah diupload</div>` : ''}
|
|
||||||
<div class="grid grid-cols-1 gap-2">
|
<div class="grid grid-cols-1 gap-2">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-gray-600 mb-1">Jenis Sampah</label>
|
<label class="block text-xs font-semibold text-gray-600 mb-1">Jenis Sampah</label>
|
||||||
|
|
@ -662,7 +803,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
fileInput.addEventListener('change', async function() {
|
fileInput.addEventListener('change', async function() {
|
||||||
if (fileInput.files && fileInput.files[0]) {
|
if (fileInput.files && fileInput.files[0]) {
|
||||||
const originalFile = 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 watermarkedFile = await applyWatermark(originalFile, photoNumber);
|
||||||
|
|
||||||
const dataTransfer = new DataTransfer();
|
const dataTransfer = new DataTransfer();
|
||||||
|
|
@ -684,16 +825,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
const itemIndex = Array.from(repeater.children).indexOf(item);
|
const itemIndex = Array.from(repeater.children).indexOf(item);
|
||||||
if (itemIndex >= 0 && tps.timbangan[itemIndex]) {
|
if (itemIndex >= 0 && tps.timbangan[itemIndex]) {
|
||||||
tps.timbangan[itemIndex].uploaded = false;
|
tps.timbangan[itemIndex].uploaded = false;
|
||||||
const existingUploadBtn = item.querySelector('.btn-upload-timbangan');
|
refreshTimbanganUploadState(item);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -705,6 +837,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
weightInputValue.value = parsed.toFixed(2);
|
weightInputValue.value = parsed.toFixed(2);
|
||||||
updateTpsTotalTimbangan();
|
updateTpsTotalTimbangan();
|
||||||
syncTimbanganToTpsData();
|
syncTimbanganToTpsData();
|
||||||
|
refreshTimbanganUploadState(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
weightInputDisplay.addEventListener('blur', function() {
|
weightInputDisplay.addEventListener('blur', function() {
|
||||||
|
|
@ -718,6 +851,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
}
|
}
|
||||||
updateTpsTotalTimbangan();
|
updateTpsTotalTimbangan();
|
||||||
syncTimbanganToTpsData();
|
syncTimbanganToTpsData();
|
||||||
|
refreshTimbanganUploadState(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
jenisSampahSelect.addEventListener('change', function() {
|
jenisSampahSelect.addEventListener('change', function() {
|
||||||
|
|
@ -729,20 +863,16 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
item.remove();
|
item.remove();
|
||||||
const form = tpsContentContainer.querySelector('form');
|
const form = tpsContentContainer.querySelector('form');
|
||||||
const rep = form ? form.querySelector('.tps-timbangan-repeater') : null;
|
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();
|
updateTpsTotalTimbangan();
|
||||||
syncTimbanganToTpsData();
|
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);
|
repeater.appendChild(item);
|
||||||
|
refreshTimbanganUploadState(item);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -753,20 +883,23 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
|
||||||
const repeater = form.querySelector('.tps-timbangan-repeater');
|
const repeater = form.querySelector('.tps-timbangan-repeater');
|
||||||
const items = repeater.querySelectorAll('.timbangan-item');
|
const items = repeater.querySelectorAll('.timbangan-item');
|
||||||
|
const previousTimbangan = [...tps.timbangan];
|
||||||
|
|
||||||
tps.timbangan = [];
|
tps.timbangan = [];
|
||||||
items.forEach(item => {
|
items.forEach((item, index) => {
|
||||||
const fileInput = item.querySelector('.input-foto-timbangan');
|
const fileInput = item.querySelector('.input-foto-timbangan');
|
||||||
const weightValue = item.querySelector('.input-berat-timbangan-value');
|
const weightValue = item.querySelector('.input-berat-timbangan-value');
|
||||||
const weight = parseWeightInput(weightValue.value);
|
const weight = parseWeightInput(weightValue.value);
|
||||||
const jenisSampah = item.querySelector('.input-jenis-sampah').value;
|
const jenisSampah = item.querySelector('.input-jenis-sampah').value;
|
||||||
|
const ocrInfo = item.querySelector('.input-ocr-info')?.textContent || 'OCR: belum diproses.';
|
||||||
|
|
||||||
tps.timbangan.push({
|
tps.timbangan.push({
|
||||||
file: fileInput.files[0] || null,
|
file: fileInput.files[0] || null,
|
||||||
berat: [weight],
|
berat: [weight],
|
||||||
jenisSampah: [jenisSampah],
|
jenisSampah: [jenisSampah],
|
||||||
lokasiAngkut: [],
|
lokasiAngkut: [],
|
||||||
uploaded: false
|
uploaded: previousTimbangan[index]?.uploaded ?? false,
|
||||||
|
ocrInfo
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -803,14 +936,32 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
function uploadSingleFotoTimbangan(itemIndex) {
|
function uploadSingleFotoTimbangan(itemIndex, targetItem = null) {
|
||||||
const tps = tpsData[activeTpsIndex];
|
const tps = tpsData[activeTpsIndex];
|
||||||
if (!tps.timbangan[itemIndex] || !tps.timbangan[itemIndex].file) {
|
if (!tps.timbangan[itemIndex] || !tps.timbangan[itemIndex].file) {
|
||||||
alert('Belum ada foto timbangan yang dipilih!');
|
alert('Belum ada foto timbangan yang dipilih!');
|
||||||
return;
|
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;
|
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() {
|
function uploadFotoKedatangan() {
|
||||||
|
|
@ -830,7 +981,11 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
alert('Belum ada foto petugas yang dipilih!');
|
alert('Belum ada foto petugas yang dipilih!');
|
||||||
return;
|
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;
|
tps.fotoPetugasUploaded = true;
|
||||||
renderTpsForm();
|
renderTpsForm();
|
||||||
}
|
}
|
||||||
|
|
@ -842,7 +997,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
if (!tps.fotoPetugas.length) return alert('Foto petugas belum diupload!');
|
if (!tps.fotoPetugas.length) return alert('Foto petugas belum diupload!');
|
||||||
if (!tps.namaPetugas.trim()) return alert('Nama petugas belum diisi!');
|
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;
|
tps.submitted = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -857,4 +1012,5 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeLocation();
|
initializeLocation();
|
||||||
|
loadDetailData();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -312,15 +312,7 @@ const DetailPenjemputan = (function() {
|
||||||
<input type="file" class="tps-foto-petugas block w-full text-sm text-gray-700 border border-gray-200 rounded-xl p-2 file:mr-3 file:rounded-lg file:border-0 file:bg-upst file:px-3 file:py-2 file:text-xs file:font-bold file:text-white" accept="image/*" multiple />
|
<input type="file" class="tps-foto-petugas block w-full text-sm text-gray-700 border border-gray-200 rounded-xl p-2 file:mr-3 file:rounded-lg file:border-0 file:bg-upst file:px-3 file:py-2 file:text-xs file:font-bold file:text-white" accept="image/*" multiple />
|
||||||
<div class="tps-preview-petugas space-y-2"></div>
|
<div class="tps-preview-petugas space-y-2"></div>
|
||||||
|
|
||||||
${tps.fotoPetugas.length > 0 && !tps.fotoPetugasUploaded ? `
|
<div class="petugas-upload-state">${getPetugasUploadStateMarkup(tps)}</div>
|
||||||
<button type="button" class="tps-btn-upload-petugas w-full bg-blue-500 text-white py-2 rounded-xl font-bold text-xs hover:brightness-110">
|
|
||||||
Upload ${tps.fotoPetugas.length} Foto Petugas
|
|
||||||
</button>
|
|
||||||
` : tps.fotoPetugasUploaded ? `
|
|
||||||
<div class="text-center text-xs text-green-600 font-bold py-2">
|
|
||||||
✓ Foto petugas sudah diupload
|
|
||||||
</div>
|
|
||||||
` : ''}
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-gray-600 mb-1">Nama Petugas</label>
|
<label class="block text-xs font-semibold text-gray-600 mb-1">Nama Petugas</label>
|
||||||
|
|
@ -356,6 +348,7 @@ const DetailPenjemputan = (function() {
|
||||||
|
|
||||||
namaPetugasInput.addEventListener('input', function() {
|
namaPetugasInput.addEventListener('input', function() {
|
||||||
tps.namaPetugas = this.value;
|
tps.namaPetugas = this.value;
|
||||||
|
refreshPetugasUploadState(form);
|
||||||
});
|
});
|
||||||
|
|
||||||
btnAddTimbangan.addEventListener('click', function() {
|
btnAddTimbangan.addEventListener('click', function() {
|
||||||
|
|
@ -546,6 +539,7 @@ const DetailPenjemputan = (function() {
|
||||||
const jenisSampah = existingData ? existingData.jenisSampah : CONFIG.DEFAULT_JENIS;
|
const jenisSampah = existingData ? existingData.jenisSampah : CONFIG.DEFAULT_JENIS;
|
||||||
const hasFile = existingData && existingData.file;
|
const hasFile = existingData && existingData.file;
|
||||||
const isUploaded = existingData && existingData.uploaded;
|
const isUploaded = existingData && existingData.uploaded;
|
||||||
|
const ocrInfoText = existingData && existingData.ocrInfo ? existingData.ocrInfo : (hasFile ? 'OCR: diproses.' : 'OCR: belum diproses.');
|
||||||
|
|
||||||
item.innerHTML = `
|
item.innerHTML = `
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
|
|
@ -556,16 +550,8 @@ const DetailPenjemputan = (function() {
|
||||||
<div class="${hasFile ? '' : 'hidden'} input-preview-wrap relative rounded-xl overflow-hidden border border-gray-200 bg-black">
|
<div class="${hasFile ? '' : 'hidden'} input-preview-wrap relative rounded-xl overflow-hidden border border-gray-200 bg-black">
|
||||||
<img class="input-preview-image w-full h-44 object-contain" alt="Preview foto timbangan" />
|
<img class="input-preview-image w-full h-44 object-contain" alt="Preview foto timbangan" />
|
||||||
</div>
|
</div>
|
||||||
<p class="text-[11px] text-gray-500 input-ocr-info">${hasFile ? 'OCR: diproses.' : 'OCR: belum diproses.'}</p>
|
<p class="text-[11px] text-gray-500 input-ocr-info">${ocrInfoText}</p>
|
||||||
${hasFile && !isUploaded ? `
|
<div class="timbangan-upload-state">${getTimbanganUploadStateMarkup(hasFile, isUploaded, weight > 0)}</div>
|
||||||
<button type="button" class="btn-upload-timbangan w-full bg-blue-500 text-white py-2 rounded-xl font-bold text-xs hover:brightness-110">
|
|
||||||
Upload Foto Timbangan Ini
|
|
||||||
</button>
|
|
||||||
` : isUploaded ? `
|
|
||||||
<div class="text-center text-xs text-green-600 font-bold py-2">
|
|
||||||
✓ Foto timbangan sudah diupload
|
|
||||||
</div>
|
|
||||||
` : ''}
|
|
||||||
<div class="grid grid-cols-1 gap-2">
|
<div class="grid grid-cols-1 gap-2">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs font-semibold text-gray-600 mb-1">Jenis Sampah</label>
|
<label class="block text-xs font-semibold text-gray-600 mb-1">Jenis Sampah</label>
|
||||||
|
|
@ -625,19 +611,7 @@ const DetailPenjemputan = (function() {
|
||||||
const itemIndex = Array.from(repeater.children).indexOf(item);
|
const itemIndex = Array.from(repeater.children).indexOf(item);
|
||||||
if (itemIndex >= 0 && tps.timbangan[itemIndex]) {
|
if (itemIndex >= 0 && tps.timbangan[itemIndex]) {
|
||||||
tps.timbangan[itemIndex].uploaded = false;
|
tps.timbangan[itemIndex].uploaded = false;
|
||||||
|
refreshTimbanganUploadState(item);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -649,6 +623,7 @@ const DetailPenjemputan = (function() {
|
||||||
weightInputValue.value = parsed.toFixed(2);
|
weightInputValue.value = parsed.toFixed(2);
|
||||||
updateTpsTotalTimbangan();
|
updateTpsTotalTimbangan();
|
||||||
syncTimbanganToTpsData();
|
syncTimbanganToTpsData();
|
||||||
|
refreshTimbanganUploadState(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
weightInputDisplay.addEventListener('blur', function() {
|
weightInputDisplay.addEventListener('blur', function() {
|
||||||
|
|
@ -662,6 +637,7 @@ const DetailPenjemputan = (function() {
|
||||||
}
|
}
|
||||||
updateTpsTotalTimbangan();
|
updateTpsTotalTimbangan();
|
||||||
syncTimbanganToTpsData();
|
syncTimbanganToTpsData();
|
||||||
|
refreshTimbanganUploadState(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
jenisSampahSelect.addEventListener('change', function() {
|
jenisSampahSelect.addEventListener('change', function() {
|
||||||
|
|
@ -685,16 +661,92 @@ const DetailPenjemputan = (function() {
|
||||||
syncTimbanganToTpsData();
|
syncTimbanganToTpsData();
|
||||||
});
|
});
|
||||||
|
|
||||||
const btnUploadTimbangan = item.querySelector('.btn-upload-timbangan');
|
repeater.appendChild(item);
|
||||||
if (btnUploadTimbangan) {
|
refreshTimbanganUploadState(item);
|
||||||
btnUploadTimbangan.addEventListener('click', function() {
|
return item;
|
||||||
const itemIndex = Array.from(repeater.children).indexOf(item);
|
|
||||||
uploadSingleFotoTimbangan(itemIndex);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
repeater.appendChild(item);
|
function getTimbanganUploadStateMarkup(hasFile, isUploaded, hasValidWeight) {
|
||||||
return item;
|
if (!hasFile) {
|
||||||
|
return '<p class="text-[11px] text-gray-400">Pilih foto timbangan terlebih dahulu</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isUploaded) {
|
||||||
|
return `
|
||||||
|
<div class="text-center text-xs text-green-600 font-bold py-2 upload-success-message">✓ Foto timbangan sudah diupload</div>
|
||||||
|
<p class="text-[11px] text-gray-500 text-center">Kalau mau revisi, pilih file baru di atas. Status upload akan direset otomatis.</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValidWeight) {
|
||||||
|
return `
|
||||||
|
<button type="button" disabled class="btn-upload-timbangan w-full bg-gray-300 text-gray-500 py-2 rounded-xl font-bold text-xs cursor-not-allowed">Upload Foto Timbangan Ini</button>
|
||||||
|
<p class="text-[11px] text-red-500 text-center">Isi berat manual dulu sebelum upload jika berat tidak terbaca.</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `
|
||||||
|
<button type="button" class="btn-upload-timbangan w-full bg-blue-500 text-white py-2 rounded-xl font-bold text-xs hover:brightness-110">Upload Foto Timbangan Ini</button>
|
||||||
|
<p class="text-[11px] text-amber-600 text-center">Foto siap diupload.</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPetugasUploadStateMarkup(tps) {
|
||||||
|
if (tps.fotoPetugasUploaded) {
|
||||||
|
return '<div class="text-center text-xs text-green-600 font-bold py-2">✓ Foto petugas sudah diupload</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tps.fotoPetugas.length) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tps.namaPetugas.trim()) {
|
||||||
|
return `
|
||||||
|
<button type="button" disabled class="tps-btn-upload-petugas w-full bg-gray-300 text-gray-500 py-2 rounded-xl font-bold text-xs cursor-not-allowed">Upload ${tps.fotoPetugas.length} Foto Petugas</button>
|
||||||
|
<p class="text-[11px] text-red-500 text-center">Isi nama petugas terlebih dahulu</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `<button type="button" class="tps-btn-upload-petugas w-full bg-blue-500 text-white py-2 rounded-xl font-bold text-xs hover:brightness-110">Upload ${tps.fotoPetugas.length} Foto Petugas</button>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
function renumberTimbanganItems(repeater) {
|
||||||
|
|
@ -1023,26 +1075,27 @@ async function applyWatermark(file, photoNumber) {
|
||||||
|
|
||||||
const repeater = form.querySelector('.tps-timbangan-repeater');
|
const repeater = form.querySelector('.tps-timbangan-repeater');
|
||||||
const items = repeater.querySelectorAll('.timbangan-item');
|
const items = repeater.querySelectorAll('.timbangan-item');
|
||||||
|
const previousTimbangan = [...tps.timbangan];
|
||||||
|
|
||||||
tps.timbangan = [];
|
tps.timbangan = [];
|
||||||
items.forEach(item => {
|
items.forEach((item, index) => {
|
||||||
const fileInput = item.querySelector('.input-foto-timbangan');
|
const fileInput = item.querySelector('.input-foto-timbangan');
|
||||||
const weightValue = item.querySelector('.input-berat-timbangan-value');
|
const weightValue = item.querySelector('.input-berat-timbangan-value');
|
||||||
const jenisSampahSelect = item.querySelector('.input-jenis-sampah');
|
const jenisSampahSelect = item.querySelector('.input-jenis-sampah');
|
||||||
|
const ocrInfo = item.querySelector('.input-ocr-info')?.textContent || 'OCR: belum diproses.';
|
||||||
const existingIndex = tps.timbangan.length;
|
const existingData = previousTimbangan[index];
|
||||||
const existingData = tps.timbangan[existingIndex];
|
|
||||||
|
|
||||||
tps.timbangan.push({
|
tps.timbangan.push({
|
||||||
file: fileInput.files[0] || (existingData ? existingData.file : null),
|
file: fileInput.files[0] || (existingData ? existingData.file : null),
|
||||||
weight: parseWeightInput(weightValue.value),
|
weight: parseWeightInput(weightValue.value),
|
||||||
jenisSampah: jenisSampahSelect.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];
|
const tps = state.tpsData[state.activeTpsIndex];
|
||||||
|
|
||||||
if (!tps.timbangan[itemIndex] || !tps.timbangan[itemIndex].file) {
|
if (!tps.timbangan[itemIndex] || !tps.timbangan[itemIndex].file) {
|
||||||
|
|
@ -1051,29 +1104,24 @@ async function applyWatermark(file, photoNumber) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const timbanganItem = tps.timbangan[itemIndex];
|
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)`);
|
alert(`Upload foto timbangan #${itemIndex + 1} untuk ${tps.name}\nJenis: ${timbanganItem.jenisSampah}\nBerat: ${timbanganItem.weight} kg\n(Implementasi upload ke server)`);
|
||||||
|
|
||||||
timbanganItem.uploaded = true;
|
timbanganItem.uploaded = true;
|
||||||
|
|
||||||
|
if (!targetItem) {
|
||||||
const form = elements.tpsContentContainer.querySelector('form');
|
const form = elements.tpsContentContainer.querySelector('form');
|
||||||
const repeater = form.querySelector('.tps-timbangan-repeater');
|
const repeater = form ? form.querySelector('.tps-timbangan-repeater') : null;
|
||||||
const items = repeater.querySelectorAll('.timbangan-item');
|
const items = repeater ? repeater.querySelectorAll('.timbangan-item') : [];
|
||||||
const targetItem = items[itemIndex];
|
targetItem = items[itemIndex] || null;
|
||||||
|
}
|
||||||
|
|
||||||
if (targetItem) {
|
if (targetItem) {
|
||||||
const uploadBtn = targetItem.querySelector('.btn-upload-timbangan');
|
refreshTimbanganUploadState(targetItem);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1096,6 +1144,10 @@ async function applyWatermark(file, photoNumber) {
|
||||||
alert('Belum ada foto petugas yang dipilih!');
|
alert('Belum ada foto petugas yang dipilih!');
|
||||||
return;
|
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)`);
|
alert(`Upload ${tps.fotoPetugas.length} foto petugas untuk ${tps.name}\n(Implementasi upload ke server)`);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue