Recipe Search Dialog

This commit is contained in:
Kuchenpirat 2025-07-30 11:03:28 +00:00
commit cae6e18c58

View file

@ -52,10 +52,6 @@
<div class="mr-auto"> <div class="mr-auto">
{{ $t("search.results") }} {{ $t("search.results") }}
</div> </div>
<!-- <router-link
:to="advancedSearchUrl"
class="text-primary"
> {{ $t("search.advanced-search") }} </router-link> -->
</v-card-actions> </v-card-actions>
<RecipeCardMobile <RecipeCardMobile
@ -76,7 +72,7 @@
</div> </div>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import RecipeCardMobile from "./RecipeCardMobile.vue"; import RecipeCardMobile from "./RecipeCardMobile.vue";
import { useLoggedInState } from "~/composables/use-logged-in-state"; import { useLoggedInState } from "~/composables/use-logged-in-state";
import type { RecipeSummary } from "~/lib/api/types/recipe"; import type { RecipeSummary } from "~/lib/api/types/recipe";
@ -85,17 +81,15 @@ import { useRecipeSearch } from "~/composables/recipes/use-recipe-search";
import { usePublicExploreApi } from "~/composables/api/api-client"; import { usePublicExploreApi } from "~/composables/api/api-client";
const SELECTED_EVENT = "selected"; const SELECTED_EVENT = "selected";
export default defineNuxtComponent({
components: {
RecipeCardMobile,
},
setup(_, context) { // Define emits
const emit = defineEmits<{
selected: [recipe: RecipeSummary];
}>();
const $auth = useMealieAuth(); const $auth = useMealieAuth();
const state = reactive({ const loading = ref(false);
loading: false, const selectedIndex = ref(-1);
selectedIndex: -1,
});
// =========================================================================== // ===========================================================================
// Dialog State Management // Dialog State Management
@ -105,7 +99,7 @@ export default defineNuxtComponent({
watch(dialog, (val) => { watch(dialog, (val) => {
if (!val) { if (!val) {
search.query.value = ""; search.query.value = "";
state.selectedIndex = -1; selectedIndex.value = -1;
search.data.value = []; search.data.value = [];
} }
}); });
@ -116,17 +110,17 @@ export default defineNuxtComponent({
function selectRecipe() { function selectRecipe() {
const recipeCards = document.getElementsByClassName("arrow-nav"); const recipeCards = document.getElementsByClassName("arrow-nav");
if (recipeCards) { if (recipeCards) {
if (state.selectedIndex < 0) { if (selectedIndex.value < 0) {
state.selectedIndex = -1; selectedIndex.value = -1;
document.getElementById("arrow-search")?.focus(); document.getElementById("arrow-search")?.focus();
return; return;
} }
if (state.selectedIndex >= recipeCards.length) { if (selectedIndex.value >= recipeCards.length) {
state.selectedIndex = recipeCards.length - 1; selectedIndex.value = recipeCards.length - 1;
} }
(recipeCards[state.selectedIndex] as HTMLElement).focus(); (recipeCards[selectedIndex.value] as HTMLElement).focus();
} }
} }
@ -137,11 +131,11 @@ export default defineNuxtComponent({
} }
else if (e.key === "ArrowUp") { else if (e.key === "ArrowUp") {
e.preventDefault(); e.preventDefault();
state.selectedIndex--; selectedIndex.value--;
} }
else if (e.key === "ArrowDown") { else if (e.key === "ArrowDown") {
e.preventDefault(); e.preventDefault();
state.selectedIndex++; selectedIndex.value++;
} }
else { else {
return; return;
@ -158,9 +152,8 @@ export default defineNuxtComponent({
} }
}); });
const groupSlug = computed(() => route.params.groupSlug as string || $auth.user.value?.groupSlug || "");
const route = useRoute(); const route = useRoute();
const advancedSearchUrl = computed(() => `/g/${groupSlug.value}`); const groupSlug = computed(() => route.params.groupSlug as string || $auth.user.value?.groupSlug || "");
watch(route, close); watch(route, close);
function open() { function open() {
@ -177,22 +170,15 @@ export default defineNuxtComponent({
const search = useRecipeSearch(api); const search = useRecipeSearch(api);
// Select Handler // Select Handler
function handleSelect(recipe: RecipeSummary) { function handleSelect(recipe: RecipeSummary) {
close(); close();
context.emit(SELECTED_EVENT, recipe); emit(SELECTED_EVENT, recipe);
} }
return { // Expose functions to parent components
...toRefs(state), defineExpose({
advancedSearchUrl,
dialog,
open, open,
close, close,
handleSelect,
search,
};
},
}); });
</script> </script>