| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  | <template> | 
					
						
							|  |  |  |   <div> | 
					
						
							| 
									
										
										
										
											2022-09-10 20:21:57 +02:00
										 |  |  |     <v-form ref="domUrlForm" @submit.prevent="createByUrl(recipeUrl, importKeywordsAsTags, stayInEditMode)"> | 
					
						
							| 
									
										
										
										
											2022-05-25 19:33:58 -08:00
										 |  |  |       <div> | 
					
						
							| 
									
										
										
										
											2023-01-29 02:39:51 +01:00
										 |  |  |         <v-card-title class="headline"> {{ $t('recipe.scrape-recipe') }} </v-card-title> | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  |         <v-card-text> | 
					
						
							| 
									
										
										
										
											2023-01-29 02:39:51 +01:00
										 |  |  |           {{ $t('recipe.scrape-recipe-description') }} | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  |           <v-text-field | 
					
						
							|  |  |  |             v-model="recipeUrl" | 
					
						
							|  |  |  |             :label="$t('new-recipe.recipe-url')" | 
					
						
							|  |  |  |             :prepend-inner-icon="$globals.icons.link" | 
					
						
							|  |  |  |             validate-on-blur | 
					
						
							|  |  |  |             autofocus | 
					
						
							|  |  |  |             filled | 
					
						
							|  |  |  |             clearable | 
					
						
							|  |  |  |             class="rounded-lg mt-2" | 
					
						
							|  |  |  |             rounded | 
					
						
							|  |  |  |             :rules="[validators.url]" | 
					
						
							|  |  |  |             :hint="$t('new-recipe.url-form-hint')" | 
					
						
							|  |  |  |             persistent-hint | 
					
						
							|  |  |  |           ></v-text-field> | 
					
						
							| 
									
										
										
										
											2023-01-29 02:39:51 +01:00
										 |  |  |           <v-checkbox v-model="importKeywordsAsTags" hide-details :label="$t('recipe.import-original-keywords-as-tags')" /> | 
					
						
							|  |  |  |           <v-checkbox v-model="stayInEditMode" hide-details :label="$t('recipe.stay-in-edit-mode')" /> | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  |         </v-card-text> | 
					
						
							|  |  |  |         <v-card-actions class="justify-center"> | 
					
						
							|  |  |  |           <div style="width: 250px"> | 
					
						
							|  |  |  |             <BaseButton :disabled="recipeUrl === null" rounded block type="submit" :loading="loading" /> | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |         </v-card-actions> | 
					
						
							| 
									
										
										
										
											2022-05-25 19:33:58 -08:00
										 |  |  |       </div> | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  |     </v-form> | 
					
						
							|  |  |  |     <v-expand-transition> | 
					
						
							|  |  |  |       <v-alert v-show="error" color="error" class="mt-6 white--text"> | 
					
						
							|  |  |  |         <v-card-title class="ma-0 pa-0"> | 
					
						
							|  |  |  |           <v-icon left color="white" x-large> {{ $globals.icons.robot }} </v-icon> | 
					
						
							|  |  |  |           {{ $t("new-recipe.error-title") }} | 
					
						
							|  |  |  |         </v-card-title> | 
					
						
							|  |  |  |         <v-divider class="my-3 mx-2"></v-divider> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <p> | 
					
						
							|  |  |  |           {{ $t("new-recipe.error-details") }} | 
					
						
							|  |  |  |         </p> | 
					
						
							|  |  |  |         <div class="d-flex row justify-space-around my-3 force-white"> | 
					
						
							|  |  |  |           <a | 
					
						
							|  |  |  |             class="dark" | 
					
						
							|  |  |  |             href="https://developers.google.com/search/docs/data-types/recipe" | 
					
						
							|  |  |  |             target="_blank" | 
					
						
							|  |  |  |             rel="noreferrer nofollow" | 
					
						
							|  |  |  |           > | 
					
						
							|  |  |  |             {{ $t("new-recipe.google-ld-json-info") }} | 
					
						
							|  |  |  |           </a> | 
					
						
							|  |  |  |           <a href="https://github.com/hay-kot/mealie/issues" target="_blank" rel="noreferrer nofollow"> | 
					
						
							|  |  |  |             {{ $t("new-recipe.github-issues") }} | 
					
						
							|  |  |  |           </a> | 
					
						
							|  |  |  |           <a href="https://schema.org/Recipe" target="_blank" rel="noreferrer nofollow"> | 
					
						
							|  |  |  |             {{ $t("new-recipe.recipe-markup-specification") }} | 
					
						
							|  |  |  |           </a> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       </v-alert> | 
					
						
							|  |  |  |     </v-expand-transition> | 
					
						
							|  |  |  |   </div> | 
					
						
							|  |  |  | </template> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <script lang="ts"> | 
					
						
							| 
									
										
										
										
											2022-10-23 13:02:56 -08:00
										 |  |  | import { | 
					
						
							|  |  |  |   defineComponent, | 
					
						
							|  |  |  |   reactive, | 
					
						
							|  |  |  |   toRefs, | 
					
						
							|  |  |  |   ref, | 
					
						
							|  |  |  |   useRouter, | 
					
						
							|  |  |  |   computed, | 
					
						
							| 
									
										
										
										
											2023-11-05 19:07:02 -06:00
										 |  |  |   useContext, | 
					
						
							| 
									
										
										
										
											2022-10-23 13:02:56 -08:00
										 |  |  |   useRoute, | 
					
						
							|  |  |  |   onMounted, | 
					
						
							|  |  |  | } from "@nuxtjs/composition-api"; | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  | import { AxiosResponse } from "axios"; | 
					
						
							|  |  |  | import { useUserApi } from "~/composables/api"; | 
					
						
							| 
									
										
										
										
											2023-08-21 12:18:55 -05:00
										 |  |  | import { useTagStore } from "~/composables/store/use-tag-store"; | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  | import { validators } from "~/composables/use-validators"; | 
					
						
							|  |  |  | import { VForm } from "~/types/vuetify"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default defineComponent({ | 
					
						
							|  |  |  |   setup() { | 
					
						
							|  |  |  |     const state = reactive({ | 
					
						
							|  |  |  |       error: false, | 
					
						
							|  |  |  |       loading: false, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-05 19:07:02 -06:00
										 |  |  |     const { $auth } = useContext(); | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  |     const api = useUserApi(); | 
					
						
							|  |  |  |     const route = useRoute(); | 
					
						
							| 
									
										
										
										
											2023-11-05 19:07:02 -06:00
										 |  |  |     const groupSlug = computed(() => route.value.params.groupSlug || $auth.user?.groupSlug || ""); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  |     const router = useRouter(); | 
					
						
							| 
									
										
										
										
											2023-08-21 12:18:55 -05:00
										 |  |  |     const tags = useTagStore(); | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-21 12:18:55 -05:00
										 |  |  |     function handleResponse(response: AxiosResponse<string> | null, edit = false, refreshTags = false) { | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  |       if (response?.status !== 201) { | 
					
						
							|  |  |  |         state.error = true; | 
					
						
							|  |  |  |         state.loading = false; | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2023-08-21 12:18:55 -05:00
										 |  |  |       if (refreshTags) { | 
					
						
							|  |  |  |         tags.actions.refresh(); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2023-12-11 03:36:45 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |       // we clear the query params first so if the user hits back, they don't re-import the recipe
 | 
					
						
							|  |  |  |       router.replace({ query: {} }).then( | 
					
						
							|  |  |  |         () => router.push(`/g/${groupSlug.value}/r/${response.data}?edit=${edit.toString()}`) | 
					
						
							|  |  |  |       ); | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const recipeUrl = computed({ | 
					
						
							|  |  |  |       set(recipe_import_url: string | null) { | 
					
						
							|  |  |  |         if (recipe_import_url !== null) { | 
					
						
							|  |  |  |           recipe_import_url = recipe_import_url.trim(); | 
					
						
							|  |  |  |           router.replace({ query: { ...route.value.query, recipe_import_url } }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       get() { | 
					
						
							|  |  |  |         return route.value.query.recipe_import_url as string | null; | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const importKeywordsAsTags = computed({ | 
					
						
							|  |  |  |       get() { | 
					
						
							| 
									
										
										
										
											2022-09-10 20:21:57 +02:00
										 |  |  |         return route.value.query.use_keywords === "1"; | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2022-09-10 20:21:57 +02:00
										 |  |  |       set(v: boolean) { | 
					
						
							|  |  |  |         router.replace({ query: { ...route.value.query, use_keywords: v ? "1" : "0" } }); | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const stayInEditMode = computed({ | 
					
						
							|  |  |  |       get() { | 
					
						
							|  |  |  |         return route.value.query.edit === "1"; | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       set(v: boolean) { | 
					
						
							|  |  |  |         router.replace({ query: { ...route.value.query, edit: v ? "1" : "0" } }); | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  |       }, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     onMounted(() => { | 
					
						
							|  |  |  |       if (!recipeUrl.value) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (recipeUrl.value.includes("https")) { | 
					
						
							| 
									
										
										
										
											2022-09-10 20:21:57 +02:00
										 |  |  |         createByUrl(recipeUrl.value, importKeywordsAsTags.value, stayInEditMode.value); | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const domUrlForm = ref<VForm | null>(null); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-10 20:21:57 +02:00
										 |  |  |     async function createByUrl(url: string | null, importKeywordsAsTags: boolean, stayInEditMode: boolean) { | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  |       if (url === null) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!domUrlForm.value?.validate() || url === "") { | 
					
						
							|  |  |  |         console.log("Invalid URL", url); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       state.loading = true; | 
					
						
							|  |  |  |       const { response } = await api.recipes.createOneByUrl(url, importKeywordsAsTags); | 
					
						
							| 
									
										
										
										
											2023-08-21 12:18:55 -05:00
										 |  |  |       handleResponse(response, stayInEditMode, importKeywordsAsTags); | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       recipeUrl, | 
					
						
							|  |  |  |       importKeywordsAsTags, | 
					
						
							| 
									
										
										
										
											2022-09-10 20:21:57 +02:00
										 |  |  |       stayInEditMode, | 
					
						
							| 
									
										
										
										
											2022-05-25 19:08:32 +02:00
										 |  |  |       domUrlForm, | 
					
						
							|  |  |  |       createByUrl, | 
					
						
							|  |  |  |       ...toRefs(state), | 
					
						
							|  |  |  |       validators, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <style> | 
					
						
							|  |  |  | .force-white > a { | 
					
						
							|  |  |  |   color: white !important; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | </style> |