Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions project/backend/RecipeSUCUK.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# SUCUK = Search for Uncomplicated Cooking and User-friendly Kitchen recipes
import Database
from Ingredient import Ingredient
from Recipe import Recipe
from Database import getAllRecipes, getAllIngredientsForRecipe
Expand All @@ -8,8 +7,8 @@
def findRecipes(ingredients: list[Ingredient]) -> list[Recipe]:
recipes = __initRecipes()

for Ingredient in ingredients:
recipes = __filterRecipes(recipes, Ingredient)
for ingredient in ingredients:
recipes = __filterRecipes(recipes, ingredient)
Comment on lines 1 to +11

recipes.sort(key=lambda x: x.getRating(), reverse=True)

Expand All @@ -19,10 +18,10 @@ def findRecipes(ingredients: list[Ingredient]) -> list[Recipe]:
return recipes


def __filterRecipes(recipes: list[Recipe], Ingredient: Ingredient) -> list[Recipe]:
def __filterRecipes(recipes: list[Recipe], ingredient: Ingredient) -> list[Recipe]:
for recipe in recipes:
for recipeIngredient in recipe.getIngredients():
if recipeIngredient.getName() == Ingredient.getName():
if recipeIngredient.getName() == ingredient.getName():
recipe.incrementMatching()
recipe.setRating(recipe.getMatching() / len(recipe.getIngredients()))
return recipes
Expand Down
8 changes: 4 additions & 4 deletions project/frontend/app/components/profile_dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,26 @@ export default function ProfileDropdown() {
<div ref={menuRef} className="account-menu">
<button
onClick={() => setOpen(!open)}
className="account-menu__trigger"
className="account-menu-trigger"
aria-label="Account-Menü"
aria-expanded={open}
>
<User size={28} />
</button>

{open && (
<div className="account-menu__dropdown" role="menu">
<div className="account-menu-dropdown" role="menu">
<button
onClick={handleProfil}
className="account-menu__item"
className="account-menu-item"
role="menuitem"
>
<UserCircle size={18} />
<span>Profil ansehen</span>
</button>
<button
onClick={ handleLogout }
className="account-menu__item"
className="account-menu-item"
role="menuitem"
>
<LogOut size={18} />
Expand Down
111 changes: 56 additions & 55 deletions project/frontend/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,86 +1,87 @@
/* stylelint-disable */
@import "tailwindcss";


:root {
--font-size: 16px;
--background: #ffffff;
--foreground: oklch(0.145 0 0);
--card: #ffffff;
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--background: #fff;
--foreground: oklch(14.5% 0 0deg);
--card: #fff;
--card-foreground: oklch(14.5% 0 0deg);
--popover: oklch(100% 0 0deg);
--popover-foreground: oklch(14.5% 0 0deg);
--primary: #030213;
--primary-foreground: oklch(1 0 0);
--secondary: oklch(0.95 0.0058 264.53);
--primary-foreground: oklch(100% 0 0deg);
--secondary: oklch(95% 0.0058 264.53deg);
--secondary-foreground: #030213;
--muted: #ececf0;
--muted-foreground: #717182;
--accent: #e9ebef;
--accent-foreground: #030213;
--destructive: #d4183d;
--destructive-foreground: #ffffff;
--border: rgba(0, 0, 0, 0.1);
--destructive-foreground: #fff;
--border: rgb(0 0 0 / 10%);
--input: transparent;
--input-background: #f3f3f5;
--switch-background: #cbced4;
--font-weight-medium: 500;
--font-weight-normal: 400;
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--ring: oklch(70.8% 0 0deg);
--chart-1: oklch(64.6% 0.222 41.116deg);
--chart-2: oklch(60% 0.118 184.704deg);
--chart-3: oklch(39.8% 0.07 227.392deg);
--chart-4: oklch(82.8% 0.189 84.429deg);
--chart-5: oklch(76.9% 0.188 70.08deg);
--radius: 0.625rem;
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar: oklch(98.5% 0 0deg);
--sidebar-foreground: oklch(14.5% 0 0deg);
--sidebar-primary: #030213;
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
--sidebar-primary-foreground: oklch(98.5% 0 0deg);
--sidebar-accent: oklch(97% 0 0deg);
--sidebar-accent-foreground: oklch(20.5% 0 0deg);
--sidebar-border: oklch(92.2% 0 0deg);
--sidebar-ring: oklch(70.8% 0 0deg);
--text-base: 10px;
--text-2xl: 30px;
--text-lg: 20px;
--text-xl:25px;
}

.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.145 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.145 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.985 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.396 0.141 25.723);
--destructive-foreground: oklch(0.637 0.237 25.331);
--border: oklch(0.269 0 0);
--input: oklch(0.269 0 0);
--ring: oklch(0.439 0 0);
--background: oklch(14.5% 0 0deg);
--foreground: oklch(98.5% 0 0deg);
--card: oklch(14.5% 0 0deg);
--card-foreground: oklch(98.5% 0 0deg);
--popover: oklch(14.5% 0 0deg);
--popover-foreground: oklch(98.5% 0 0deg);
--primary: oklch(98.5% 0 0deg);
--primary-foreground: oklch(20.5% 0 0deg);
--secondary: oklch(26.9% 0 0deg);
--secondary-foreground: oklch(98.5% 0 0deg);
--muted: oklch(26.9% 0 0deg);
--muted-foreground: oklch(70.8% 0 0deg);
--accent: oklch(26.9% 0 0deg);
--accent-foreground: oklch(98.5% 0 0deg);
--destructive: oklch(39.6% 0.141 25.723deg);
--destructive-foreground: oklch(63.7% 0.237 25.331deg);
--border: oklch(26.9% 0 0deg);
--input: oklch(26.9% 0 0deg);
--ring: oklch(43.9% 0 0deg);
--font-weight-medium: 500;
--font-weight-normal: 400;
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(0.269 0 0);
--sidebar-ring: oklch(0.439 0 0);
--chart-1: oklch(48.8% 0.243 264.376deg);
--chart-2: oklch(69.6% 0.17 162.48deg);
--chart-3: oklch(76.9% 0.188 70.08deg);
--chart-4: oklch(62.7% 0.265 303.9deg);
--chart-5: oklch(64.5% 0.246 16.439deg);
--sidebar: oklch(20.5% 0 0deg);
--sidebar-foreground: oklch(98.5% 0 0deg);
--sidebar-primary: oklch(48.8% 0.243 264.376deg);
--sidebar-primary-foreground: oklch(98.5% 0 0deg);
--sidebar-accent: oklch(26.9% 0 0deg);
--sidebar-accent-foreground: oklch(98.5% 0 0deg);
--sidebar-border: oklch(26.9% 0 0deg);
--sidebar-ring: oklch(43.9% 0 0deg);
}

@theme inline {
Expand Down
46 changes: 23 additions & 23 deletions project/frontend/app/recipeFinder/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -219,56 +219,56 @@ export default function RecipeFinder() {
});
}}
onClick={() => setModalOpen(true)}
className="finder-sidebar__add-btn"
className="finder-sidebar-add-btn"
>
Comment on lines 221 to 223
<Plus size={15} />
Zutat hinzufügen
</Button>
<Button onClick={() => setIngredients([])} className="finder-sidebar__clear-btn">
<Button onClick={() => setIngredients([])} className="finder-sidebar-clear-btn">
Alle entfernen
Comment on lines +222 to 228
</Button>
</div>


