feat(suggestions): C2 — Meal suggestions (variety-aware) (#40)

feat(suggestions): implement C2 meal suggestion screen (Issue #27)

Co-authored-by: Marcel Raddatz <marcel@raddatz.cloud>
Co-committed-by: Marcel Raddatz <marcel@raddatz.cloud>
This commit was merged in pull request #40.
This commit is contained in:
2026-04-03 11:18:45 +02:00
committed by marcel
parent 05e47c3dac
commit 7c07bc443b
7 changed files with 768 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
<script lang="ts">
import { formatDayLabel } from './week';
interface SlotRecipe {
id?: string;
name?: string;
effort?: string;
}
interface Slot {
id?: string;
slotDate?: string;
recipe?: SlotRecipe | null;
}
interface WeekPlan {
id?: string;
weekStart?: string;
slots?: Slot[];
}
let {
selectedDay,
weekPlan
}: {
selectedDay: string;
weekPlan: WeekPlan | null;
} = $props();
let expanded = $state(false);
let slotsWithMeal = $derived(
(weekPlan?.slots ?? []).filter((s) => s.recipe && s.slotDate !== selectedDay)
);
function toggle() {
expanded = !expanded;
}
</script>
<div
data-testid="context-banner"
class="rounded-[var(--radius-md)] border border-[var(--green-light)] bg-[var(--green-tint)] px-4 py-3"
>
<div class="flex items-center justify-between">
<p class="font-[var(--font-sans)] text-[12px] font-medium text-[var(--color-text)]">
Vorschläge für <strong>{formatDayLabel(selectedDay)}</strong>
</p>
<button
type="button"
onclick={toggle}
aria-expanded={expanded}
aria-controls="context-detail"
class="font-[var(--font-sans)] text-[12px] text-[var(--color-text-muted)] hover:text-[var(--color-text)]"
>
{expanded ? 'Filter ausblenden ▲' : 'Filter einblenden ▼'}
</button>
</div>
<div
id="context-detail"
data-testid="context-detail"
aria-hidden={!expanded}
{...expanded ? {} : { hidden: true }}
>
{#if slotsWithMeal.length > 0}
<div class="mt-3">
<p class="mb-1 font-[var(--font-sans)] text-[11px] uppercase tracking-wide text-[var(--color-text-muted)]">
Diese Woche bisher
</p>
<ul class="space-y-1">
{#each slotsWithMeal as slot}
<li class="flex gap-2 font-[var(--font-sans)] text-[12px] text-[var(--color-text)]">
<span class="text-[var(--color-text-muted)]">{formatDayLabel(slot.slotDate!).split(',')[0]}</span>
<span>{slot.recipe?.name}</span>
</li>
{/each}
</ul>
</div>
{:else}
<p class="mt-2 font-[var(--font-sans)] text-[12px] text-[var(--color-text-muted)]">
Noch keine Gerichte diese Woche geplant
</p>
{/if}
</div>
</div>