Replace SwapSuggestionList with RecipePicker in both mobile and desktop
swap contexts. RecipePicker now accepts excludeRecipeId, replacingRecipe,
and isDisabled props. Mobile swap sheet also triggers suggestion fetch
via activePickerDate so green/yellow/red score badges appear during swap.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- +server.ts: pass topN=100 so all recipes are scored in one request
- RecipePicker: Empfohlen keeps top 5 with scoreDelta > 0; builds a
scoreMap from all suggestions; shows green/yellow/red delta badge on
every recipe in Alle Rezepte that has a score entry
- Extracted scoreBadge snippet to avoid duplication between sections
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Neutral suggestions (no variety impact) now show "= 0.0 Punkte" in yellow
instead of no badge, making the three states explicit: green (improves),
yellow (neutral), red (worsens).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Avoids floating-point display like 6.199999999999999 by using
score.toFixed(1) in VarietyScoreCard.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shows the actual score delta (e.g. "↓ -1.5 Punkte") in red instead of a
generic ⚠ Variationskonflikt label, letting users compare the cost of each
recipe to make an informed swap decision.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Button only renders when onremove callback is provided, keeping the
component usable in read-only contexts without the destructive action.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes the inline interface from RecipePicker.svelte and replaces
any[] in +page.svelte with Suggestion[] — compile-time safety.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Defensive null-coalescing prevents crash when suggestion data arrives
without scoreDelta (e.g. stale backend or mismatched schema).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Suggestion interface: { recipe, scoreDelta, hasConflict } (no simulatedScore)
- Badge renders from hasConflict directly — no client-side delta computation needed
- New isLoading prop shows skeleton rows while suggestions fetch is in flight
- currentVarietyScore prop removed from component and both call sites follow in next commit
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Unused since the suggestions route was removed (commit 4333dc0).
RecipePicker.test.ts is the active coverage for suggestion rendering.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds excludeRecipeId prop to SwapSuggestionList so the meal being
replaced is not offered as a swap candidate.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix 7px → 11px font-size on section headers in RecipePicker
- Extract shared slotActions.ts with UUID validation for planId/slotId/recipeId
- Load full recipe list in planner page load (was placeholder current-week slots)
- Update planner/+page.svelte to pass data.recipes as allRecipes to RecipePicker
- Update planner and recipes page.server.ts to use shared slot action helpers
- Fix planner page.server tests: add recipes mock for parallel GET load
- Update action tests to use valid UUIDs (were 'plan-1'/'r1' style strings)
- Add validation-path tests for blank/invalid input on all slot actions
- Add tests for recipes/+server.ts GET endpoint (DayPicker week navigation)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shows undo notification after slot add/replace. Rückgängig button
calls onundo, auto-dismisses after 4s via ondismiss callback.
Also patches test-setup for userEvent + fake timers compatibility.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
C4 sheet content: Empfohlen section with variety delta badges,
Alle Rezepte with client-side search filter. GET /planner endpoint
proxies suggestions to backend for lazy client-side loading.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix logic bug `{#if !isPlanner === false}` - view/cook buttons now visible for all roles, swap only for planner
- Convert Tauschen from dead button to link with suggestions href
- Add week.ts unit tests (23 tests covering getWeekStart Sunday edge case, prevWeek/nextWeek, weekDays, isToday, formatWeekRange)
- Fix isToday to use UTC consistently (.toISOString().slice(0,10)) instead of local date
- Add server-side role guard to createPlan action (403 for members)
- Add weekStart format validation in createPlan action
- Add isSelected prop to DayMealCard with green treatment
- Make variety banner sticky on mobile (always visible per spec)
- Add day name abbreviation above date badge in desktop column headers
- Remove placeholder Navigation text from desktop sidebar
- Add aria-label to desktop empty tile buttons
- Add variety score partial failure test, multiple overlaps test, WeekStrip today+selected test
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Three-breakpoint layout (mobile/tablet/desktop) with VarietyScoreCard,
WeekStrip, DayMealCard components. Server loads week plan and variety
score via API; read-only role behavior derived from benutzer.rolle.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>