feat(recipes): implement recipe library page with search and effort filtering

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-03 09:49:39 +02:00
parent a25286e385
commit 47c748145d
2 changed files with 128 additions and 1 deletions

View File

@@ -1 +1,54 @@
<h1 class="text-2xl font-medium p-6">Rezepte</h1>
<script lang="ts">
import FilterChipRow from '$lib/recipes/FilterChipRow.svelte';
import RecipeGrid from '$lib/recipes/RecipeGrid.svelte';
type RecipeSummary = {
id: string;
name: string;
cookTimeMin?: number;
effort?: string;
heroImageUrl?: string;
};
let { data }: { data: { recipes: RecipeSummary[] } } = $props();
let searchQuery = $state('');
let activeFilter = $state('Alle');
const effortMap: Record<string, string> = {
Leicht: 'Easy',
Mittel: 'Medium',
Schwer: 'Hard'
};
let filteredRecipes = $derived(
data.recipes
.filter((r) => {
if (activeFilter === 'Alle') return true;
return r.effort === effortMap[activeFilter];
})
.filter((r) => r.name.toLowerCase().includes(searchQuery.toLowerCase()))
);
</script>
<svelte:head>
<title>Rezepte — Mealplan</title>
</svelte:head>
<div class="p-6 space-y-4">
<div class="flex items-center justify-between">
<h1 class="text-2xl font-medium">Rezepte</h1>
<a href="/recipes/new" class="btn variant-filled-primary">Rezept hinzufügen</a>
</div>
<input
type="search"
placeholder="Suchen…"
class="input"
bind:value={searchQuery}
/>
<FilterChipRow {activeFilter} onFilter={(f) => (activeFilter = f)} />
<RecipeGrid recipes={filteredRecipes} />
</div>