diff --git a/frontend/src/services/api.ts b/frontend/src/services/api.ts index 857c3f9..bc1d7d6 100644 --- a/frontend/src/services/api.ts +++ b/frontend/src/services/api.ts @@ -645,6 +645,112 @@ export const savedRecipesAPI = { }, } +// --- Meal Plan types --- + +export interface MealPlanSlot { + id: number + plan_id: number + day_of_week: number // 0 = Monday + meal_type: string + recipe_id: number | null + recipe_title: string | null + servings: number + custom_label: string | null +} + +export interface MealPlan { + id: number + week_start: string // ISO date, e.g. "2026-04-13" + meal_types: string[] + slots: MealPlanSlot[] + created_at: string +} + +export interface RetailerLink { + retailer: string + label: string + url: string +} + +export interface GapItem { + ingredient_name: string + needed_raw: string | null + have_quantity: number | null + have_unit: string | null + covered: boolean + retailer_links: RetailerLink[] +} + +export interface ShoppingList { + plan_id: number + gap_items: GapItem[] + covered_items: GapItem[] + disclosure: string | null +} + +export interface PrepTask { + id: number + recipe_id: number | null + task_label: string + duration_minutes: number | null + sequence_order: number + equipment: string | null + is_parallel: boolean + notes: string | null + user_edited: boolean +} + +export interface PrepSession { + id: number + plan_id: number + scheduled_date: string + status: 'draft' | 'reviewed' | 'done' + tasks: PrepTask[] +} + +// --- Meal Plan API --- + +export const mealPlanAPI = { + async list(): Promise { + const resp = await api.get('/meal-plans/') + return resp.data + }, + + async create(weekStart: string, mealTypes: string[]): Promise { + const resp = await api.post('/meal-plans/', { week_start: weekStart, meal_types: mealTypes }) + return resp.data + }, + + async get(planId: number): Promise { + const resp = await api.get(`/meal-plans/${planId}`) + return resp.data + }, + + async upsertSlot(planId: number, dayOfWeek: number, mealType: string, data: { recipe_id?: number | null; servings?: number; custom_label?: string | null }): Promise { + const resp = await api.put(`/meal-plans/${planId}/slots/${dayOfWeek}/${mealType}`, data) + return resp.data + }, + + async deleteSlot(planId: number, slotId: number): Promise { + await api.delete(`/meal-plans/${planId}/slots/${slotId}`) + }, + + async getShoppingList(planId: number): Promise { + const resp = await api.get(`/meal-plans/${planId}/shopping-list`) + return resp.data + }, + + async getPrepSession(planId: number): Promise { + const resp = await api.get(`/meal-plans/${planId}/prep-session`) + return resp.data + }, + + async updatePrepTask(planId: number, taskId: number, data: Partial>): Promise { + const resp = await api.patch(`/meal-plans/${planId}/prep-session/tasks/${taskId}`, data) + return resp.data + }, +} + // ========== Browser Types ========== export interface BrowserDomain {