search bar added
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -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>
|
||||||
Reference in New Issue
Block a user