From 21b59dc0cf31c39251ce2ca48c56c5714fc82a4d Mon Sep 17 00:00:00 2001 From: suskozaver Date: Thu, 17 Sep 2026 19:18:22 +0200 Subject: [PATCH] Let an existing pack be given its tablet size The tablets feature shipped with one way to record how big a tablet is: the add form, and only when the compound was already marked as tablets. Everything else arrived without it. A pack added before the compound was described that way, a row entered as an ordinary vial, anything imported: all of them visible on the shelf, none of them countable, and the Log a dose form saying "Add the tablet size to the pack first" with nowhere to do it. So the Stock row offers it. For a pack, and also for an ordinary row of a compound the library calls tablets, which is how such a row becomes a pack at all. It asks for both numbers, because a pack's strengthMg is the mass of the whole pack and is the product of the two, and it says what the row will read once saved, including any dose already taken. When identical vials are grouped it writes to every member, unlike the buttons beside it. Those change one vial's state and the group is meant to split; this changes what the row has always been, and writing it to one member would leave a pack with a size beside a shelf of identical packs without one. The log hint also told two different stories with one sentence. No pack in stock at all and a pack with no size recorded both read as an instruction to go and edit a pack, which in the first case does not exist. Three states, three sentences. --- src/app/stock/page.tsx | 138 ++++++++++++++++++++++++++++++++ src/components/LogDoseSheet.tsx | 14 +++- src/lib/i18n/translations.ts | 20 ++++- 3 files changed, 165 insertions(+), 7 deletions(-) diff --git a/src/app/stock/page.tsx b/src/app/stock/page.tsx index 010c65f..24801ee 100755 --- a/src/app/stock/page.tsx +++ b/src/app/stock/page.tsx @@ -91,6 +91,16 @@ export default function StockPage() { const [toppingUp, setToppingUp] = useState(null); /** Which vial is being emptied into a nasal spray bottle. */ const [transferring, setTransferring] = useState(null); + /** + * Which row is having its tablet size set. + * + * Needed because a pack can exist before anyone said how big one tablet is: + * added before the compound was marked as tablets, or imported, or added + * while the compound was still described as a powder. Without a way to say it + * afterwards the pack is stuck, countable by nothing, and the form for + * logging a dose can only say that the size is missing. + */ + const [sizing, setSizing] = useState(null); const now = Date.now(); /* @@ -357,7 +367,33 @@ export default function StockPage() { solution it can never be. */ onReconstitute={isPack(v) ? undefined : () => setReconstituting(v.id)} + tabletCompound={findPeptide(custom, v.peptideId)?.preparation === "tablet"} + onSetTabletSize={() => setSizing(v.id)} /> + {sizing === v.id && ( + setSizing(null)} + onSave={(mgEach, tabletsInPack) => { + /* + Every vial in the group, unlike the buttons beside it, + which act on the oldest one alone. Those change one + vial's state and the group is meant to split. This + changes what the row has always been, so writing it to + one member would break the group into a pack with a + size and a shelf of identical packs without one. + */ + for (const target of group ? group.vials : [v]) { + updateVial(target.id, { + container: "pack", + mgPerTablet: mgEach, + strengthMg: packStrengthMg(mgEach, tabletsInPack), + }); + } + setSizing(null); + }} + /> + )} {reconstituting === v.id && ( void; onFinish?: () => void; + /** Whether the library says this compound comes as tablets. */ + tabletCompound?: boolean; + onSetTabletSize?: () => void; }) { const { t } = useLang(); const st = vialStatus(vial, now); @@ -703,6 +744,18 @@ function VialRow({ {t("stock_to_spray")} )} + {/* + Offered for a pack, and also for an ordinary row of a compound the + library calls tablets, which is how a row added before anyone said + so becomes a pack at all. Without the second case the size could + only ever be set at the moment of adding, and a pack added the day + before the compound was marked as tablets was stuck for good. + */} + {onSetTabletSize && (pack || tabletCompound) && ( + + )} {onFinish && ( + + + + ); +} + function TopUpForm({ vial, bottles, diff --git a/src/components/LogDoseSheet.tsx b/src/components/LogDoseSheet.tsx index 3f66cbd..0576545 100755 --- a/src/components/LogDoseSheet.tsx +++ b/src/components/LogDoseSheet.tsx @@ -567,9 +567,17 @@ export function LogDoseSheet({ 0 - ? t("log_per_tablet_hint", { dose: formatDose(mcgPerTablet(vial)) }) - : t("log_no_tablet_size") + /* + Three states, three sentences. The first version said "add + the tablet size to the pack" whether or not there was a pack + to add it to, which reads as an instruction with nowhere to + carry it out. + */ + !vial + ? t("log_no_pack_in_stock") + : mcgPerTablet(vial) > 0 + ? t("log_per_tablet_hint", { dose: formatDose(mcgPerTablet(vial)) }) + : t("log_no_tablet_size") } >