From 9fb1a726dd1a38fdf9cbbf69b44e0f191247c818 Mon Sep 17 00:00:00 2001 From: Arnaud Nelissen Date: Mon, 15 Jun 2026 15:34:35 +0200 Subject: [PATCH] feat(pump): link pump events to milk stock, fix expiry units - PUMP modal: "Ajouter au stock" toggle with location selector - Merge option: pick existing today's lot to add volume to (expiry kept) - On save: POST new MilkStock or PATCH existing volume - Milk page: expiry input now in hours/days/months per location - Milk page: "soon" alert threshold scales per location (freezer=7d, fridge=24h, room=2h) Co-Authored-By: Claude Sonnet 4.6 --- src/app/(app)/milk/page.tsx | 47 +++++++++++++---- src/components/event-modal.tsx | 93 ++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 10 deletions(-) diff --git a/src/app/(app)/milk/page.tsx b/src/app/(app)/milk/page.tsx index 7fb8a1a..fd8909b 100644 --- a/src/app/(app)/milk/page.tsx +++ b/src/app/(app)/milk/page.tsx @@ -37,7 +37,13 @@ function expiryStatus(stock: Stock): "expired" | "soon" | "ok" { const now = Date.now(); const exp = new Date(stock.expiresAt).getTime(); if (exp <= now) return "expired"; - if (exp - now < 6 * 60 * 60 * 1000) return "soon"; // < 6h + // "soon" threshold scales with location: room <2h, fridge <24h, freezer <7d + const remaining = exp - now; + const soonMs = + stock.location === "freezer" ? 7 * 24 * 3600_000 : + stock.location === "fridge" ? 24 * 3600_000 : + 2 * 3600_000; + if (remaining < soonMs) return "soon"; return "ok"; } @@ -51,7 +57,7 @@ export default function MilkPage() { volume: "", storedAt: localNowString(), notes: "", - expiryHours: "", + expiryCustom: "", // in hours (room), days (fridge), months (freezer) }); const [saving, setSaving] = useState(false); @@ -77,7 +83,13 @@ export default function MilkPage() { e.preventDefault(); if (!selectedBaby) return; setSaving(true); - const expiryHours = form.expiryHours ? parseFloat(form.expiryHours) : undefined; + let expiryCustom: number | undefined; + if (form.expiryCustom) { + const v = parseFloat(form.expiryCustom); + if (location === "fridge") expiryCustom = v * 24; + else if (location === "freezer") expiryCustom = v * 24 * 30; + else expiryCustom = v; + } await fetch("/api/milk", { method: "POST", headers: { "Content-Type": "application/json" }, @@ -87,11 +99,11 @@ export default function MilkPage() { storedAt: form.storedAt, location, notes: form.notes || null, - expiryHours, + expiryCustom, }), }); qc.invalidateQueries({ queryKey: ["milk"] }); - setForm({ volume: "", storedAt: localNowString(), notes: "", expiryHours: "" }); + setForm({ volume: "", storedAt: localNowString(), notes: "", expiryCustom: "" }); setShowForm(false); setSaving(false); } @@ -177,7 +189,7 @@ export default function MilkPage() { return ( + {addToStock && ( +
+
+ +
+ {(["room", "fridge", "freezer"] as const).map((loc) => ( + + ))} +
+
+ {todayLots.length > 0 && ( +
+ +
+ + {todayLots.map((lot) => ( + + ))} +
+ {mergeLotId && ( +

+ Volume sera ajouté à ce lot. Péremption inchangée. +

+ )} +
+ )} +
+ )} + + )} )}