fix: community module integration fixes -- slots payload + ForkResult type

- PublishPayload gains optional slots field; PublishPlanModal maps
  plan.slots into the payload so the backend can compute element
  snapshot scores (seasoning, richness, etc.) from actual recipes
- plan-forked emit type updated to ForkResult across CommunityFeedPanel
  and RecipesView so forked_from is preserved for future navigation
This commit is contained in:
pyr0ball 2026-04-13 14:21:33 -07:00
parent d7bfc083e7
commit 878a9a268c
4 changed files with 9 additions and 3 deletions

View file

@ -118,12 +118,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue' import { ref, onMounted, onUnmounted } from 'vue'
import { useCommunityStore } from '../stores/community' import { useCommunityStore } from '../stores/community'
import type { ForkResult } from '../stores/community'
import CommunityPostCard from './CommunityPostCard.vue' import CommunityPostCard from './CommunityPostCard.vue'
import PublishPlanModal from './PublishPlanModal.vue' import PublishPlanModal from './PublishPlanModal.vue'
import HallOfChaosView from './HallOfChaosView.vue' import HallOfChaosView from './HallOfChaosView.vue'
const emit = defineEmits<{ const emit = defineEmits<{
'plan-forked': [payload: { plan_id: number; week_start: string }] 'plan-forked': [payload: ForkResult]
}>() }>()
const store = useCommunityStore() const store = useCommunityStore()
@ -201,7 +202,7 @@ async function handleFork(slug: string) {
try { try {
const result = await store.forkPost(slug) const result = await store.forkPost(slug)
showToast('Plan added to your week.', 'success') showToast('Plan added to your week.', 'success')
emit('plan-forked', { plan_id: result.plan_id, week_start: result.week_start }) emit('plan-forked', result)
} catch (err: unknown) { } catch (err: unknown) {
showToast(err instanceof Error ? err.message : 'Could not fork this plan.', 'error') showToast(err instanceof Error ? err.message : 'Could not fork this plan.', 'error')
} }

View file

@ -202,6 +202,9 @@ async function onSubmit() {
if (description.value.trim()) payload.description = description.value.trim() if (description.value.trim()) payload.description = description.value.trim()
if (pseudonymName.value.trim()) payload.pseudonym_name = pseudonymName.value.trim() if (pseudonymName.value.trim()) payload.pseudonym_name = pseudonymName.value.trim()
if (props.plan?.id != null) payload.plan_id = props.plan.id if (props.plan?.id != null) payload.plan_id = props.plan.id
if (props.plan?.slots?.length) {
payload.slots = props.plan.slots.map(({ day, meal_type, recipe_id }) => ({ day, meal_type, recipe_id }))
}
submitting.value = true submitting.value = true
try { try {

View file

@ -563,6 +563,7 @@ import RecipeDetailPanel from './RecipeDetailPanel.vue'
import RecipeBrowserPanel from './RecipeBrowserPanel.vue' import RecipeBrowserPanel from './RecipeBrowserPanel.vue'
import SavedRecipesPanel from './SavedRecipesPanel.vue' import SavedRecipesPanel from './SavedRecipesPanel.vue'
import CommunityFeedPanel from './CommunityFeedPanel.vue' import CommunityFeedPanel from './CommunityFeedPanel.vue'
import type { ForkResult } from '../stores/community'
import type { RecipeSuggestion, GroceryLink } from '../services/api' import type { RecipeSuggestion, GroceryLink } from '../services/api'
import { recipesAPI } from '../services/api' import { recipesAPI } from '../services/api'
@ -592,7 +593,7 @@ function onTabKeydown(e: KeyboardEvent) {
} }
// Community tab: navigate to Find tab after a plan fork (full plan view deferred to Task 9) // Community tab: navigate to Find tab after a plan fork (full plan view deferred to Task 9)
function onPlanForked(_payload: { plan_id: number; week_start: string }) { function onPlanForked(_payload: ForkResult) {
activeTab.value = 'find' activeTab.value = 'find'
} }

View file

@ -63,6 +63,7 @@ export interface PublishPayload {
plan_id?: number plan_id?: number
recipe_id?: number recipe_id?: number
outcome_notes?: string outcome_notes?: string
slots?: CommunityPostSlot[]
} }
export interface PublishResult { export interface PublishResult {