{ingredients.length > 0 ? (
<div className="finder-sidebar__ingredient-list">
<div className="finder-sidebar-ingredient-list">
{ingredients.map(i => (
<div key={i.name} className="finder-sidebar__ingredient">
<span className="finder-sidebar__ingredient-name">{i.name}</span>
<div key={i.name} className="finder-sidebar-ingredient">
<span className="finder-sidebar-ingredient-name">{i.name}</span>

{editingIngredient === i.name ? (
// Bearbeitungsmodus
<div className="finder-sidebar__ingredient-edit">
<div className="finder-sidebar-ingredient-edit">
<input
type="number"
value={editAmount}
onChange={e => setEditAmount(e.target.value)}
onKeyDown={e => e.key === "Enter" && handleEditSave(i.name)}
min={0}
className="finder-sidebar__edit-input"
className="finder-sidebar-edit-input"
autoFocus
/>
<select
value={editUnit}
onChange={e => setEditUnit(e.target.value)}
className="finder-sidebar__edit-select"
className="finder-sidebar-edit-select"
>
{EINHEITEN.map(e => <option key={e} value={e}>{e}</option>)}
</select>
<button onClick={() => handleEditSave(i.name)} className="finder-sidebar__edit-save">✓</button>
<button onClick={() => setEditingIngredient(null)} className="finder-sidebar__edit-cancel">✕</button>
<button onClick={() => handleEditSave(i.name)} className="finder-sidebar-edit-save">✓</button>
<button onClick={() => setEditingIngredient(null)} className="finder-sidebar-edit-cancel">✕</button>
Comment on lines +258 to +259
</div>
) : (
// Anzeigemodus — klickbar
<div className="finder-sidebar__ingredient-right">
<div className="finder-sidebar-ingredient-right">
<span
onClick={() => handleEditStart(i)}
className="finder-sidebar__ingredient-amount"
className="finder-sidebar-ingredient-amount"
title="Klicken zum Bearbeiten"
>
{i.amount} {i.unit}
Comment on lines 264 to 269
</span>
<button onClick={() => handleRemoveIngredient(i.name)} className="finder-sidebar__ingredient-remove">
<button onClick={() => handleRemoveIngredient(i.name)} className="finder-sidebar-ingredient-remove">
<X size={14} />
</button>
</div>
Expand All @@ -277,27 +277,27 @@ export default function RecipeFinder() {
))}
</div>
) : (
<p className="finder-sidebar__empty">Noch keine Zutaten.</p>
<p className="finder-sidebar-empty">Noch keine Zutaten.</p>
)}
</div>

{/* Personenanzahl */}
<div className="finder-sidebar__section">
<p className="finder-sidebar__title">Personen</p>
<div className="finder-sidebar__persons">
<button onClick={() => setServings(Math.max(1, servings - 1))} className="finder-sidebar__persons-btn">−</button>
<div className="finder-sidebar-section">
<p className="finder-sidebar-title">Personen</p>
<div className="finder-sidebar-persons">
Comment on lines +285 to +287
Comment on lines +285 to +287
<button onClick={() => setServings(Math.max(1, servings - 1))} className="finder-sidebar-persons-btn">−</button>
<div>
<div className="finder-sidebar__persons-count">{servings}</div>
<div className="finder-sidebar__persons-label">Personen</div>
<div className="finder-sidebar-persons-count">{servings}</div>
<div className="finder-sidebar-persons-label">Personen</div>
</div>
<button onClick={() => setServings(servings + 1)} className="finder-sidebar__persons-btn">+</button>
<button onClick={() => setServings(servings + 1)} className="finder-sidebar-persons-btn">+</button>
</div>
</div>

{/* Suche starten */}
<div className="finder-sidebar__section">
<div className="finder-sidebar-section">
{searchError && <p style={{ color: '#b91c1c', fontSize: 13, fontFamily: 'system-ui', marginBottom: 8 }}>{searchError}</p>}
<button onClick={handleSearch} disabled={searching || ingredients.length === 0} className="finder-sidebar__search-btn">
<button onClick={handleSearch} disabled={searching || ingredients.length === 0} className="finder-sidebar-search-btn">
<Search size={15} />
{searching ? "Suche läuft…" : "Rezepte suchen"}
</button>
Expand Down
22 changes: 11 additions & 11 deletions project/frontend/app/recipeFinder/popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,16 @@ export default function AddIngredientsPopup({ ingredients, onAdd, suggestions =

return (
<div className="popup">
<h2 className="popup__title">Zutaten Hinzufügen</h2>
<h2 className="popup-title">Zutaten Hinzufügen</h2>

<div className="popup__fields">
<div className="popup-fields">
<input
type="text"
value={ingredientName}
onChange={e => setIngredientName(e.target.value)}
onKeyDown={e => e.key === "Enter" && handleAddIngredient()}
placeholder="z.B. Tomaten"
className="popup__input"
className="popup-input"
/>
<input
ref={amountInputRef}
Expand All @@ -83,21 +83,21 @@ export default function AddIngredientsPopup({ ingredients, onAdd, suggestions =
onKeyDown={e => e.key === "Enter" && handleAddIngredient()}
placeholder="Menge"
min={0}
className="popup__input popup__input--amount"
className="popup-input popup-input-amount"
/>
<select
value={ingredientUnit}
onChange={e => setIngredientUnit(e.target.value)}
className="popup__select"
className="popup-select"
>
{EINHEITEN.map(e => <option key={e} value={e}>{e}</option>)}
</select>
</div>

{suggestions.length > 0 && (
<div className="popup__suggestions">
<p className="popup__suggestions-label">Häufig verwendet</p>
<div className="popup__suggestions-list">
<div className="popup-suggestions">
<p className="popup-suggestions-label">Häufig verwendet</p>
<div className="popup-suggestions-list">
{suggestions.map(s => {
const added = isAlreadyAdded(s);
return (
Expand All @@ -106,7 +106,7 @@ export default function AddIngredientsPopup({ ingredients, onAdd, suggestions =
type="button"
disabled={added}
onClick={() => !added && handleSuggestionClick(s)}
className={`popup__suggestion-badge${added ? " popup__suggestion-badge--added" : ""}`}
className={`popup-suggestion-badge${added ? " popup-suggestion-badge-added" : ""}`}
title={added ? "Bereits hinzugefügt" : (s.unit ? `${s.name} (${s.unit})` : s.name)}
>
{s.name}
Expand All @@ -117,9 +117,9 @@ export default function AddIngredientsPopup({ ingredients, onAdd, suggestions =
</div>
)}

{inputError && <p className="popup__error">{inputError}</p>}
{inputError && <p className="popup-error">{inputError}</p>}

<button onClick={handleAddIngredient} className="popup__btn">
<button onClick={handleAddIngredient} className="popup-btn">
Hinzufügen
</button>
</div>
Expand Down
Loading
Loading