Add pantry and shopping lists
This commit is contained in:
85
stacks/recipe/js/services/planStore.js
Normal file
85
stacks/recipe/js/services/planStore.js
Normal file
@@ -0,0 +1,85 @@
|
||||
import { RECIPES } from '../data/catalog.js';
|
||||
import { MEAL_SLOTS } from '../planner/mealSlots.js';
|
||||
import { PLANS_STORAGE_KEY } from '../storageKeys.js';
|
||||
import { startOfDay } from './dateUtils.js';
|
||||
|
||||
export function dateKey(d) {
|
||||
const x = startOfDay(d);
|
||||
const y = x.getFullYear();
|
||||
const m = String(x.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(x.getDate()).padStart(2, '0');
|
||||
return `${y}-${m}-${day}`;
|
||||
}
|
||||
|
||||
export function newPlanEntryId() {
|
||||
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
|
||||
return crypto.randomUUID();
|
||||
}
|
||||
return `e${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
||||
}
|
||||
|
||||
/** Jedna pora dnia = tablica wpisów { id, recipeId, servings } */
|
||||
export function normalizeSlotValue(v) {
|
||||
if (!v) return [];
|
||||
if (Array.isArray(v)) {
|
||||
return v
|
||||
.filter((x) => x && x.recipeId && RECIPES[x.recipeId])
|
||||
.map((x) => ({
|
||||
id: x.id && String(x.id).length ? String(x.id) : newPlanEntryId(),
|
||||
recipeId: x.recipeId,
|
||||
servings: Math.max(1, Math.min(12, Number(x.servings) || 1)),
|
||||
}));
|
||||
}
|
||||
if (typeof v === 'object' && v.recipeId && RECIPES[v.recipeId]) {
|
||||
return [{
|
||||
id: newPlanEntryId(),
|
||||
recipeId: v.recipeId,
|
||||
servings: Math.max(1, Math.min(12, Number(v.servings) || 1)),
|
||||
}];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
export function normalizeDayPlan(day) {
|
||||
if (!day || typeof day !== 'object') return {};
|
||||
const out = {};
|
||||
MEAL_SLOTS.forEach((s) => {
|
||||
const arr = normalizeSlotValue(day[s.id]);
|
||||
if (arr.length > 0) out[s.id] = arr;
|
||||
});
|
||||
return out;
|
||||
}
|
||||
|
||||
export function normalizeAllPlans(plans) {
|
||||
if (!plans || typeof plans !== 'object') return {};
|
||||
const out = {};
|
||||
Object.keys(plans).forEach((key) => {
|
||||
const d = normalizeDayPlan(plans[key]);
|
||||
if (Object.keys(d).length > 0) out[key] = d;
|
||||
});
|
||||
return out;
|
||||
}
|
||||
|
||||
export function loadPlans() {
|
||||
try {
|
||||
const raw = localStorage.getItem(PLANS_STORAGE_KEY);
|
||||
if (!raw) return {};
|
||||
const parsed = JSON.parse(raw);
|
||||
if (typeof parsed !== 'object' || parsed === null) return {};
|
||||
return normalizeAllPlans(parsed);
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
export function savePlans(plans) {
|
||||
try {
|
||||
localStorage.setItem(PLANS_STORAGE_KEY, JSON.stringify(plans));
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
export function getDayPlan(plans, d) {
|
||||
const key = dateKey(d);
|
||||
const day = plans[key];
|
||||
return day && typeof day === 'object' ? day : {};
|
||||
}
|
||||
Reference in New Issue
Block a user