feat(recipes): add image upload, fix save 500, seed HelloFresh data
- Store hero image as base64 data URI in text column (V023 migration) - Add file upload UI to RecipeForm with FileReader preview - Remove isChildFriendly from RecipeCreateRequest (no form field) - Fix 500 on save: effort values now lowercase, serves/cookTimeMin changed from primitive short to nullable Integer to survive omitted fields - Fix empty categories panel: removed stale tagType=category filter - Group category tags by type with German headings in recipe form - Split SuggestionResponse.SuggestionRecipe (no image) from SlotRecipe - Seed 11 HelloFresh recipes with ingredients, steps and tags (V101) - Add frontend e2e scaffold, specs and dev yml Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,22 +1,51 @@
|
||||
<script lang="ts">
|
||||
interface Warning {
|
||||
title: string;
|
||||
explanation: string;
|
||||
interface WarningItem {
|
||||
dayShort: string;
|
||||
recipeName: string;
|
||||
slotId: number;
|
||||
}
|
||||
|
||||
let { warnings }: { warnings: Warning[] } = $props();
|
||||
interface ActionWarning {
|
||||
title: string;
|
||||
items: WarningItem[];
|
||||
}
|
||||
|
||||
let { warnings, weekStart }: { warnings: ActionWarning[]; weekStart: string } = $props();
|
||||
</script>
|
||||
|
||||
{#each warnings as warning}
|
||||
{#each warnings as warning (warning.title)}
|
||||
<div
|
||||
data-testid="warning-card"
|
||||
class="rounded-[var(--radius-lg)] border border-[var(--yellow-light)] bg-[var(--yellow-tint)] px-4 py-3"
|
||||
class="rounded-[var(--radius-lg)] border border-[var(--yellow-light)] bg-[var(--yellow-tint)] overflow-hidden"
|
||||
>
|
||||
<p class="font-[var(--font-sans)] text-[13px] font-medium text-[var(--yellow-text)]">
|
||||
{warning.title}
|
||||
</p>
|
||||
<p class="mt-1 font-[var(--font-sans)] text-[13px] text-[var(--color-text-muted)]">
|
||||
{warning.explanation}
|
||||
</p>
|
||||
<!-- Header row -->
|
||||
<div class="px-4 py-2.5 border-b border-[var(--yellow-light)]">
|
||||
<p class="font-[var(--font-sans)] text-[13px] font-medium text-[var(--yellow-text)]">
|
||||
{warning.title}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Item rows -->
|
||||
{#each warning.items as item (item.slotId)}
|
||||
<div class="flex items-center justify-between gap-3 px-4 py-2.5 border-b border-[var(--yellow-light)] last:border-b-0">
|
||||
<!-- Left: day label + recipe name -->
|
||||
<div class="flex items-center gap-2 min-w-0">
|
||||
<span class="font-[var(--font-sans)] text-[11px] font-medium text-[var(--yellow-text)] w-6 flex-shrink-0">
|
||||
{item.dayShort}
|
||||
</span>
|
||||
<span class="font-[var(--font-sans)] text-[13px] text-[var(--color-text)] truncate">
|
||||
{item.recipeName}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Right: swap link -->
|
||||
<a
|
||||
href="/planner?week={weekStart}&swap={item.slotId}"
|
||||
class="font-[var(--font-sans)] text-[12px] font-medium text-[var(--yellow-text)] flex-shrink-0 hover:underline"
|
||||
>
|
||||
Tauschen →
|
||||
</a>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
Reference in New Issue
Block a user