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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user