From de0008f5c75f43e29e1e2e3d3a46f2e2263f4e88 Mon Sep 17 00:00:00 2001 From: pyr0ball Date: Thu, 16 Apr 2026 10:50:34 -0700 Subject: [PATCH] fix: meal planner auto-selects current week on load, + New week idempotent - Add autoSelectPlan() to the store: after loadPlans() resolves, set activePlan to the current week's plan (or most recent) without a second API round-trip -- list already returns full PlanSummary with slots - Call autoSelectPlan(mondayOfCurrentWeek()) in onMounted so the grid populates immediately without the user touching the dropdown - Make onNewPlan idempotent: if a 409 comes back, activate the existing plan for that week instead of surfacing an error to the user --- frontend/src/components/MealPlanView.vue | 20 ++++++++++++++------ frontend/src/stores/mealPlan.ts | 16 +++++++++++++++- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/MealPlanView.vue b/frontend/src/components/MealPlanView.vue index d69de44..7ee4c1e 100644 --- a/frontend/src/components/MealPlanView.vue +++ b/frontend/src/components/MealPlanView.vue @@ -101,7 +101,10 @@ const canAddMealType = computed(() => (activePlan.value?.meal_types.length ?? 0) < 4 ) -onMounted(() => store.loadPlans()) +onMounted(async () => { + await store.loadPlans() + store.autoSelectPlan(mondayOfCurrentWeek()) +}) function mondayOfCurrentWeek(): string { const today = new Date() @@ -116,15 +119,20 @@ function mondayOfCurrentWeek(): string { async function onNewPlan() { planError.value = null planCreating.value = true + const weekStart = mondayOfCurrentWeek() try { - const weekStart = mondayOfCurrentWeek() await store.createPlan(weekStart, ['dinner']) } catch (err: unknown) { const msg = err instanceof Error ? err.message : String(err) - // 409 means a plan for this week already exists — surface it helpfully - planError.value = msg.includes('409') || msg.toLowerCase().includes('already exists') - ? 'A plan for this week already exists. Select it from the dropdown above.' - : `Couldn't create plan: ${msg}` + if (msg.includes('409') || msg.toLowerCase().includes('already exists')) { + // Plan for this week exists — just activate it instead of erroring + const existing = plans.value.find(p => p.week_start === weekStart) + if (existing) { + await store.setActivePlan(existing.id) + } + } else { + planError.value = `Couldn't create plan: ${msg}` + } } finally { planCreating.value = false } diff --git a/frontend/src/stores/mealPlan.ts b/frontend/src/stores/mealPlan.ts index 2c50324..d287d8c 100644 --- a/frontend/src/stores/mealPlan.ts +++ b/frontend/src/stores/mealPlan.ts @@ -40,6 +40,20 @@ export const useMealPlanStore = defineStore('mealPlan', () => { } } + /** + * Auto-select the best available plan without a round-trip. + * Prefers the plan whose week_start matches preferredWeekStart (current week's Monday). + * Falls back to the first plan in the list (most recent, since list is DESC). + * No-ops if a plan is already active or no plans exist. + */ + function autoSelectPlan(preferredWeekStart?: string) { + if (activePlan.value || plans.value.length === 0) return + const match = preferredWeekStart + ? (plans.value.find(p => p.week_start === preferredWeekStart) ?? plans.value[0]) + : plans.value[0] + if (match) activePlan.value = match ?? null + } + async function createPlan(weekStart: string, mealTypes: string[]): Promise { const plan = await mealPlanAPI.create(weekStart, mealTypes) plans.value = [plan, ...plans.value] @@ -129,7 +143,7 @@ export const useMealPlanStore = defineStore('mealPlan', () => { return { plans, activePlan, shoppingList, prepSession, loading, shoppingListLoading, prepLoading, slots, - getSlot, loadPlans, createPlan, setActivePlan, + getSlot, loadPlans, autoSelectPlan, createPlan, setActivePlan, upsertSlot, clearSlot, loadShoppingList, loadPrepSession, updatePrepTask, } })