search bar added
This commit is contained in:
@@ -190,3 +190,57 @@
|
||||
.cancel-btn:hover {
|
||||
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);
|
||||
}
|
||||
@@ -12,6 +12,27 @@
|
||||
<p class="collection-title">Your Recipe Collection</p>
|
||||
</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-row v-if="loading" justify="center" class="py-16">
|
||||
@@ -223,6 +244,9 @@ const selectedRecipe = ref(null)
|
||||
const isEditing = ref(false)
|
||||
const originalRecipe = ref(null)
|
||||
const config = useRuntimeConfig()
|
||||
const searchQuery = ref('')
|
||||
const isSearching = ref(false)
|
||||
let debounceTimeout = null
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchRecipes()
|
||||
@@ -325,4 +349,31 @@ const sortedRecipes = computed(() => {
|
||||
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>
|
||||
Reference in New Issue
Block a user