search bar added

This commit is contained in:
2026-03-18 20:44:54 +00:00
parent 8f6e7e2214
commit f1acfcd073
2 changed files with 105 additions and 0 deletions

View File

@@ -189,4 +189,58 @@
.cancel-btn:hover { .cancel-btn:hover {
background-color: rgba(140, 74, 50, 0.05) !important; background-color: rgba(140, 74, 50, 0.05) !important;
}
.search-bar .v-field {
background-color: #FBF6E9 !important;
border: 1px solid #e2d7ba !important;
transition: all 0.3s ease;
}
.search-bar input::placeholder {
color: #86571D !important;
opacity: 0.7 !important;
font-family: 'Libre Baskerville', serif !important;
font-style: italic;
-webkit-text-fill-color: #86571D !important;
}
.search-bar .v-field__input,
.search-bar input {
color: #2e1e0a !important;
font-family: 'Libre Baskerville', serif !important;
font-size: 1.0rem !important;
opacity: 1 !important;
-webkit-text-fill-color: #2e1e0a !important;
}
.search-bar .v-field--focused {
border-color: #556b2f !important;
background-color: #556b2f0d !important;
}
.mdi-auto-fix {
animation: pulse-green 1.5s infinite;
}
@keyframes pulse-green {
0% { opacity: 1; transform: scale(1); }
50% { opacity: 0.5; transform: scale(1.1); }
100% { opacity: 1; transform: scale(1); }
}
.search-bar .v-field__clearable {
margin-right: 4px;
}
.search-bar .v-field__clearable .v-icon {
color: #8c4a32 !important;
opacity: 0.6;
font-size: 1.2rem !important;
transition: all 0.2s ease;
}
.search-bar .v-field__clearable .v-icon:hover {
opacity: 1;
transform: scale(1.1);
} }

View File

@@ -12,6 +12,27 @@
<p class="collection-title">Your Recipe Collection</p> <p class="collection-title">Your Recipe Collection</p>
</header> </header>
<v-row justify="center" class="mb-6">
<v-col cols="12" md="8" lg="6">
<v-text-field
v-model="searchQuery"
placeholder="Search for 'comfort food' or 'smoothie recipe'"
variant="outlined"
class="search-bar"
hide-details
clearable
@click:clear="fetchRecipes"
:loading="isSearching"
>
<template v-slot:prepend-inner>
<v-icon :color="isSearching ? '#556b2f' : '#2e1e0a'">
{{ isSearching ? 'mdi-auto-fix' : 'mdi-magnify' }}
</v-icon>
</template>
</v-text-field>
</v-col>
</v-row>
<v-divider class="mb-10 separator"></v-divider> <v-divider class="mb-10 separator"></v-divider>
<v-row v-if="loading" justify="center" class="py-16"> <v-row v-if="loading" justify="center" class="py-16">
@@ -223,6 +244,9 @@ const selectedRecipe = ref(null)
const isEditing = ref(false) const isEditing = ref(false)
const originalRecipe = ref(null) const originalRecipe = ref(null)
const config = useRuntimeConfig() const config = useRuntimeConfig()
const searchQuery = ref('')
const isSearching = ref(false)
let debounceTimeout = null
onMounted(async () => { onMounted(async () => {
await fetchRecipes() await fetchRecipes()
@@ -325,4 +349,31 @@ const sortedRecipes = computed(() => {
return new Date(b.createdAt) - new Date(a.createdAt) return new Date(b.createdAt) - new Date(a.createdAt)
}) })
}) })
const performSearch = async () => {
if (!searchQuery.value) {
await fetchRecipes()
return
}
try {
isSearching.value = true
const data = await $fetch(`${config.public.apiBase}api/recipe/search`, {
params: { query: searchQuery.value },
credentials: 'include'
})
recipes.value = data
} catch (err) {
console.error("The Chef couldn't find those flavors:", err)
} finally {
isSearching.value = false
}
}
watch(searchQuery, (newVal) => {
clearTimeout(debounceTimeout)
debounceTimeout = setTimeout(() => {
performSearch()
}, 600)
})
</script> </script>