| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  | <template> | 
					
						
							| 
									
										
										
										
											2021-08-08 20:52:44 -08:00
										 |  |  |   <v-container> | 
					
						
							|  |  |  |     <v-row dense> | 
					
						
							|  |  |  |       <v-col> | 
					
						
							|  |  |  |         <v-text-field | 
					
						
							|  |  |  |           v-model="searchString" | 
					
						
							|  |  |  |           outlined | 
					
						
							|  |  |  |           color="primary accent-3" | 
					
						
							|  |  |  |           :placeholder="$t('search.search-placeholder')" | 
					
						
							|  |  |  |           :append-icon="$globals.icons.search" | 
					
						
							|  |  |  |         > | 
					
						
							|  |  |  |         </v-text-field> | 
					
						
							|  |  |  |       </v-col> | 
					
						
							|  |  |  |       <v-col cols="12" md="2" sm="12"> | 
					
						
							|  |  |  |         <v-text-field v-model="maxResults" class="mt-0 pt-0" :label="$t('search.max-results')" type="number" outlined /> | 
					
						
							|  |  |  |       </v-col> | 
					
						
							|  |  |  |     </v-row> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-04 20:24:32 -08:00
										 |  |  |     <ToggleState> | 
					
						
							|  |  |  |       <template #activator="{ state, toggle }"> | 
					
						
							|  |  |  |         <v-switch :value="state" color="info" class="ma-0 pa-0" label="Advanced" @input="toggle" @click="toggle"> | 
					
						
							|  |  |  |           Advanced | 
					
						
							|  |  |  |         </v-switch> | 
					
						
							|  |  |  |       </template> | 
					
						
							|  |  |  |       <template #default="{ state }"> | 
					
						
							|  |  |  |         <v-expand-transition> | 
					
						
							|  |  |  |           <v-row v-show="state" dense class="my-0 dense flex-row align-center justify-space-around"> | 
					
						
							|  |  |  |             <v-col> | 
					
						
							|  |  |  |               <h3 class="pl-2 text-center headline"> | 
					
						
							|  |  |  |                 {{ $t("category.category-filter") }} | 
					
						
							|  |  |  |               </h3> | 
					
						
							|  |  |  |               <RecipeSearchFilterSelector class="mb-1" @update="updateCatParams" /> | 
					
						
							|  |  |  |               <RecipeCategoryTagSelector | 
					
						
							|  |  |  |                 v-model="includeCategories" | 
					
						
							|  |  |  |                 :solo="true" | 
					
						
							|  |  |  |                 :dense="false" | 
					
						
							|  |  |  |                 :return-object="false" | 
					
						
							|  |  |  |               /> | 
					
						
							|  |  |  |             </v-col> | 
					
						
							|  |  |  |             <v-col> | 
					
						
							|  |  |  |               <h3 class="pl-2 text-center headline"> | 
					
						
							|  |  |  |                 {{ $t("search.tag-filter") }} | 
					
						
							|  |  |  |               </h3> | 
					
						
							|  |  |  |               <RecipeSearchFilterSelector class="mb-1" @update="updateTagParams" /> | 
					
						
							|  |  |  |               <RecipeCategoryTagSelector | 
					
						
							|  |  |  |                 v-model="includeTags" | 
					
						
							|  |  |  |                 :solo="true" | 
					
						
							|  |  |  |                 :dense="false" | 
					
						
							|  |  |  |                 :return-object="false" | 
					
						
							|  |  |  |                 :tag-selector="true" | 
					
						
							|  |  |  |               /> | 
					
						
							|  |  |  |             </v-col> | 
					
						
							|  |  |  |           </v-row> | 
					
						
							|  |  |  |         </v-expand-transition> | 
					
						
							|  |  |  |       </template> | 
					
						
							|  |  |  |     </ToggleState> | 
					
						
							| 
									
										
										
										
											2021-08-08 20:52:44 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     <RecipeCardSection | 
					
						
							| 
									
										
										
										
											2021-09-04 20:24:32 -08:00
										 |  |  |       class="mt-n5" | 
					
						
							| 
									
										
										
										
											2021-08-08 20:52:44 -08:00
										 |  |  |       :title-icon="$globals.icons.magnify" | 
					
						
							|  |  |  |       :recipes="showRecipes" | 
					
						
							|  |  |  |       :hard-limit="maxResults" | 
					
						
							|  |  |  |       @sort="assignFuzzy" | 
					
						
							|  |  |  |     /> | 
					
						
							|  |  |  |   </v-container> | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  | </template> | 
					
						
							| 
									
										
										
										
											2021-08-08 20:52:44 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | <script> | 
					
						
							|  |  |  | import Fuse from "fuse.js"; | 
					
						
							|  |  |  | import { defineComponent } from "vue-demi"; | 
					
						
							|  |  |  | import RecipeSearchFilterSelector from "~/components/Domain/Recipe/RecipeSearchFilterSelector.vue"; | 
					
						
							|  |  |  | import RecipeCategoryTagSelector from "~/components/Domain/Recipe/RecipeCategoryTagSelector.vue"; | 
					
						
							|  |  |  | import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue"; | 
					
						
							|  |  |  | import { useRecipes, allRecipes } from "~/composables/use-recipes"; | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | export default defineComponent({ | 
					
						
							| 
									
										
										
										
											2021-08-08 20:52:44 -08:00
										 |  |  |   components: { | 
					
						
							|  |  |  |     RecipeCategoryTagSelector, | 
					
						
							|  |  |  |     RecipeSearchFilterSelector, | 
					
						
							|  |  |  |     RecipeCardSection, | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |   setup() { | 
					
						
							| 
									
										
										
										
											2021-08-08 20:52:44 -08:00
										 |  |  |     const { assignSorted } = useRecipes(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return { assignSorted, allRecipes }; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   data() { | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       maxResults: 21, | 
					
						
							|  |  |  |       searchResults: [], | 
					
						
							|  |  |  |       catFilter: { | 
					
						
							|  |  |  |         exclude: false, | 
					
						
							|  |  |  |         matchAny: false, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       tagFilter: { | 
					
						
							|  |  |  |         exclude: false, | 
					
						
							|  |  |  |         matchAny: false, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       sortedResults: [], | 
					
						
							|  |  |  |       includeCategories: [], | 
					
						
							|  |  |  |       includeTags: [], | 
					
						
							|  |  |  |       options: { | 
					
						
							|  |  |  |         shouldSort: true, | 
					
						
							|  |  |  |         threshold: 0.6, | 
					
						
							|  |  |  |         location: 0, | 
					
						
							|  |  |  |         distance: 100, | 
					
						
							|  |  |  |         findAllMatches: true, | 
					
						
							|  |  |  |         maxPatternLength: 32, | 
					
						
							|  |  |  |         minMatchCharLength: 2, | 
					
						
							|  |  |  |         keys: ["name", "description"], | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   computed: { | 
					
						
							|  |  |  |     searchString: { | 
					
						
							|  |  |  |       set(q) { | 
					
						
							|  |  |  |         this.$router.replace({ query: { ...this.$route.query, q } }); | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       get() { | 
					
						
							|  |  |  |         return this.$route.query.q || ""; | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     filteredRecipes() { | 
					
						
							|  |  |  |       return this.allRecipes.filter((recipe) => { | 
					
						
							|  |  |  |         const includesTags = this.check(this.includeTags, recipe.tags, this.tagFilter.matchAny, this.tagFilter.exclude); | 
					
						
							|  |  |  |         const includesCats = this.check( | 
					
						
							|  |  |  |           this.includeCategories, | 
					
						
							|  |  |  |           recipe.recipeCategory, | 
					
						
							|  |  |  |           this.catFilter.matchAny, | 
					
						
							|  |  |  |           this.catFilter.exclude | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |         return [includesTags, includesCats].every((x) => x === true); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     fuse() { | 
					
						
							|  |  |  |       return new Fuse(this.filteredRecipes, this.options); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     fuzzyRecipes() { | 
					
						
							|  |  |  |       if (this.searchString.trim() === "") { | 
					
						
							|  |  |  |         return this.filteredRecipes; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       const result = this.fuse.search(this.searchString.trim()); | 
					
						
							|  |  |  |       return result.map((x) => x.item); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     isSearching() { | 
					
						
							|  |  |  |       return this.searchString && this.searchString.length > 0; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     showRecipes() { | 
					
						
							|  |  |  |       if (this.sortedResults.length > 0) { | 
					
						
							|  |  |  |         return this.sortedResults; | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         return this.fuzzyRecipes; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   methods: { | 
					
						
							|  |  |  |     assignFuzzy(val) { | 
					
						
							|  |  |  |       this.sortedResults = val; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     check(filterBy, recipeList, matchAny, exclude) { | 
					
						
							|  |  |  |       let isMatch = true; | 
					
						
							|  |  |  |       if (filterBy.length === 0) return isMatch; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (recipeList) { | 
					
						
							|  |  |  |         if (matchAny) { | 
					
						
							|  |  |  |           isMatch = filterBy.some((t) => recipeList.includes(t)); // Checks if some items are a match
 | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           isMatch = filterBy.every((t) => recipeList.includes(t)); // Checks if every items is a match
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return exclude ? !isMatch : isMatch; | 
					
						
							|  |  |  |       } else; | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     updateTagParams(params) { | 
					
						
							|  |  |  |       this.tagFilter = params; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     updateCatParams(params) { | 
					
						
							|  |  |  |       this.catFilter = params; | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |   }, | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | </script> | 
					
						
							| 
									
										
										
										
											2021-08-08 20:52:44 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | <style></style> |