update: detail batal, array berat, tps json

main
muamars 2026-03-09 10:12:58 +07:00
parent 6bbe35c450
commit 56e16c328c
11 changed files with 215 additions and 24 deletions

View File

@ -45,6 +45,12 @@ namespace eSPJ.Controllers.SpjDriverUpstController
return View("~/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/Batal.cshtml");
}
[HttpGet("detail-batal")]
public IActionResult DetailBatal()
{
return View("~/Views/Admin/Transport/SpjDriverUpst/DetailPenjemputan/DetailBatal.cshtml");
}
[HttpPost("")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Submit([FromForm] DetailPenjemputanRequest request)

View File

@ -10,8 +10,9 @@ namespace eSPJ.Models
public class TimbanganItem
{
public string? FotoFileName { get; set; }
public decimal Berat { get; set; }
public JenisSampah JenisSampah { get; set; } = JenisSampah.Residu;
public List<decimal> Berat { get; set; } = new();
public List<string> LokasiAngkut { get; set; } = new();
public List<JenisSampah> JenisSampah { get; set; } = new();
public bool IsUploaded { get; set; }
public DateTime? WaktuUpload { get; set; }
}

View File

@ -172,8 +172,9 @@ namespace eSPJ.Services
tpsData.Timbangan.Add(new TimbanganItem
{
FotoFileName = fileName,
Berat = i < request.BeratTimbangan.Count ? request.BeratTimbangan[i] : 0,
JenisSampah = jenisSampah,
Berat = new List<decimal> { (i < request.BeratTimbangan.Count ? request.BeratTimbangan[i] : 0) },
LokasiAngkut = new List<string>(),
JenisSampah = new List<JenisSampah> { jenisSampah },
IsUploaded = true,
WaktuUpload = DateTime.Now
});

View File

@ -1,6 +1,6 @@
@{
Layout = "~/Views/Admin/Transport/SpjDriverUpst/Shared/_Layout.cshtml";
ViewData["Title"] = "Detail Batal Penjemputan";
ViewData["Title"] = "Batal Penjemputan";
}
<div class="w-full lg:max-w-sm mx-auto bg-gray-50 min-h-screen">

View File

@ -0,0 +1,106 @@
@{
Layout = "~/Views/Admin/Transport/SpjDriverUpst/Shared/_Layout.cshtml";
ViewData["Title"] = "Detail Batal Penjemputan";
}
<div class="w-full lg:max-w-sm mx-auto bg-gray-50 min-h-screen pb-20">
<div class="bg-upst text-white px-6 pt-8 pb-16 rounded-b-[40px] shadow-lg relative">
<div class="flex items-center justify-between relative z-10">
<a href="@Url.Action("Index", "Home")" class="w-10 h-10 flex items-center justify-center bg-white/10 rounded-xl backdrop-blur-md hover:bg-white/20 transition-all">
<i class="w-5 h-5" data-lucide="chevron-left"></i>
</a>
<h1 class="text-lg font-black uppercase tracking-tight">Detail Batal</h1>
<div class="w-10"></div>
</div>
</div>
<div class="px-4 pb-6 relative -mt-10 z-20">
<div class="bg-white rounded-2xl p-5 shadow-sm border border-gray-100">
<div class="flex items-center justify-between border-b border-gray-100 pb-4 mb-4">
<div class="flex items-center gap-3">
<div>
<div class="flex items-center gap-2 mb-2">
<div class="bg-red-100 text-red-600 px-3 py-1 rounded-full text-xs font-bold border border-red-200" id="status-badge">-</div>
<div class="text-xs text-gray-500" id="tanggal-batal">-</div>
</div>
<h3 class="font-bold text-gray-900" id="nama-perusahaan">-</h3>
<p class="text-sm text-gray-700 leading-relaxed items-center flex" id="alamat-perusahaan">
-
</p>
</div>
</div>
</div>
<div class="space-y-5">
<div>
<label class="block text-sm font-semibold text-gray-700 mb-2">Alasan Pembatalan</label>
<div class="w-full rounded-xl text-sm border border-gray-200 bg-gray-50 p-4 text-gray-700 leading-relaxed" id="alasan-pembatalan">
-
</div>
</div>
<div>
<label class="block text-sm font-semibold text-gray-700 mb-2">Foto Bukti Pembatalan</label>
<div class="grid grid-cols-1 gap-3" id="foto-bukti-container">
</div>
</div>
<div class="pt-4">
<a href="@Url.Action("Index", "Home")"
class="block w-full bg-gray-100 text-gray-700 font-bold py-3.5 rounded-xl text-center hover:bg-gray-200 transition-colors">
Kembali ke Beranda
</a>
</div>
</div>
</div>
</div>
<partial name="~/Views/Admin/Transport/SpjDriverUpst/Shared/Components/_Navigation.cshtml" />
</div>
@section Scripts {
<script>
document.addEventListener('DOMContentLoaded', async function() {
try {
const response = await fetch('/driver/json/pembatalan-data.json');
const data = await response.json();
const pembatalan = data.pembatalan;
document.getElementById('nama-perusahaan').textContent = pembatalan.namaPerusahaan;
document.getElementById('alamat-perusahaan').textContent = pembatalan.alamat;
document.getElementById('alasan-pembatalan').textContent = pembatalan.alasanPembatalan;
document.getElementById('status-badge').textContent = pembatalan.status;
const tanggal = new Date(pembatalan.tanggalBatal);
const formatter = new Intl.DateTimeFormat('id-ID', {
day: '2-digit',
month: 'short',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
timeZone: 'Asia/Jakarta'
});
document.getElementById('tanggal-batal').textContent = formatter.format(tanggal) + ' WIB';
const fotoBuktiContainer = document.getElementById('foto-bukti-container');
if (pembatalan.fotoBukti && pembatalan.fotoBukti.length > 0) {
pembatalan.fotoBukti.forEach(foto => {
const fotoDivEl = document.createElement('div');
fotoDivEl.className = 'relative group cursor-pointer aspect-square rounded-xl overflow-hidden border border-gray-200';
fotoDivEl.innerHTML = `
<img src="${foto.url}" alt="Bukti ${foto.id}" class="w-full h-full object-cover transition-transform duration-300 group-hover:scale-110" />
`;
fotoBuktiContainer.appendChild(fotoDivEl);
});
}
} catch (error) {
console.error('Error loading pembatalan data:', error);
}
});
</script>
}

View File

@ -154,7 +154,7 @@
</div>
</a>
<a href="@Url.Action("Batal", "DetailPenjemputan")" class="block relative pl-12 group">
<a href="@Url.Action("DetailBatal", "DetailPenjemputan")" class="block relative pl-12 group">
<div class="absolute left-4 top-1 w-4 h-4 bg-red-500 rounded-full z-10 ring-4 ring-red-100"></div>
<div class="bg-red-50/50 p-4 rounded-3xl border border-red-100 shadow-sm group-active:bg-red-100 transition-colors">
<div class="flex justify-between items-start mb-2">

View File

@ -846,6 +846,9 @@
.table-row {
display: table-row;
}
.aspect-square {
aspect-ratio: 1 / 1;
}
.h-0\.5 {
height: calc(var(--spacing) * 0.5);
}
@ -2112,6 +2115,9 @@
.py-3 {
padding-block: calc(var(--spacing) * 3);
}
.py-3\.5 {
padding-block: calc(var(--spacing) * 3.5);
}
.py-4 {
padding-block: calc(var(--spacing) * 4);
}
@ -2220,6 +2226,9 @@
.pb-16 {
padding-bottom: calc(var(--spacing) * 16);
}
.pb-20 {
padding-bottom: calc(var(--spacing) * 20);
}
.pb-24 {
padding-bottom: calc(var(--spacing) * 24);
}
@ -2374,9 +2383,6 @@
.break-all {
word-break: break-all;
}
.whitespace-nowrap {
white-space: nowrap;
}
.text-amber-600 {
color: var(--color-amber-600);
}
@ -2792,6 +2798,16 @@
}
}
}
.group-hover\:scale-110 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
--tw-scale-x: 110%;
--tw-scale-y: 110%;
--tw-scale-z: 110%;
scale: var(--tw-scale-x) var(--tw-scale-y);
}
}
}
.group-hover\:rotate-180 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
@ -3002,13 +3018,6 @@
}
}
}
.hover\:bg-green-200 {
&:hover {
@media (hover: hover) {
background-color: var(--color-green-200);
}
}
}
.hover\:bg-green-600 {
&:hover {
@media (hover: hover) {

View File

@ -610,8 +610,8 @@ document.addEventListener('DOMContentLoaded', function() {
const item = document.createElement('div');
item.className = 'timbangan-item rounded-2xl border border-gray-200 p-3 space-y-2 bg-gray-50';
const weight = existingData ? existingData.weight : 0;
const jenisSampah = existingData ? (existingData.jenisSampah || DEFAULT_JENIS) : DEFAULT_JENIS;
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;
@ -758,10 +758,14 @@ document.addEventListener('DOMContentLoaded', function() {
items.forEach(item => {
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;
tps.timbangan.push({
file: fileInput.files[0] || null,
weight: parseWeightInput(weightValue.value),
jenisSampah: item.querySelector('.input-jenis-sampah').value,
berat: [weight],
jenisSampah: [jenisSampah],
lokasiAngkut: [],
uploaded: false
});
});
@ -784,8 +788,10 @@ document.addEventListener('DOMContentLoaded', function() {
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 || DEFAULT_JENIS);
const weight = timb.berat && timb.berat.length > 0 ? timb.berat[0] : 0;
const jenis = timb.jenisSampah && timb.jenisSampah.length > 0 ? timb.jenisSampah[0] : DEFAULT_JENIS;
formData.append('BeratTimbangan', weight);
formData.append('JenisSampahList', jenis);
});
tps.fotoPetugas.forEach((file) => formData.append('FotoPetugas', file));

View File

@ -1226,8 +1226,20 @@ async function applyWatermark(file, photoNumber) {
};
})();
document.addEventListener('DOMContentLoaded', function() {
DetailPenjemputan.init(['TPS A', 'TPS B', 'TPS C']);
document.addEventListener('DOMContentLoaded', async function() {
try {
const response = await fetch('/driver/json/tps-list.json');
const data = await response.json();
const tpsList = data.tpsList.map(tps => ({
name: tps.name,
lokasiAngkutId: tps.lokasiAngkutId,
spjDetailId: tps.spjDetailId,
id: tps.id
}));
DetailPenjemputan.init(tpsList);
} catch (error) {
console.error('Error loading TPS list:', error);
}
const platNomorEl = document.getElementById('plat-nomor');
if (platNomorEl) {

View File

@ -0,0 +1,16 @@
{
"pembatalan": {
"namaPerusahaan": "CV Tri Berkah Sejahtera",
"alamat": "Kp. Pertanian II Rt.004 Rw.001 Kel. Klender Kec, Duren Sawit, Kota Adm. Jakarta Timur 13470",
"tanggalBatal": "2026-03-09T09:45:00",
"alasanPembatalan": "Kendaraan mengalami kendala mesin di perjalanan sehingga tidak memungkinkan untuk melanjutkan penjemputan hari ini.",
"fotoBukti": [
{
"id": 1,
"fileName": "bukti_1.jpg",
"url": "https://sukabumisatu.com/wp-content/uploads/2025/04/IMG-20250423-WA0030-1140x815.jpg"
}
],
"status": "Dibatalkan"
}
}

View File

@ -0,0 +1,34 @@
{
"tpsList": [
{
"id": "TPS001",
"name": "TPS A",
"lokasiAngkutId": "LOK001",
"spjDetailId": "SPJ001",
"alamat": "Jl. Merpati No. 1, Jakarta",
"latitude": "-6.2088",
"longitude": "106.8905",
"status": "aktif"
},
{
"id": "TPS002",
"name": "TPS B",
"lokasiAngkutId": "LOK002",
"spjDetailId": "SPJ002",
"alamat": "Jl. Kenari No. 5, Jakarta",
"latitude": "-6.2100",
"longitude": "106.8920",
"status": "aktif"
},
{
"id": "TPS003",
"name": "TPS C",
"lokasiAngkutId": "LOK003",
"spjDetailId": "SPJ003",
"alamat": "Jl. Flamboyan No. 10, Jakarta",
"latitude": "-6.2120",
"longitude": "106.8935",
"status": "aktif"
}
]
}