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>
80 lines
2.3 KiB
Svelte
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;"
|
|
>
|
|
×
|
|
</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>
|