Improve pantry view

This commit is contained in:
2026-03-24 23:15:56 +01:00
parent 8672c8da28
commit 21901c6147
3 changed files with 270 additions and 40 deletions

View File

@@ -1,6 +1,7 @@
/**
* Katalog składników i przepisów — odpowiednik tabel w DB (edycja poza aplikacją).
* pantryUnit: jednostka magazynowa / sumowania na liście zakupów (g, ml, szt.).
* purchasePack: minimalna „sztuka” ze sklepu w tej samej jednostce co pantryUnit (np. 200 g).
* nutritionPer100g — wartości szacunkowe na 100 g (dla płynów: traktuj ml≈g przy wodzie).
*/
@@ -15,7 +16,13 @@ export const CATEGORY_LABELS = {
inne: 'Inne',
};
/** @type {Record<string, { id: string, name: string, category: keyof typeof CATEGORY_LABELS, pantryUnit: 'g'|'ml'|'szt', nutritionPer100g?: { kcal: number, protein: number, fat: number, carbs: number } }>} */
/**
* @typedef {{ kcal: number, protein: number, fat: number, carbs: number }} NutritionPer100
* @typedef {{ amount: number, label?: string }} PurchasePack
* @typedef {{ id: string, name: string, category: keyof typeof CATEGORY_LABELS, pantryUnit: 'g'|'ml'|'szt', purchasePack?: PurchasePack, nutritionPer100g?: NutritionPer100 }} IngredientDef
*/
/** @type {Record<string, IngredientDef>} */
export const INGREDIENTS = {
maka_pszenna: {
id: 'maka_pszenna',
@@ -29,6 +36,7 @@ export const INGREDIENTS = {
name: 'Mleko',
category: 'nabial',
pantryUnit: 'ml',
purchasePack: { amount: 1000, label: 'butelka 1 l' },
nutritionPer100g: { kcal: 42, protein: 3.4, fat: 1, carbs: 5 },
},
jajko: {
@@ -169,6 +177,7 @@ export const INGREDIENTS = {
name: 'Serek wiejski',
category: 'nabial',
pantryUnit: 'g',
purchasePack: { amount: 200, label: 'opakowanie 200 g' },
nutritionPer100g: { kcal: 97, protein: 11, fat: 5, carbs: 3 },
},
orzechy_wloskie: {
@@ -316,3 +325,47 @@ export const RECIPES = {
],
},
};
/**
* Krok +/- w spiżarni: całe opakowanie albo domyślny krok (10 g/ml lub 1 szt.).
* @param {string} ingredientId
* @returns {number}
*/
export function pantryQtyStep(ingredientId) {
const d = INGREDIENTS[ingredientId];
if (!d) return 10;
if (d.purchasePack && Number.isFinite(d.purchasePack.amount) && d.purchasePack.amount > 0) {
return d.purchasePack.amount;
}
return d.pantryUnit === 'szt' ? 1 : 10;
}
/**
* @param {IngredientDef} def
* @param {number} stockQty — w pantryUnit
*/
export function nutritionForStock(def, stockQty) {
const n = def.nutritionPer100g;
if (!n || !Number.isFinite(stockQty) || stockQty <= 0) return null;
const f = stockQty / 100;
return {
kcal: Math.round(n.kcal * f),
protein: Math.round(n.protein * f * 10) / 10,
fat: Math.round(n.fat * f * 10) / 10,
carbs: Math.round(n.carbs * f * 10) / 10,
};
}
/**
* Pełne opakowania + reszta (np. 450 g / 200 → 2 + 50 g).
* @param {IngredientDef} def
* @param {number} stockQty
* @returns {{ fullPacks: number, remainder: number } | null}
*/
export function splitStockIntoPacks(def, stockQty) {
const size = def.purchasePack?.amount;
if (!size || !Number.isFinite(size) || size <= 0 || !Number.isFinite(stockQty)) return null;
const fullPacks = Math.floor(stockQty / size);
const remainder = Math.round((stockQty - fullPacks * size) * 10) / 10;
return { fullPacks, remainder };
}