Files
star-erp/resources/js/Pages/Inventory/Count/Print.tsx

167 lines
7.1 KiB
TypeScript
Raw Normal View History

import { useEffect, useRef } from 'react';
import { Head } from '@inertiajs/react';
import JsBarcode from 'jsbarcode';
interface PrintProps {
doc: {
doc_no: string;
warehouse_name: string;
snapshot_date: string;
created_at: string;
print_date: string;
created_by: string;
items: Array<{
id: string;
product_name: string;
product_code: string;
specification: string;
unit: string;
quantity: number;
counted_qty: number | null;
notes: string;
}>;
};
}
export default function Print({ doc }: PrintProps) {
const barcodeRef = useRef<SVGSVGElement>(null);
useEffect(() => {
if (barcodeRef.current) {
try {
JsBarcode(barcodeRef.current, doc.doc_no, {
format: "CODE128",
width: 2, // Thicker bars for better scanning
height: 50, // Taller
displayValue: false,
margin: 10, // Mandatory quiet zone for scanners
marginBottom: 5
});
} catch (e) {
console.error("Barcode generation failed", e);
}
}
// Delay print slightly to ensure render
const timer = setTimeout(() => {
window.print();
}, 500);
return () => clearTimeout(timer);
}, [doc.doc_no]);
return (
<div className="bg-white text-black font-sans text-sm min-h-screen">
<Head title={`列印盤點單 ${doc.doc_no}`} />
<style>{`
@media print {
@page {
size: A4 landscape;
margin: 10mm;
}
body {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
/* Hide browser default header/footer if possible (browser dependent) */
}
`}</style>
{/* Header Section */}
<div className="relative mb-6">
{/* Barcode - Top Right */}
<div className="absolute top-0 right-0 flex flex-col items-end">
<svg ref={barcodeRef}></svg>
{/* <span className="text-xs font-mono mt-1">{doc.doc_no}</span> */}
</div>
{/* Company & Title - Center */}
<div className="text-center pt-4">
<h1 className="text-2xl font-bold tracking-widest mb-2"></h1>
<h2 className="text-xl font-bold tracking-widest"></h2>
</div>
</div>
{/* Info Section */}
<div className="flex justify-between items-end mb-2 border-b-2 border-black pb-2">
<div className="space-y-1">
<div className="flex gap-4">
<span className="font-bold"></span>
<span className="font-mono font-bold">{doc.doc_no}</span>
</div>
<div className="flex gap-4">
<span className="font-bold"></span>
<span>{doc.created_at}</span>
</div>
<div className="flex gap-4">
<span className="font-bold"></span>
<span>{doc.warehouse_name}</span>
</div>
</div>
<div className="text-right">
<div className="flex gap-4">
<span className="font-bold"></span>
<span>{doc.print_date}</span>
</div>
</div>
</div>
{/* Table Section */}
<table className="w-full border-collapse border border-black mb-8">
<thead>
<tr className="bg-gray-100">
<th className="border border-black px-2 py-1 w-12 text-center"></th>
<th className="border border-black px-2 py-1 w-32 text-left"></th>
<th className="border border-black px-2 py-1 text-left"></th>
<th className="border border-black px-2 py-1 w-32 text-left"></th>
<th className="border border-black px-2 py-1 w-20 text-right"></th>
<th className="border border-black px-2 py-1 w-16 text-center"></th>
<th className="border border-black px-2 py-1 w-32 text-left"></th>
</tr>
</thead>
<tbody>
{doc.items.map((item, index) => (
<tr key={item.id}>
<td className="border border-black px-2 py-2 text-center">{index + 1}</td>
<td className="border border-black px-2 py-2 font-mono">{item.product_code}</td>
<td className="border border-black px-2 py-2">{item.product_name}</td>
<td className="border border-black px-2 py-2">{item.specification || '-'}</td>
<td className="border border-black px-2 py-2 text-right">
{item.counted_qty !== null ? Number(item.counted_qty).toFixed(2) : ''}
</td>
<td className="border border-black px-2 py-2 text-center">{item.unit || '-'}</td>
<td className="border border-black px-2 py-2">{item.notes}</td>
</tr>
))}
{/* Empty rows filler if needed, but usually not required unless strictly paging */}
</tbody>
</table>
{/* Footer Section */}
<div className="fixed bottom-0 w-full mb-4">
<div className="flex justify-between items-end px-4">
<div className="w-1/3 border-b border-black pb-1 mb-1">
<span className="font-bold"></span>
<span className="ml-2">{doc.created_by}</span>
</div>
<div className="w-1/3 border-b border-black pb-1 mb-1 mx-4">
<span className="font-bold"></span>
</div>
<div className="w-1/3 border-b border-black pb-1 mb-1">
<span className="font-bold"></span>
</div>
</div>
<div className="flex justify-between items-center text-xs mt-4 px-4">
<div>
&nbsp;&nbsp; {doc.created_by}
</div>
<div>
1 / 1
</div>
</div>
</div>
</div>
);
}