diff --git a/frontend/src/components/RecipeBrowserPanel.vue b/frontend/src/components/RecipeBrowserPanel.vue index e785d5b..288310f 100644 --- a/frontend/src/components/RecipeBrowserPanel.vue +++ b/frontend/src/components/RecipeBrowserPanel.vue @@ -527,8 +527,10 @@ function onTagSearchInput() { tagSearchDebounce = setTimeout(async () => { tagModal.value.searching = true try { - // Re-use the browser API: browse all recipes filtered by title substring - const res = await browserAPI.browse('_all', '_all', { page: 1, q }) + // Use the first available domain with category=_all to search all recipes by title. + // Domain must be a real domain slug — '_all' is not valid at the browse endpoint. + const searchDomain = domains.value[0]?.id ?? 'cuisine' + const res = await browserAPI.browse(searchDomain, '_all', { page: 1, q }) tagModal.value.results = (res.recipes ?? []).slice(0, 8).map( (r: { id: number; title: string }) => ({ id: r.id, title: r.title }) ) diff --git a/frontend/src/components/RecipeDetailPanel.vue b/frontend/src/components/RecipeDetailPanel.vue index 1de54a9..efb80eb 100644 --- a/frontend/src/components/RecipeDetailPanel.vue +++ b/frontend/src/components/RecipeDetailPanel.vue @@ -225,6 +225,23 @@ + +
+ @@ -354,7 +371,7 @@ import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue' import { useRecipesStore } from '../stores/recipes' import { useSavedRecipesStore } from '../stores/savedRecipes' -import { inventoryAPI, recipesAPI } from '../services/api' +import { inventoryAPI, recipesAPI, browserAPI } from '../services/api' import type { RecipeSuggestion, GroceryLink, StepAnalysis } from '../services/api' import SaveRecipeModal from './SaveRecipeModal.vue' @@ -386,6 +403,12 @@ onMounted(() => { ) ;(focusable ?? dialogRef.value)?.focus() }) + // Load community tags in the background — non-critical, silently skip on error + browserAPI.listRecipeTags(props.recipe.id).then((tags) => { + communityTags.value = tags + }).catch(() => { + // Community tags are supplemental; silently skip on error + }) }) onUnmounted(() => { @@ -411,6 +434,10 @@ const isSaved = computed(() => savedStore.isSaved(props.recipe.id)) const cookDone = ref(false) +// ── Community tags ──────────────────────────────────────── +type CommunityTag = { id: number; domain: string; category: string; subcategory: string | null; pseudonym: string; upvotes: number; accepted: boolean } +const communityTags = ref