diff --git a/backend/__pycache__/db_utils.cpython-313.pyc b/backend/__pycache__/db_utils.cpython-313.pyc index 38fbbe1..35a823f 100644 Binary files a/backend/__pycache__/db_utils.cpython-313.pyc and b/backend/__pycache__/db_utils.cpython-313.pyc differ diff --git a/backend/__pycache__/main.cpython-313.pyc b/backend/__pycache__/main.cpython-313.pyc index 54601e3..104f60b 100644 Binary files a/backend/__pycache__/main.cpython-313.pyc and b/backend/__pycache__/main.cpython-313.pyc differ diff --git a/backend/db_utils.py b/backend/db_utils.py index 0998071..03f3c2b 100644 --- a/backend/db_utils.py +++ b/backend/db_utils.py @@ -55,7 +55,7 @@ def list_recipes_db() -> List[Dict[str, Any]]: cur.execute( """ SELECT id, name, meal_type, time_minutes, - tags, ingredients, steps + tags, ingredients, steps, image FROM recipes ORDER BY id """ @@ -68,7 +68,7 @@ def list_recipes_db() -> List[Dict[str, Any]]: def update_recipe_db(recipe_id: int, recipe_data: Dict[str, Any]) -> Optional[Dict[str, Any]]: """ עדכון מתכון קיים לפי id. - recipe_data: name, meal_type, time_minutes, tags, ingredients, steps + recipe_data: name, meal_type, time_minutes, tags, ingredients, steps, image """ conn = get_conn() try: @@ -81,9 +81,10 @@ def update_recipe_db(recipe_id: int, recipe_data: Dict[str, Any]) -> Optional[Di time_minutes = %s, tags = %s, ingredients = %s, - steps = %s + steps = %s, + image = %s WHERE id = %s - RETURNING id, name, meal_type, time_minutes, tags, ingredients, steps + RETURNING id, name, meal_type, time_minutes, tags, ingredients, steps, image """, ( recipe_data["name"], @@ -92,6 +93,7 @@ def update_recipe_db(recipe_id: int, recipe_data: Dict[str, Any]) -> Optional[Di json.dumps(recipe_data.get("tags", [])), json.dumps(recipe_data.get("ingredients", [])), json.dumps(recipe_data.get("steps", [])), + recipe_data.get("image"), recipe_id, ), ) @@ -129,9 +131,9 @@ def create_recipe_db(recipe_data: Dict[str, Any]) -> Dict[str, Any]: with conn.cursor() as cur: cur.execute( """ - INSERT INTO recipes (name, meal_type, time_minutes, tags, ingredients, steps) - VALUES (%s, %s, %s, %s, %s, %s) - RETURNING id, name, meal_type, time_minutes, tags, ingredients, steps + INSERT INTO recipes (name, meal_type, time_minutes, tags, ingredients, steps, image) + VALUES (%s, %s, %s, %s, %s, %s, %s) + RETURNING id, name, meal_type, time_minutes, tags, ingredients, steps, image """, ( recipe_data["name"], @@ -140,6 +142,7 @@ def create_recipe_db(recipe_data: Dict[str, Any]) -> Dict[str, Any]: json.dumps(recipe_data.get("tags", [])), json.dumps(recipe_data.get("ingredients", [])), json.dumps(recipe_data.get("steps", [])), + recipe_data.get("image"), ), ) row = cur.fetchone() diff --git a/backend/main.py b/backend/main.py index edfc28f..6328b3c 100644 --- a/backend/main.py +++ b/backend/main.py @@ -24,6 +24,7 @@ class RecipeBase(BaseModel): tags: List[str] = [] ingredients: List[str] = [] steps: List[str] = [] + image: Optional[str] = None # Base64-encoded image or image URL class RecipeCreate(RecipeBase): @@ -65,6 +66,7 @@ def list_recipes(): tags=r["tags"] or [], ingredients=r["ingredients"] or [], steps=r["steps"] or [], + image=r.get("image"), ) for r in rows ] @@ -86,6 +88,7 @@ def create_recipe(recipe_in: RecipeCreate): tags=row["tags"] or [], ingredients=row["ingredients"] or [], steps=row["steps"] or [], + image=row.get("image"), ) @app.put("/recipes/{recipe_id}", response_model=Recipe) @@ -105,6 +108,7 @@ def update_recipe(recipe_id: int, recipe_in: RecipeUpdate): tags=row["tags"] or [], ingredients=row["ingredients"] or [], steps=row["steps"] or [], + image=row.get("image"), ) @@ -136,6 +140,7 @@ def random_recipe( tags=r["tags"] or [], ingredients=r["ingredients"] or [], steps=r["steps"] or [], + image=r.get("image"), ) for r in rows ] diff --git a/backend/schema.sql b/backend/schema.sql index 2e5c4dc..905d5c4 100644 --- a/backend/schema.sql +++ b/backend/schema.sql @@ -7,7 +7,8 @@ CREATE TABLE IF NOT EXISTS recipes ( tags JSONB NOT NULL DEFAULT '[]', -- ["מהיר", "בריא"] ingredients JSONB NOT NULL DEFAULT '[]', -- ["ביצה", "עגבניה", "מלח"] - steps JSONB NOT NULL DEFAULT '[]' -- ["לחתוך", "לבשל", ...] + steps JSONB NOT NULL DEFAULT '[]', -- ["לחתוך", "לבשל", ...] + image TEXT -- Base64-encoded image or image URL ); -- Optional: index for filters diff --git a/frontend/src/assets/placeholder.svg b/frontend/src/assets/placeholder.svg new file mode 100644 index 0000000..fbb594f --- /dev/null +++ b/frontend/src/assets/placeholder.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + No Image + \ No newline at end of file diff --git a/frontend/src/components/RecipeDetails.jsx b/frontend/src/components/RecipeDetails.jsx index cdfa816..5c0d00e 100644 --- a/frontend/src/components/RecipeDetails.jsx +++ b/frontend/src/components/RecipeDetails.jsx @@ -1,3 +1,5 @@ +import placeholderImage from "../assets/placeholder.svg"; + function RecipeDetails({ recipe, onEditClick, onDeleteClick, onShowDeleteModal }) { if (!recipe) { return ( @@ -14,11 +16,9 @@ function RecipeDetails({ recipe, onEditClick, onDeleteClick, onShowDeleteModal } return (
{/* Recipe Image */} - {recipe.image && ( -
- {recipe.name} -
- )} +
+ {recipe.name} +
diff --git a/frontend/src/components/RecipeSearchList.jsx b/frontend/src/components/RecipeSearchList.jsx index 231d4f8..55ca5f2 100644 --- a/frontend/src/components/RecipeSearchList.jsx +++ b/frontend/src/components/RecipeSearchList.jsx @@ -1,4 +1,5 @@ import { useState } from "react"; +import placeholderImage from "../assets/placeholder.svg"; function RecipeSearchList({ allRecipes, @@ -181,11 +182,9 @@ function RecipeSearchList({ } onClick={() => onSelect(r)} > - {r.image && ( -
- {r.name} -
- )} +
+ {r.name} +
{r.name}