Files
mealprep/frontend/src/lib/planner/RecipePickerDrawer.svelte
Marcel Raddatz f97cf49bd0 feat(planner): overhaul desktop layout — flip tiles, no right panel
Replaces 3-panel layout with 2-panel (sidebar + full-width grid):
- Remove persistent right panel and toolbar + Gericht hinzufügen button
- grid-cols-7 tiles use DesktopDayTile (CSS 3D card flip)
- RecipePickerDrawer slides in on tile CTA / Gericht tauschen
- Page-owned activeSlotId + drawerOpen/drawerSlotId state
- Single Escape handler: drawer > flip priority
- Extend server load to forward recipe tags from /v1/recipes API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 11:04:26 +02:00

80 lines
2.3 KiB
Svelte

<script lang="ts">
import type { Recipe, Suggestion } from '$lib/planner/types';
import RecipePicker from './RecipePicker.svelte';
let {
open,
slotDate,
planId,
suggestions,
allRecipes,
isLoading,
onpick,
onclose,
excludeRecipeId,
replacingRecipe
}: {
open: boolean;
slotDate: string;
planId: string;
suggestions: Suggestion[];
allRecipes: Recipe[];
isLoading: boolean;
onpick: (recipeId: string, recipeName: string) => void;
onclose: () => void;
excludeRecipeId?: string;
replacingRecipe?: { name: string; meta?: string };
} = $props();
let drawerTransform = $derived(open ? 'translateX(0)' : 'translateX(100%)');
let backdropVisibility = $derived(open ? 'visible' : 'hidden');
let backdropOpacity = $derived(open ? '1' : '0');
</script>
<!-- Backdrop -->
<div
data-testid="drawer-backdrop"
aria-hidden="true"
onclick={onclose}
style="position: fixed; inset: 0; background: rgba(0,0,0,0.3); z-index: 40; visibility: {backdropVisibility}; opacity: {backdropOpacity}; transition: opacity 0.2s, visibility 0.2s;"
></div>
<!-- Drawer panel -->
<div
data-testid="recipe-picker-drawer"
aria-hidden={!open}
style="position: fixed; right: 0; top: 0; height: 100%; width: min(480px, 90vw); background: var(--color-page); border-left: 1px solid var(--color-border); z-index: 50; transform: {drawerTransform}; transition: transform 0.25s ease; display: flex; flex-direction: column;"
>
<!-- Header -->
<div style="display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--color-border); flex-shrink: 0;">
<p style="margin: 0; font-family: var(--font-display); font-size: 15px; font-weight: 500; color: var(--color-text);">
Rezept wählen
</p>
<button
type="button"
aria-label="Schließen"
onclick={onclose}
style="background: none; border: none; cursor: pointer; font-size: 20px; line-height: 1; color: var(--color-text-muted); padding: 4px 8px;"
>
&times;
</button>
</div>
<!-- RecipePicker content — only mount when open to avoid duplicate text in DOM -->
<div style="overflow-y: auto; flex: 1;">
{#if open}
<RecipePicker
{planId}
date={slotDate}
dateLabel={slotDate}
{suggestions}
{allRecipes}
{isLoading}
{onpick}
{excludeRecipeId}
{replacingRecipe}
/>
{/if}
</div>
</div>