feat: implement frontend Web UI pages

- Add types for all API models (MealPlan, Recipe, Ingredient, etc.)
- Add API client with mealPlannerApi wrapper for all endpoints
- Implement Dashboard with weekly meal plan grid view
- Implement Pantry page with add/remove functionality
- Implement MealDetail page with recipe display
- Implement ShoppingList page with aisle grouping
- Add ShoppingList route to App.tsx
- Add vite-env.d.ts for Vite env type support
This commit is contained in:
2026-05-04 20:54:54 -07:00
parent 933a0cc9db
commit 08e196b0ab
8 changed files with 773 additions and 11 deletions
+154
View File
@@ -0,0 +1,154 @@
export interface FamilyProfile {
id: string
name: string
household_size: number
adult_count: number
child_count: number
dietary_notes?: string
budget_per_meal: number
created_at?: string
updated_at?: string
members: FamilyMember[]
}
export interface FamilyMember {
id: string
family_profile_id: string
name: string
email?: string
role: 'adult' | 'child'
likes_mushrooms: boolean
created_at?: string
updated_at?: string
}
export interface Recipe {
id: string
family_profile_id?: string
name: string
description?: string
image_url?: string
image_source?: string
prep_time_minutes?: number
cook_time_minutes?: number
servings: number
servings_scaled?: number
cuisine_tags: string[]
dietary_tags: string[]
protein_type?: string
spice_level?: number
ingredients: RecipeIngredient[]
instructions: string[]
source_url?: string
is_manually_added: boolean
scraped_at?: string
created_at?: string
updated_at?: string
total_time_minutes?: number
}
export interface RecipeIngredient {
ingredient_id?: string
name: string
quantity?: number
unit?: string
is_optional: boolean
}
export interface MealPlan {
id: string
family_profile_id: string
week_start_date: string
status: 'draft' | 'pending_approval' | 'approved' | 'locked'
approval_deadline?: string
total_estimated_cost?: number
notes?: string
created_at?: string
updated_at?: string
items: MealPlanItem[]
}
export interface MealPlanItem {
id: string
meal_plan_id: string
recipe_id: string
day_of_week: number
meal_type: 'breakfast' | 'lunch' | 'dinner'
approval_status: 'pending' | 'approved' | 'denied' | 'swapped'
denial_reason?: string
denial_details?: string
estimated_cost?: number
used_pantry_items: string[]
recipe?: Recipe
created_at?: string
updated_at?: string
}
export interface HomePantryItem {
id: string
family_profile_id: string
ingredient_id: string
quantity?: number
unit?: string
expires_at?: string
added_at?: string
created_at?: string
ingredient?: Ingredient
}
export interface Ingredient {
id: string
name: string
name_lower: string
plural_name?: string
aisle?: string
typical_price?: number
unit?: string
season_months?: number[]
created_at?: string
}
export interface ShoppingListItem {
ingredient_id?: string
name: string
quantity?: number
unit?: string
aisle?: string
estimated_price?: number
is_on_sale: boolean
sale_price?: number
in_season: boolean
in_pantry: boolean
}
export interface ShoppingList {
week_start_date: string
items: ShoppingListItem[]
total_estimated_cost: number
sale_items_count: number
by_aisle: Record<string, ShoppingListItem[]>
}
export interface VoteRequest {
vote: boolean
denial_reason?: string
denial_details?: string
}
export interface ScrapeLog {
id: string
source: string
scrape_type: string
status: string
items_scraped?: number
error_message?: string
started_at?: string
completed_at?: string
duration_seconds?: number
}
export interface SystemStats {
recipes: number
ingredients: number
meal_plans: number
}