feat(weekplan): MIKRO WEEK-2 dagliga måltidsslots (vardag middag, helg lunch+middag)
This commit is contained in:
@@ -79,6 +79,11 @@ export default function PlanScreen() {
|
|||||||
}, []);
|
}, []);
|
||||||
const mondayKey = toKey(monday);
|
const mondayKey = toKey(monday);
|
||||||
const weekDays = useMemo(() => Array.from({ length: 7 }, (_, i) => addDays(monday, i)), [monday]);
|
const weekDays = useMemo(() => Array.from({ length: 7 }, (_, i) => addDays(monday, i)), [monday]);
|
||||||
|
// Vardag: middag. Helg (lör/sön): lunch + middag. Realistisk förifylld default.
|
||||||
|
const mealSlots = useMemo(
|
||||||
|
() => weekDays.map((d) => (d.getDay() === 0 || d.getDay() === 6 ? ["lunch", "dinner"] : ["dinner"])),
|
||||||
|
[weekDays],
|
||||||
|
);
|
||||||
|
|
||||||
const query = useQuery({
|
const query = useQuery({
|
||||||
queryKey: ["week-plan", mondayKey],
|
queryKey: ["week-plan", mondayKey],
|
||||||
@@ -125,7 +130,7 @@ export default function PlanScreen() {
|
|||||||
mutationFn: () =>
|
mutationFn: () =>
|
||||||
api("/v1/week-plans/generate", {
|
api("/v1/week-plans/generate", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: { weekStartDate: mondayKey, mealTypes: ["lunch", "dinner"] },
|
body: { weekStartDate: mondayKey, mealTypes: ["lunch", "dinner"], mealSlots },
|
||||||
}),
|
}),
|
||||||
onSuccess: () => setGenerating(true),
|
onSuccess: () => setGenerating(true),
|
||||||
onError: onMutationError,
|
onError: onMutationError,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ interface WeekPlanJobInput {
|
|||||||
weekStartDate: string;
|
weekStartDate: string;
|
||||||
daysToPlann?: number;
|
daysToPlann?: number;
|
||||||
mealTypes: MealType[];
|
mealTypes: MealType[];
|
||||||
|
mealSlots?: MealType[][];
|
||||||
portionsPerMeal?: number;
|
portionsPerMeal?: number;
|
||||||
budgetMinorTotal?: number;
|
budgetMinorTotal?: number;
|
||||||
preferLeftoversFirst: boolean;
|
preferLeftoversFirst: boolean;
|
||||||
@@ -228,7 +229,8 @@ export async function processGenerateWeekPlan(
|
|||||||
const date = new Date(Date.parse(data.input.weekStartDate) + day * 86_400_000)
|
const date = new Date(Date.parse(data.input.weekStartDate) + day * 86_400_000)
|
||||||
.toISOString()
|
.toISOString()
|
||||||
.slice(0, 10);
|
.slice(0, 10);
|
||||||
for (const mealType of mealTypes) {
|
const dayMeals = data.input.mealSlots ? (data.input.mealSlots[day] ?? []) : mealTypes;
|
||||||
|
for (const mealType of dayMeals) {
|
||||||
// Matlåda om det finns och portionerna räcker
|
// Matlåda om det finns och portionerna räcker
|
||||||
const box = mealBoxes[boxIndex];
|
const box = mealBoxes[boxIndex];
|
||||||
if (box && box.portionsRemaining >= Math.min(portions, 2)) {
|
if (box && box.portionsRemaining >= Math.min(portions, 2)) {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export const generateWeekPlanInputSchema = z.object({
|
|||||||
weekStartDate: dateStringSchema,
|
weekStartDate: dateStringSchema,
|
||||||
daysToPlann: z.number().int().min(1).max(14).optional(),
|
daysToPlann: z.number().int().min(1).max(14).optional(),
|
||||||
mealTypes: z.array(z.enum(MEAL_TYPES)).min(1).default(["dinner"]),
|
mealTypes: z.array(z.enum(MEAL_TYPES)).min(1).default(["dinner"]),
|
||||||
|
mealSlots: z.array(z.array(z.enum(MEAL_TYPES))).optional(),
|
||||||
portionsPerMeal: z.number().int().min(1).max(20).optional(),
|
portionsPerMeal: z.number().int().min(1).max(20).optional(),
|
||||||
budgetMinorTotal: z.number().int().min(0).max(5_000_000).optional(),
|
budgetMinorTotal: z.number().int().min(0).max(5_000_000).optional(),
|
||||||
/** T.ex. "Sju middagar för fyra personer under 1 000 kr" (spec §26). */
|
/** T.ex. "Sju middagar för fyra personer under 1 000 kr" (spec §26). */
|
||||||
|
|||||||
Reference in New Issue
Block a user