Add container weight tracking for weigh-based concentrate audits
Build and push image / build (push) Successful in 1m6s

Record the total weight of a jar (product + container) at acquisition so
audits can be done by simply re-weighing the sealed jar. The tare is
derived (containerWeight − productWeight), and the audit flow offers a
"Weigh container" toggle that auto-calculates remaining product from the
scale reading.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-07 23:11:39 -04:00
parent e9e66ab1cb
commit a1be29ab6e
11 changed files with 205 additions and 26 deletions
@@ -1,6 +1,7 @@
import { useState } from "react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import type { Bootstrap, Item } from "../../types.js";
import { TYPES } from "../../types.js";
import { api } from "../../api.js";
import type { BatchOp } from "../../api.js";
import { Btn, Field, Input, Select } from "../primitives/index.js";
@@ -26,8 +27,14 @@ export function BulkEditModal({
const [cbd, setCbd] = useState("");
const [totalCannabinoids, setTotalCannabinoids] = useState("");
const [purchaseDate, setPurchaseDate] = useState("");
const [containerWeight, setContainerWeight] = useState("");
const [error, setError] = useState<string | null>(null);
const hasBulkWeighable = items.some((i) => {
const cfg = TYPES.find((t) => t.id === i.type);
return i.kind === "bulk" && cfg?.weighable;
});
const save = useMutation({
mutationFn: () => {
const fields: Record<string, string | number | null> = {};
@@ -38,6 +45,7 @@ export function BulkEditModal({
if (cbd !== "") fields.cbd = parseFloat(cbd);
if (totalCannabinoids !== "") fields.totalCannabinoids = parseFloat(totalCannabinoids);
if (purchaseDate) fields.purchaseDate = purchaseDate;
if (containerWeight !== "") fields.containerWeight = parseFloat(containerWeight);
if (Object.keys(fields).length === 0) {
return Promise.reject(new Error("No fields to update — fill in at least one field."));
@@ -163,6 +171,20 @@ export function BulkEditModal({
</Field>
</div>
{hasBulkWeighable && (
<div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 16, marginTop: 16 }}>
<Field label="Container weight (g)">
<Input
type="number"
step="0.01"
placeholder="—"
value={containerWeight}
onChange={(e) => setContainerWeight(e.target.value)}
/>
</Field>
</div>
)}
{error && (
<div style={{ marginTop: 14, fontSize: 12, color: "var(--terracotta)" }}>{error}</div>
)}