pesapakawan/wwwroot/website/js/datatables_pengolahan.js

354 lines
12 KiB
JavaScript

document.addEventListener("DOMContentLoaded", function () {
initializePengolahanDataTable();
});
// helper: parse date string in format dd/mm/yyyy to a Date object (local)
function parseDateDMY(dateStr) {
if (!dateStr) return new Date(dateStr);
// accept either dd/mm/yyyy or ISO
if (dateStr.indexOf("/") !== -1) {
const parts = dateStr.split("/");
// parts[0]=dd, [1]=mm, [2]=yyyy
const d = parseInt(parts[0], 10);
const m = parseInt(parts[1], 10) - 1;
const y = parseInt(parts[2], 10);
return new Date(y, m, d);
}
return new Date(dateStr);
}
function initializePengolahanDataTable() {
if (!document.getElementById("pengolahanTable")) return;
if (typeof $ !== "undefined" && $.fn.DataTable) {
$("#pengolahanTable").DataTable({
ajax: {
url: "/api/web/jasa/olah",
type: "POST",
dataSrc: function (json) {
if (!json) return [];
return json.data || json;
},
error: function (xhr, error, thrown) {
console.error("Error fetching pengolahan data:", error || thrown);
},
},
columns: [
{
data: null,
className: "px-3 py-4 text-sm text-gray-900 text-center font-medium",
title: "No",
width: "5%",
render: function (data, type, row, meta) {
return meta.row + 1;
},
},
{
data: "nama",
className: "px-3 py-4 text-sm text-gray-900 font-medium break-words",
title: "Nama Perusahaan",
width: "25%",
},
{
data: "alamat",
className: "px-3 py-4 text-sm text-gray-700 break-words",
title: "Alamat",
width: "50%",
},
{
data: "tglBerlakuIzin",
className: "px-3 py-4 text-sm text-gray-900 text-center",
title: "Berlaku Hingga",
width: "20%",
render: function (data, type, row) {
if (type === "display") {
const date = parseDateDMY(data);
const formattedDate = date.toLocaleDateString("id-ID", {
year: "numeric",
month: "2-digit",
day: "2-digit",
});
const today = new Date();
const expiry = parseDateDMY(data);
const daysUntilExpiry = Math.ceil(
(expiry - today) / (1000 * 60 * 60 * 24)
);
let statusClass = "bg-green-100 text-green-800";
if (daysUntilExpiry < 30) {
statusClass = "bg-red-100 text-red-800";
} else if (daysUntilExpiry < 90) {
statusClass = "bg-yellow-100 text-yellow-800";
}
return `<div class="text-center">
<div class="text-sm font-medium text-gray-900 mb-1">${formattedDate}</div>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ${statusClass}">
${
daysUntilExpiry > 0
? `${daysUntilExpiry} hari`
: "Expired"
}
</span>
</div>`;
}
return data;
},
},
],
language: {
search: "Cari:",
lengthMenu: "Tampilkan _MENU_ data per halaman",
info: "Menampilkan _START_ sampai _END_ dari _TOTAL_ data",
infoEmpty: "Menampilkan 0 sampai 0 dari 0 data",
infoFiltered: "(disaring dari _MAX_ total data)",
paginate: {
first: "Pertama",
last: "Terakhir",
next: "Selanjutnya",
previous: "Sebelumnya",
},
emptyTable: "Tidak ada data yang tersedia",
zeroRecords: "Tidak ditemukan data yang sesuai",
},
pageLength: 10,
responsive: false,
ordering: true,
searching: true,
paging: true,
info: true,
autoWidth: false,
scrollX: false,
layout: {
topStart: {
pageLength: {
text: "Tampilkan _MENU_ data",
},
},
topEnd: {
search: {
placeholder: "Cari perusahaan pengolahan...",
},
},
bottomStart: "info",
bottomEnd: "paging",
},
initComplete: function () {
$("#loadingIndicator").hide();
const wrapper = $(".dataTables_wrapper");
wrapper
.find('input[type="search"]')
.addClass(
"block w-full px-4 py-2 text-sm border border-gray-300 rounded-lg bg-white focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200"
)
.attr("placeholder", "Cari perusahaan pengolahan...");
wrapper
.find("select")
.addClass(
"px-3 py-2 text-sm border border-gray-300 rounded-lg bg-white focus:ring-2 focus:ring-blue-500 focus:border-transparent"
);
wrapper
.find(".dt-paging .dt-paging-button")
.addClass(
"px-3 py-2 mx-1 text-sm border border-gray-300 rounded-md bg-white text-gray-700 hover:bg-blue-50 hover:text-blue-600 hover:border-blue-300 transition-all duration-200"
);
wrapper
.find(".dt-paging .dt-paging-button.current")
.addClass("bg-blue-600 text-white border-blue-600 hover:bg-blue-700")
.removeClass("bg-white text-gray-700");
wrapper
.find(".dt-paging .dt-paging-button.disabled")
.addClass("opacity-50 cursor-not-allowed");
if (window.innerWidth <= 768) {
wrapper.find(".dt-paging").addClass("text-center");
wrapper.find(".dt-info").addClass("text-center text-sm");
wrapper.find(".dt-length").addClass("text-center");
wrapper.find(".dt-search").addClass("text-center");
}
wrapper.find(".dt-length").addClass("flex items-center space-x-2");
wrapper.find(".dt-search").addClass("flex items-center space-x-2");
wrapper.find(".dt-info").addClass("text-sm text-gray-600");
$("#pengolahanTable").removeClass("dataTable").addClass("w-full");
$("#pengolahanTable thead th").addClass(
"bg-cyan-400 text-white font-semibold text-sm uppercase tracking-wider border-b"
);
wrapper.find(".dtr-control").remove();
$("#pengolahanTable tbody tr").addClass("transition-all duration-200");
$(window).on("resize", function () {
const wrapper = $(".dataTables_wrapper");
if (window.innerWidth <= 768) {
wrapper.find(".dt-paging").addClass("text-center");
wrapper.find(".dt-info").addClass("text-center text-sm");
wrapper.find(".dt-length").addClass("text-center");
wrapper.find(".dt-search").addClass("text-center");
} else {
wrapper.find(".dt-paging").removeClass("text-center");
wrapper.find(".dt-info").removeClass("text-center text-sm");
wrapper.find(".dt-length").removeClass("text-center");
wrapper.find(".dt-search").removeClass("text-center");
}
});
},
drawCallback: function () {
$("#pengolahanTable tbody tr")
.removeClass("bg-blue-50")
.hover(
function () {
$(this).addClass(
"bg-blue-50 shadow-sm transform transition-all duration-200"
);
},
function () {
$(this).removeClass("bg-blue-50 shadow-sm transform");
}
);
$("#pengolahanTable tbody tr:even").addClass("bg-gray-50");
$("#pengolahanTable tbody tr:odd").addClass("bg-white");
},
});
} else {
loadPengolahanDataManually();
}
}
function loadPengolahanDataManually() {
fetch("/website/data/pengolahan-data.json")
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then((data) => {
const tbody = document.querySelector("#pengolahanTable tbody");
tbody.innerHTML = "";
data.forEach((item, index) => {
const row = document.createElement("tr");
row.className = `${
index % 2 === 0 ? "bg-gray-50" : "bg-white"
} hover:bg-blue-50 transition-all duration-200`;
const date = parseDateDMY(item.tglBerlakuIzin);
const formattedDate = date.toLocaleDateString("id-ID", {
year: "numeric",
month: "2-digit",
day: "2-digit",
});
const today = new Date();
const expiry = new Date(item.tglBerlakuIzin);
const daysUntilExpiry = Math.ceil(
(expiry - today) / (1000 * 60 * 60 * 24)
);
let statusClass = "bg-green-100 text-green-800";
let statusText = `${daysUntilExpiry} hari`;
if (daysUntilExpiry < 0) {
statusClass = "bg-red-100 text-red-800";
statusText = "Expired";
} else if (daysUntilExpiry < 30) {
statusClass = "bg-red-100 text-red-800";
} else if (daysUntilExpiry < 90) {
statusClass = "bg-yellow-100 text-yellow-800";
}
row.innerHTML = `
<td class="px-3 py-4 text-sm text-gray-900 text-center font-medium" style="width: 5%">${
index + 1
}</td>
<td class="px-3 py-4 text-sm text-gray-900 font-medium break-words" style="width: 25%">${
item.nama
}</td>
<td class="px-3 py-4 text-sm text-gray-700 break-words" style="width: 50%">${
item.alamat
}</td>
<td class="px-3 py-4 text-sm text-gray-900 text-center" style="width: 20%">
<div class="text-sm font-medium text-gray-900">${formattedDate}</div>
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ${statusClass} mt-1">
${statusText}
</span>
</td>
`;
tbody.appendChild(row);
});
const loadingIndicator = document.getElementById("loadingIndicator");
if (loadingIndicator) {
loadingIndicator.style.display = "none";
}
addManualSearch(data);
})
.catch((error) => {
console.error("Error loading data:", error);
const loadingIndicator = document.getElementById("loadingIndicator");
if (loadingIndicator) {
loadingIndicator.innerHTML = `
<div class="text-red-500 text-center">
<i class="fas fa-exclamation-triangle mr-2"></i>
Error memuat data: ${error.message}
</div>
`;
}
});
}
function addManualSearch(data) {
const tableContainer = document
.querySelector("#pengolahanTable")
.closest(".bg-white");
if (!document.getElementById("manualSearchInput")) {
const searchContainer = document.createElement("div");
searchContainer.className = "mb-4 flex justify-end";
searchContainer.innerHTML = `
<div class="relative">
<input type="text" id="manualSearchInput" placeholder="Cari perusahaan pengolahan..."
class="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent pr-10">
<div class="absolute inset-y-0 right-0 pr-3 flex items-center">
<svg class="h-5 w-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg>
</div>
</div>
`;
tableContainer.insertBefore(
searchContainer,
document.querySelector(".overflow-x-auto")
);
document
.getElementById("manualSearchInput")
.addEventListener("input", function (e) {
const searchTerm = e.target.value.toLowerCase();
const rows = document.querySelectorAll("#pengolahanTable tbody tr");
rows.forEach((row) => {
const text = row.textContent.toLowerCase();
if (text.includes(searchTerm)) {
row.style.display = "";
} else {
row.style.display = "none";
}
});
});
}
}