edit for deplyment
This commit is contained in:
@ -6,6 +6,7 @@ import { Printer, AlertCircle } from "lucide-react";
|
||||
|
||||
export default function PrintPage() {
|
||||
const [items, setItems] = useState([]);
|
||||
const [selectedIds, setSelectedIds] = useState(new Set());
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
@ -16,6 +17,7 @@ export default function PrintPage() {
|
||||
if (!res.ok) throw new Error("Failed to fetch inventory from database");
|
||||
const data = await res.json();
|
||||
setItems(data);
|
||||
setSelectedIds(new Set(data.map(i => i.id)));
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
@ -26,9 +28,24 @@ export default function PrintPage() {
|
||||
}, []);
|
||||
|
||||
const handlePrint = () => {
|
||||
if (selectedIds.size === 0) return alert("Please select at least one label to print.");
|
||||
window.print();
|
||||
};
|
||||
|
||||
const toggleSelection = (id) => {
|
||||
const next = new Set(selectedIds);
|
||||
if (next.has(id)) next.delete(id);
|
||||
else next.add(id);
|
||||
setSelectedIds(next);
|
||||
};
|
||||
|
||||
const toggleAll = () => {
|
||||
if (selectedIds.size === items.length) setSelectedIds(new Set());
|
||||
else setSelectedIds(new Set(items.map(i => i.id)));
|
||||
};
|
||||
|
||||
const itemsToPrint = items.filter(i => selectedIds.has(i.id));
|
||||
|
||||
if (loading) return <div className="p-8 text-center">Loading inventory codes...</div>;
|
||||
if (error) return <div className="p-8 text-danger">Error: {error}</div>;
|
||||
|
||||
@ -64,11 +81,55 @@ export default function PrintPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Item Selection Table (Hidden in Print) */}
|
||||
<div className="glass no-print mb-6">
|
||||
<div className="flex justify-between items-center mb-4" style={{ padding: "0 1rem" }}>
|
||||
<h3 className="text-muted">Select Labels to Print ({selectedIds.size} selected)</h3>
|
||||
<button className="btn btn-secondary" style={{ padding: "0.25rem 0.75rem", fontSize: "0.85rem" }} onClick={toggleAll}>
|
||||
{selectedIds.size === items.length ? "Deselect All" : "Select All"}
|
||||
</button>
|
||||
</div>
|
||||
<div className="table-container" style={{ maxHeight: "300px", overflowY: "auto" }}>
|
||||
<table className="data-table">
|
||||
<thead style={{ position: "sticky", top: 0, zIndex: 1, backgroundColor: "var(--bg-card)" }}>
|
||||
<tr>
|
||||
<th style={{ width: "50px", textAlign: "center" }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selectedIds.size === items.length && items.length > 0}
|
||||
onChange={toggleAll}
|
||||
/>
|
||||
</th>
|
||||
<th>Name</th>
|
||||
<th>QR ID</th>
|
||||
<th>Category</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items.map(item => (
|
||||
<tr key={item.id} style={{ cursor: "pointer", opacity: selectedIds.has(item.id) ? 1 : 0.6 }} onClick={() => toggleSelection(item.id)}>
|
||||
<td style={{ textAlign: "center" }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selectedIds.has(item.id)}
|
||||
onChange={() => {}} /* Handled by row click */
|
||||
/>
|
||||
</td>
|
||||
<td style={{ fontWeight: 500 }}>{item.name}</td>
|
||||
<td><code className="text-muted">{item.qrCodeId}</code></td>
|
||||
<td>{item.category || "-"}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Printable Sheet Area */}
|
||||
{/* Printable Sheet Area */}
|
||||
{Array.from({ length: Math.ceil(items.length / 30) }, (_, pageIndex) => (
|
||||
{Array.from({ length: Math.ceil(itemsToPrint.length / 30) }, (_, pageIndex) => (
|
||||
<div key={pageIndex} className="print-container">
|
||||
{items.slice(pageIndex * 30, (pageIndex + 1) * 30).map((item) => (
|
||||
{itemsToPrint.slice(pageIndex * 30, (pageIndex + 1) * 30).map((item) => (
|
||||
<div key={item.id} className="label-cell">
|
||||
<div className="qr-wrapper">
|
||||
<QRCode
|
||||
|
||||
Reference in New Issue
Block a user