feat(shopping): add RecipeReferencePanel.svelte component

Desktop right panel showing this week's recipe cards with day
abbreviation, filtered staples count, and link to edit pantry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-04 18:55:31 +02:00
parent 5ac8f1768f
commit 6cc79836d5

View File

@@ -0,0 +1,62 @@
<script lang="ts">
import { formatDayAbbr } from '$lib/planner/week';
interface Slot {
slotDate?: string;
recipe?: {
id?: string;
name?: string;
};
}
interface Props {
slots: Slot[];
filteredStaplesCount: number;
}
let { slots, filteredStaplesCount }: Props = $props();
let filledSlots = $derived(slots.filter((s) => s.recipe));
</script>
<aside class="flex flex-col gap-4">
<div>
<h2 class="font-[var(--font-sans)] text-[12px] font-medium uppercase tracking-wide text-[var(--color-text-muted)]">
Rezepte dieser Woche
</h2>
<div class="mt-2 space-y-1.5">
{#each filledSlots as slot}
<a
href="/recipes/{slot.recipe?.id}"
class="flex items-center gap-2 rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-page)] px-3 py-2 hover:border-[var(--green-light)]"
>
<span class="min-w-[28px] font-[var(--font-sans)] text-[11px] text-[var(--color-text-muted)]">
{slot.slotDate ? formatDayAbbr(slot.slotDate, 'short') : ''}
</span>
<span class="flex-1 truncate font-[var(--font-sans)] text-[13px] font-medium text-[var(--color-text)]">
{slot.recipe?.name}
</span>
</a>
{/each}
{#if filledSlots.length === 0}
<p class="font-[var(--font-sans)] text-[13px] text-[var(--color-text-muted)]">
Keine Gerichte geplant.
</p>
{/if}
</div>
</div>
{#if filteredStaplesCount > 0}
<div class="rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-page)] px-3 py-2">
<p class="font-[var(--font-sans)] text-[13px] text-[var(--color-text-muted)]">
{filteredStaplesCount} Grundzutaten automatisch ausgeblendet
</p>
<a
href="/pantry"
class="font-[var(--font-sans)] text-[12px] font-medium text-[var(--green-dark)] hover:underline"
>
Vorrat bearbeiten
</a>
</div>
{/if}
</aside>