diff --git a/src/lib/pdf/stock-item-stocktake-document.tsx b/src/lib/pdf/stock-item-stocktake-document.tsx
index c93d53b..a53ccc9 100644
--- a/src/lib/pdf/stock-item-stocktake-document.tsx
+++ b/src/lib/pdf/stock-item-stocktake-document.tsx
@@ -8,6 +8,9 @@ export interface StockItemStocktakeDocumentProps {
generatedAtIso: string;
}
+const ZEBRA_EVEN = "#f8fafc"; // slate-50 — subtle alternating row tint
+const ZEBRA_ODD = "#ffffff";
+
const styles = StyleSheet.create({
page: { padding: 28, fontSize: 9, fontFamily: "Helvetica" },
header: { marginBottom: 18 },
@@ -30,29 +33,40 @@ const styles = StyleSheet.create({
paddingVertical: 4,
paddingHorizontal: 4,
},
+ trEven: {
+ flexDirection: "row",
+ backgroundColor: ZEBRA_EVEN,
+ borderBottomWidth: 0.5,
+ borderBottomColor: "#ddd",
+ paddingVertical: 4,
+ paddingHorizontal: 4,
+ },
td: { fontSize: 9 },
tdRight: { fontSize: 9, textAlign: "right" },
- // Columns mirror the /stock page table so a printed copy feels
- // familiar to the operator. Landscape A4 gives 8 columns room to
- // breathe — same allocation as the stock-orders list PDF.
- cSku: { width: "9%" },
- cName: { width: "18%" },
- cSupplier: { width: "16%" },
- cCurrent: { width: "8%" },
- cMin: { width: "7%" },
- cTarget: { width: "8%" },
- cLocation: { width: "14%" },
- cStatus: { width: "12%" },
- spacer: { width: "8%" },
+ // Status is rendered with the status colour (from STOCK_STATUS_STYLES)
+ // and bold, so it pops as a right-side summary of the row.
+ tdStatus: { fontSize: 9, fontFamily: "Helvetica-Bold" },
+ // Columns mirror the on-screen /stock table — Location dropped, Target
+ // renamed to "Max". Name and Status widened so the row reads at a
+ // glance. Landscape A4 has plenty of horizontal room.
+ cSku: { width: "10%" },
+ cName: { width: "24%" },
+ cSupplier: { width: "18%" },
+ cCurrent: { width: "9%" },
+ cMin: { width: "8%" },
+ cMax: { width: "9%" },
+ cStatus: { width: "16%" },
+ spacer: { width: "6%" },
empty: { marginTop: 24, color: "#666", fontSize: 10, textAlign: "center" },
});
/**
* Stock list PDF — landscape A4, every active stock item in a
* table sorted by name. Columns mirror the on-screen /stock table
- * (SKU, Name, Supplier, Current, Min, Target, Location, Status) so
- * the printed copy is recognisable. The Status column uses the same
- * `getStockStatus` derivation as the on-screen badge.
+ * minus Location, with Target renamed to "Max" and the Name column
+ * widened. Rows alternate subtle zebra tinting so adjacent rows are
+ * easy to scan; the Status column sits at the right edge and is
+ * bold + colour-coded against the on-screen badge palette.
*/
export function StockItemStocktakeDocument({
items,
@@ -80,10 +94,9 @@ export function StockItemStocktakeDocument({
Min
-
- Target
+
+ Max
- Location
Status
@@ -92,21 +105,22 @@ export function StockItemStocktakeDocument({
No active stock items.
) : (
- {items.map((item) => {
+ {items.map((item, idx) => {
const status = getStockStatus(
item.current_qty,
item.min_qty,
item.is_active,
);
- const statusLabel = STOCK_STATUS_STYLES[status].label;
+ const statusStyle = STOCK_STATUS_STYLES[status];
const currentQty = Number(item.current_qty ?? 0);
const minQty = Number(item.min_qty ?? 0);
- const targetQty =
+ const maxQty =
item.target_qty !== undefined && item.target_qty !== null
? Number(item.target_qty)
: null;
+ const rowStyle = idx % 2 === 0 ? styles.trEven : styles.tr;
return (
-
+
{item.sku || "—"}
{item.name}
@@ -117,13 +131,14 @@ export function StockItemStocktakeDocument({
{item.unit ? ` ${item.unit}` : ""}
{minQty}
-
- {targetQty !== null && targetQty > 0 ? targetQty : "—"}
+
+ {maxQty !== null && maxQty > 0 ? maxQty : "—"}
-
- {item.location || "—"}
+
+ {statusStyle.label}
- {statusLabel}
);