fix: align frontend API calls with backend routes and types
- Backend: rename routes /mealplan→/mealplans, /shoppinglist→/shopping - Backend: simplify swap/reroll to entry-centric endpoints (by entryId) - Frontend: fix all interfaces to use string GUIDs instead of numbers - Frontend: fix field names (weekStart, date, totalAmount) to match backend JSON - Frontend: shopping toggle by itemName instead of non-existent id - Frontend: handle 204 No Content on DELETE responses - Docker-compose: use env vars for DB credentials Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,15 +3,15 @@ import { ref } from 'vue'
|
||||
import { useApi } from '../composables/useApi'
|
||||
|
||||
export interface Ingredient {
|
||||
id?: number
|
||||
id?: string
|
||||
name: string
|
||||
amount: number
|
||||
unit: string
|
||||
category: string
|
||||
amount: number | null
|
||||
unit: string | null
|
||||
category: string | null
|
||||
}
|
||||
|
||||
export interface Recipe {
|
||||
id: number
|
||||
id: string
|
||||
title: string
|
||||
imageUrl?: string
|
||||
instructions?: string
|
||||
@@ -19,25 +19,23 @@ export interface Recipe {
|
||||
}
|
||||
|
||||
export interface MealPlanEntry {
|
||||
id: number
|
||||
id: string
|
||||
date: string
|
||||
dayOfWeek: number
|
||||
recipeId: number
|
||||
recipeId: string
|
||||
recipe: Recipe
|
||||
}
|
||||
|
||||
export interface MealPlan {
|
||||
id: number
|
||||
weekStartDate: string
|
||||
id: string
|
||||
weekStart: string
|
||||
entries: MealPlanEntry[]
|
||||
}
|
||||
|
||||
export interface ShoppingItem {
|
||||
id: number
|
||||
name: string
|
||||
amount: number
|
||||
unit: string
|
||||
category: string
|
||||
totalAmount: number | null
|
||||
unit: string | null
|
||||
category: string | null
|
||||
isChecked: boolean
|
||||
}
|
||||
|
||||
@@ -77,7 +75,7 @@ export const useMealPlanStore = defineStore('mealPlan', () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function swapMeal(entryId: number, recipeId: number): Promise<void> {
|
||||
async function swapMeal(entryId: string, recipeId: string): Promise<void> {
|
||||
error.value = null
|
||||
try {
|
||||
const updated = await api.put<MealPlanEntry>(`/mealplans/entries/${entryId}/swap`, { recipeId })
|
||||
@@ -92,7 +90,7 @@ export const useMealPlanStore = defineStore('mealPlan', () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function rerollMeal(entryId: number): Promise<void> {
|
||||
async function rerollMeal(entryId: string): Promise<void> {
|
||||
error.value = null
|
||||
try {
|
||||
const updated = await api.post<MealPlanEntry>(`/mealplans/entries/${entryId}/reroll`)
|
||||
@@ -116,13 +114,18 @@ export const useShoppingStore = defineStore('shopping', () => {
|
||||
const items = ref<ShoppingItem[]>([])
|
||||
const loading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
const activeMealPlanId = ref<string | null>(null)
|
||||
|
||||
async function fetchItems(mealPlanId?: number | string): Promise<void> {
|
||||
async function fetchItems(mealPlanId?: string): Promise<void> {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
try {
|
||||
const path = mealPlanId ? `/shopping/${mealPlanId}` : '/shopping/current'
|
||||
items.value = await api.get<ShoppingItem[]>(path)
|
||||
if (mealPlanId) {
|
||||
activeMealPlanId.value = mealPlanId
|
||||
items.value = await api.get<ShoppingItem[]>(`/shopping/${mealPlanId}`)
|
||||
} else {
|
||||
items.value = []
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof Error && e.message === 'HTTP 404') {
|
||||
items.value = []
|
||||
@@ -134,13 +137,13 @@ export const useShoppingStore = defineStore('shopping', () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function toggleItem(id: number): Promise<void> {
|
||||
const item = items.value.find(i => i.id === id)
|
||||
if (!item) return
|
||||
async function toggleItem(itemName: string): Promise<void> {
|
||||
const item = items.value.find(i => i.name === itemName)
|
||||
if (!item || !activeMealPlanId.value) return
|
||||
const prev = item.isChecked
|
||||
item.isChecked = !prev
|
||||
try {
|
||||
await api.put(`/shopping/${id}/toggle`)
|
||||
await api.put(`/shopping/${activeMealPlanId.value}/check/${encodeURIComponent(itemName)}`)
|
||||
} catch {
|
||||
item.isChecked = prev
|
||||
error.value = 'Fehler beim Aktualisieren.'
|
||||
@@ -149,7 +152,7 @@ export const useShoppingStore = defineStore('shopping', () => {
|
||||
|
||||
const uncheckedCount = () => items.value.filter(i => !i.isChecked).length
|
||||
|
||||
return { items, loading, error, fetchItems, toggleItem, uncheckedCount }
|
||||
return { items, loading, error, activeMealPlanId, fetchItems, toggleItem, uncheckedCount }
|
||||
})
|
||||
|
||||
export const useRecipesStore = defineStore('recipes', () => {
|
||||
@@ -177,13 +180,13 @@ export const useRecipesStore = defineStore('recipes', () => {
|
||||
return created
|
||||
}
|
||||
|
||||
async function updateRecipe(id: number, data: Partial<Omit<Recipe, 'id'>>): Promise<void> {
|
||||
async function updateRecipe(id: string, data: Partial<Omit<Recipe, 'id'>>): Promise<void> {
|
||||
const updated = await api.put<Recipe>(`/recipes/${id}`, data)
|
||||
const idx = recipes.value.findIndex(r => r.id === id)
|
||||
if (idx !== -1) recipes.value[idx] = updated
|
||||
}
|
||||
|
||||
async function deleteRecipe(id: number): Promise<void> {
|
||||
async function deleteRecipe(id: string): Promise<void> {
|
||||
await api.del(`/recipes/${id}`)
|
||||
recipes.value = recipes.value.filter(r => r.id !== id)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user