first commit
This commit is contained in:
parent
4518db6940
commit
e8f3995cea
|
|
@ -29,10 +29,11 @@ export default function TransaksiBAST() {
|
|||
======================================================= */
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
|
||||
axios
|
||||
.get("http://localhost:5000/api/bast")
|
||||
.then((res) => {
|
||||
// PENGAMAN KREDENSIAL: Memastikan data yang masuk ke state murni bertipe Array
|
||||
|
||||
if (res.data && res.data.success && Array.isArray(res.data.data)) {
|
||||
setDataBAST(res.data.data);
|
||||
} else if (Array.isArray(res.data)) {
|
||||
|
|
@ -51,23 +52,30 @@ export default function TransaksiBAST() {
|
|||
}, []);
|
||||
|
||||
/* =======================================================
|
||||
DOWNLOAD PDF (Sinkronisasi Properti Sesuai Database)
|
||||
PREVIEW PDF
|
||||
======================================================= */
|
||||
const downloadPDF = async (item: any) => {
|
||||
|
||||
const doc = new jsPDF();
|
||||
|
||||
/* =========================
|
||||
QR CODE EXTRACTION
|
||||
========================= */
|
||||
let qrImage = "";
|
||||
|
||||
try {
|
||||
// Menggunakan fallback jika qr_image sudah ada di dalam object barang
|
||||
|
||||
const qrRes = await axios.get(
|
||||
`http://localhost:5000/api/qrcode/${item.bast_id}`
|
||||
);
|
||||
|
||||
qrImage = qrRes.data.qr;
|
||||
|
||||
} catch (err) {
|
||||
console.log("QR Code endpoint not found, menggunakan QR default jika tersedia.");
|
||||
|
||||
console.log(
|
||||
"QR Code endpoint not found, menggunakan QR default jika tersedia."
|
||||
);
|
||||
}
|
||||
|
||||
if (qrImage) {
|
||||
|
|
@ -78,7 +86,9 @@ export default function TransaksiBAST() {
|
|||
KODE DOKUMEN BAST
|
||||
========================= */
|
||||
doc.rect(140, 50, 50, 10);
|
||||
|
||||
doc.setFontSize(10);
|
||||
|
||||
doc.text(`BAST-#${item.bast_id}`, 143, 57);
|
||||
|
||||
/* =========================
|
||||
|
|
@ -86,8 +96,14 @@ export default function TransaksiBAST() {
|
|||
========================= */
|
||||
doc.setFont("helvetica", "bold");
|
||||
doc.setFontSize(15);
|
||||
doc.text("BERITA ACARA", 105, 80, { align: "center" });
|
||||
doc.text("SERAH TERIMA BARANG/ASSET", 105, 92, { align: "center" });
|
||||
|
||||
doc.text("BERITA ACARA", 105, 80, {
|
||||
align: "center",
|
||||
});
|
||||
|
||||
doc.text("SERAH TERIMA BARANG/ASSET", 105, 92, {
|
||||
align: "center",
|
||||
});
|
||||
|
||||
/* =========================
|
||||
ISI SURAT KONTRAK BAST
|
||||
|
|
@ -95,25 +111,55 @@ export default function TransaksiBAST() {
|
|||
doc.setFont("helvetica", "normal");
|
||||
doc.setFontSize(11);
|
||||
|
||||
// Konversi tanggal sql ke format readable lokal jika ada
|
||||
const waktuBuat = item.dibuat_pada ? new Date(item.dibuat_pada).toLocaleDateString("id-ID") : "-";
|
||||
const waktuBuat = item.dibuat_pada
|
||||
? new Date(item.dibuat_pada).toLocaleDateString("id-ID")
|
||||
: "-";
|
||||
|
||||
doc.text(`Pada hari ini, tanggal ${waktuBuat},`, 20, 115);
|
||||
doc.text(`telah dilakukan serah terima barang secara sah antara pihak:`, 20, 128);
|
||||
doc.text(
|
||||
`Pada hari ini, tanggal ${waktuBuat},`,
|
||||
20,
|
||||
115
|
||||
);
|
||||
|
||||
doc.text(
|
||||
`telah dilakukan serah terima barang secara sah antara pihak:`,
|
||||
20,
|
||||
128
|
||||
);
|
||||
|
||||
doc.setFont("helvetica", "bold");
|
||||
doc.text(`[Penyerah] ${item.nama_penyerah || "-"}`, 25, 138);
|
||||
doc.text(`[Penerima] ${item.nama_penerima || "-"}`, 25, 146);
|
||||
|
||||
doc.text(
|
||||
`[Penyerah] ${item.nama_penyerah || "-"}`,
|
||||
25,
|
||||
138
|
||||
);
|
||||
|
||||
doc.text(
|
||||
`[Penerima] ${item.nama_penerima || "-"}`,
|
||||
25,
|
||||
146
|
||||
);
|
||||
|
||||
doc.setFont("helvetica", "normal");
|
||||
doc.text("Adapun rincian barang/aset CIFO yang diserahterimakan sebagai berikut:", 20, 160);
|
||||
|
||||
doc.text(
|
||||
"Adapun rincian barang/aset CIFO yang diserahterimakan sebagai berikut:",
|
||||
20,
|
||||
160
|
||||
);
|
||||
|
||||
/* =========================
|
||||
TABEL RINCIAN ASET UKK
|
||||
TABEL RINCIAN ASET
|
||||
========================= */
|
||||
autoTable(doc, {
|
||||
startY: 168,
|
||||
margin: { left: 20, right: 20 },
|
||||
|
||||
margin: {
|
||||
left: 20,
|
||||
right: 20,
|
||||
},
|
||||
|
||||
styles: {
|
||||
fontSize: 10,
|
||||
halign: "center",
|
||||
|
|
@ -121,15 +167,25 @@ export default function TransaksiBAST() {
|
|||
lineWidth: 0.3,
|
||||
lineColor: [0, 0, 0],
|
||||
},
|
||||
|
||||
headStyles: {
|
||||
fillColor: [255, 255, 255],
|
||||
textColor: [0, 0, 0],
|
||||
fontStyle: "bold",
|
||||
},
|
||||
|
||||
bodyStyles: {
|
||||
textColor: [0, 0, 0],
|
||||
},
|
||||
head: [["No.", "Kode Barang", "Nama Barang", "Kondisi Serah", "Kondisi Terima"]],
|
||||
|
||||
head: [[
|
||||
"No.",
|
||||
"Kode Barang",
|
||||
"Nama Barang",
|
||||
"Kondisi Serah",
|
||||
"Kondisi Terima"
|
||||
]],
|
||||
|
||||
body: [[
|
||||
"1",
|
||||
item.kode_barang || "-",
|
||||
|
|
@ -140,145 +196,292 @@ export default function TransaksiBAST() {
|
|||
});
|
||||
|
||||
/* =========================
|
||||
DOKUMEN KLAUSUL PENUTUP
|
||||
DOKUMEN PENUTUP
|
||||
========================= */
|
||||
doc.setFont("helvetica", "normal");
|
||||
|
||||
doc.setFontSize(11);
|
||||
doc.text("Demikian Berita Acara Serah Terima ini dibuat dengan sebenar-benarnya dan", 20, 220);
|
||||
doc.text("dipergunakan sebagaimana mestinya untuk keperluan inventarisasi sekolah.", 20, 232);
|
||||
|
||||
doc.text(
|
||||
"Demikian Berita Acara Serah Terima ini dibuat dengan sebenar-benarnya dan",
|
||||
20,
|
||||
220
|
||||
);
|
||||
|
||||
doc.text(
|
||||
"dipergunakan sebagaimana mestinya untuk keperluan inventarisasi sekolah.",
|
||||
20,
|
||||
232
|
||||
);
|
||||
|
||||
/* =========================
|
||||
TANDA TANGAN (TTD)
|
||||
TANDA TANGAN
|
||||
========================= */
|
||||
doc.setFont("helvetica", "bold");
|
||||
doc.text("Yang Menyerahkan,", 20, 255);
|
||||
doc.text("Yang Menerima,", 125, 255);
|
||||
|
||||
doc.text(
|
||||
"Yang Menyerahkan,",
|
||||
20,
|
||||
255
|
||||
);
|
||||
|
||||
doc.text(
|
||||
"Yang Menerima,",
|
||||
125,
|
||||
255
|
||||
);
|
||||
|
||||
doc.setFont("helvetica", "normal");
|
||||
doc.text(item.nama_penyerah || "-", 20, 285);
|
||||
doc.text(item.nama_penerima || "-", 125, 285);
|
||||
|
||||
doc.text(
|
||||
item.nama_penyerah || "-",
|
||||
20,
|
||||
285
|
||||
);
|
||||
|
||||
doc.text(
|
||||
item.nama_penerima || "-",
|
||||
125,
|
||||
285
|
||||
);
|
||||
|
||||
/* =========================
|
||||
SAVE EKSPOR FILE PDF
|
||||
PREVIEW PDF DI TAB BARU
|
||||
========================= */
|
||||
doc.save(`BAST_CIFO_${item.bast_id}.pdf`);
|
||||
const pdfBlob = doc.output("blob");
|
||||
|
||||
const pdfUrl = URL.createObjectURL(pdfBlob);
|
||||
|
||||
window.open(pdfUrl, "_blank");
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-8 min-h-screen bg-gray-100 dark:bg-gray-900 transition-all duration-300">
|
||||
|
||||
{/* HEADER UTAMA */}
|
||||
{/* HEADER */}
|
||||
<div className="flex justify-between items-center mb-8">
|
||||
|
||||
<div>
|
||||
|
||||
<h1 className="text-4xl font-bold dark:text-white">
|
||||
BAST
|
||||
</h1>
|
||||
|
||||
<p className="text-gray-500 dark:text-gray-300 mt-2">
|
||||
Data serah terima barang logistik resmi perusahaan & sekolah.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* RENDER LAYOUT KONDISIONAL */}
|
||||
{/* RENDER DATA */}
|
||||
{loading ? (
|
||||
|
||||
<div className="p-12 text-center bg-white dark:bg-gray-800 rounded-3xl text-blue-600 font-medium shadow-md animate-pulse">
|
||||
Sedang menyinkronkan data dokumen BAST dari server CIFO... ⏳
|
||||
</div>
|
||||
|
||||
) : dataBAST && dataBAST.length > 0 ? (
|
||||
|
||||
<div className="space-y-5">
|
||||
|
||||
{dataBAST.map((item) => (
|
||||
|
||||
<div
|
||||
key={item.bast_id}
|
||||
className="bg-white dark:bg-gray-800 rounded-3xl shadow-md p-6 border border-gray-200 dark:border-gray-700 hover:shadow-lg transition-all duration-300"
|
||||
>
|
||||
|
||||
<div className="flex flex-col sm:flex-row justify-between items-start gap-4">
|
||||
|
||||
<div className="space-y-2.5 flex-1">
|
||||
{/* ID BAST */}
|
||||
|
||||
{/* ID */}
|
||||
<div className="flex items-center gap-2">
|
||||
<FileText size={20} className="text-blue-600 shrink-0" />
|
||||
|
||||
<FileText
|
||||
size={20}
|
||||
className="text-blue-600 shrink-0"
|
||||
/>
|
||||
|
||||
<h2 className="text-xl font-extrabold dark:text-white">
|
||||
Dokumen BAST #{item.bast_id}
|
||||
</h2>
|
||||
|
||||
</div>
|
||||
|
||||
{/* INFO UTAMA BARANG */}
|
||||
{/* BARANG */}
|
||||
<div>
|
||||
|
||||
<span className="text-xs font-mono font-bold px-2 py-0.5 bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300 rounded">
|
||||
{item.kode_barang || "KODE-BLANK"}
|
||||
</span>
|
||||
|
||||
<p className="text-xl font-bold text-blue-600 dark:text-blue-400 mt-1">
|
||||
{item.nama_barang}
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
{/* KATEGORI & LOKASI ATRIBUT */}
|
||||
{/* KATEGORI */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-4 gap-y-1.5 pt-1 text-sm text-gray-600 dark:text-gray-300">
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<Layers size={16} className="text-gray-400" />
|
||||
<span>Kategori: <strong className="text-gray-800 dark:text-gray-100">{item.nama_kategori || "-"}</strong></span>
|
||||
|
||||
<Layers
|
||||
size={16}
|
||||
className="text-gray-400"
|
||||
/>
|
||||
|
||||
<span>
|
||||
Kategori:
|
||||
<strong className="text-gray-800 dark:text-gray-100">
|
||||
{" "}
|
||||
{item.nama_kategori || "-"}
|
||||
</strong>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<MapPin size={16} className="text-gray-400" />
|
||||
<span>Lokasi: <strong className="text-gray-800 dark:text-gray-100">{item.nama_lokasi || "-"}</strong></span>
|
||||
|
||||
<MapPin
|
||||
size={16}
|
||||
className="text-gray-400"
|
||||
/>
|
||||
|
||||
<span>
|
||||
Lokasi:
|
||||
<strong className="text-gray-800 dark:text-gray-100">
|
||||
{" "}
|
||||
{item.nama_lokasi || "-"}
|
||||
</strong>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* PETUGAS OTORISASI (PENYERAH & PENERIMA) */}
|
||||
{/* USER */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-4 gap-y-1.5 pt-1 border-t border-gray-100 dark:border-gray-700 text-sm text-gray-600 dark:text-gray-300">
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<BadgeCheck size={16} className="text-green-500" />
|
||||
<span>Penyerah: <strong className="text-gray-800 dark:text-gray-100">{item.nama_penyerah || "-"}</strong></span>
|
||||
|
||||
<BadgeCheck
|
||||
size={16}
|
||||
className="text-green-500"
|
||||
/>
|
||||
|
||||
<span>
|
||||
Penyerah:
|
||||
<strong className="text-gray-800 dark:text-gray-100">
|
||||
{" "}
|
||||
{item.nama_penyerah || "-"}
|
||||
</strong>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<User size={16} className="text-blue-500" />
|
||||
<span>Penerima: <strong className="text-gray-800 dark:text-gray-100">{item.nama_penerima || "-"}</strong></span>
|
||||
|
||||
<User
|
||||
size={16}
|
||||
className="text-blue-500"
|
||||
/>
|
||||
|
||||
<span>
|
||||
Penerima:
|
||||
<strong className="text-gray-800 dark:text-gray-100">
|
||||
{" "}
|
||||
{item.nama_penerima || "-"}
|
||||
</strong>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* TRACKING REALTIME TIME STAMP */}
|
||||
{/* TANGGAL */}
|
||||
<div className="flex items-center gap-2 text-xs text-gray-400 pt-1">
|
||||
|
||||
<Clock3 size={14} />
|
||||
<span>Dibuat Pada: {item.dibuat_pada ? new Date(item.dibuat_pada).toLocaleString("id-ID") : "-"}</span>
|
||||
|
||||
<span>
|
||||
Dibuat Pada:{" "}
|
||||
{item.dibuat_pada
|
||||
? new Date(item.dibuat_pada).toLocaleString("id-ID")
|
||||
: "-"}
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* SISI KANAN CONTROL STATUS & CETAK PDF */}
|
||||
{/* KANAN */}
|
||||
<div className="flex sm:flex-col items-end justify-between sm:justify-start w-full sm:w-auto gap-3 self-stretch sm:self-start border-t sm:border-t-0 pt-4 sm:pt-0 border-gray-100 dark:border-gray-700">
|
||||
|
||||
<div className="flex flex-col gap-1 items-end">
|
||||
<span className="text-[10px] uppercase font-bold text-gray-400 tracking-wider">Status Dokumen</span>
|
||||
|
||||
<span className="text-[10px] uppercase font-bold text-gray-400 tracking-wider">
|
||||
Status Dokumen
|
||||
</span>
|
||||
|
||||
<div className="flex gap-1.5">
|
||||
<span className={`text-xs font-bold px-3 py-1 rounded-full ${
|
||||
item.status_serah === "Approved" ? "bg-green-100 text-green-700" : "bg-yellow-100 text-yellow-700"
|
||||
}`}>
|
||||
|
||||
<span
|
||||
className={`text-xs font-bold px-3 py-1 rounded-full ${
|
||||
item.status_serah === "Approved"
|
||||
? "bg-green-100 text-green-700"
|
||||
: "bg-yellow-100 text-yellow-700"
|
||||
}`}
|
||||
>
|
||||
Serah: {item.status_serah}
|
||||
</span>
|
||||
<span className={`text-xs font-bold px-3 py-1 rounded-full ${
|
||||
item.status_terima === "Approved" ? "bg-green-100 text-green-700" : "bg-yellow-100 text-yellow-700"
|
||||
}`}>
|
||||
|
||||
<span
|
||||
className={`text-xs font-bold px-3 py-1 rounded-full ${
|
||||
item.status_terima === "Approved"
|
||||
? "bg-green-100 text-green-700"
|
||||
: "bg-yellow-100 text-yellow-700"
|
||||
}`}
|
||||
>
|
||||
Terima: {item.status_terima}
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={() => downloadPDF(item)}
|
||||
className="flex items-center gap-2 bg-blue-600 hover:bg-blue-700 text-white font-semibold text-sm px-4 py-2.5 rounded-xl shadow-md hover:shadow-lg transition duration-200"
|
||||
>
|
||||
|
||||
<Download size={16} />
|
||||
Cetak PDF
|
||||
|
||||
Preview PDF
|
||||
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
))}
|
||||
|
||||
</div>
|
||||
|
||||
) : (
|
||||
|
||||
<div className="p-12 text-center bg-white dark:bg-gray-800 rounded-3xl border border-gray-200 dark:border-gray-700 text-gray-400 font-medium">
|
||||
Belum ada riwayat dokumen transaksi BAST terdaftar, Bang! 📦
|
||||
</div>
|
||||
|
||||
)}
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue