feat(planner): show variety score in swap menu via RecipePicker

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>
This commit is contained in:
2026-04-09 13:40:17 +02:00
parent f4648cc382
commit f4503b0220
3 changed files with 93 additions and 23 deletions

View File

@@ -66,6 +66,7 @@
const activePickerDate = $derived(
pickerOpen ? selectedDay
: swapSheetOpen ? selectedDay
: panelState.kind === 'recipe-picker' ? panelState.date
: null
);
@@ -357,18 +358,18 @@
selectedSlot.recipe?.cookTimeMin ? `${selectedSlot.recipe.cookTimeMin} Min` : null,
selectedSlot.recipe?.effort ?? null
].filter(Boolean).join(' · ')}
<div style="padding: 16px;">
<SwapSuggestionList
replacingName={selectedSlot.recipe?.name ?? ''}
replacingMeta={replacingMeta || undefined}
recipes={sortedRecipes}
{currentWeekRecipeIds}
excludeRecipeId={selectedSlot.recipe?.id}
isLoading={swapLoading}
onpick={handleSwapPick}
oncancel={() => (swapSheetOpen = false)}
/>
</div>
<RecipePicker
planId={weekPlan?.id ?? ''}
date={selectedDay}
dateLabel={formatDayLabel(selectedDay)}
suggestions={suggestions}
allRecipes={data.recipes}
isLoading={isLoadingSuggestions}
isDisabled={swapLoading}
excludeRecipeId={selectedSlot.recipe?.id}
replacingRecipe={selectedSlot.recipe ? { name: selectedSlot.recipe.name, meta: replacingMeta || undefined } : undefined}
onpick={handleSwapPick}
/>
</BottomSheet>
</div>
@@ -607,13 +608,16 @@
pickerSlot.recipe.cookTimeMin ? `${pickerSlot.recipe.cookTimeMin} Min` : null,
pickerSlot.recipe.effort ?? null
].filter(Boolean).join(' · ')}
<div class="flex-1 overflow-y-auto -mx-4 -mb-4 px-4">
<SwapSuggestionList
replacingName={pickerSlot.recipe.name}
replacingMeta={replacingMeta || undefined}
recipes={sortedRecipes}
{currentWeekRecipeIds}
<div class="flex-1 overflow-y-auto -mx-4 -mb-4">
<RecipePicker
planId={weekPlan?.id ?? ''}
date={pickerDate}
dateLabel={formatDayLabel(pickerDate)}
suggestions={suggestions}
allRecipes={data.recipes}
isLoading={isLoadingSuggestions}
excludeRecipeId={pickerSlot.recipe.id}
replacingRecipe={{ name: pickerSlot.recipe.name, meta: replacingMeta || undefined }}
onpick={handleRecipePick}
/>
</div>