| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  | <template> | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |   <div> | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  |     <div> | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |       <BaseDialog | 
					
						
							|  |  |  |         v-model="madeThisDialog" | 
					
						
							|  |  |  |         :icon="$globals.icons.chefHat" | 
					
						
							|  |  |  |         :title="$tc('recipe.made-this')" | 
					
						
							| 
									
										
										
										
											2023-08-21 10:00:37 -05:00
										 |  |  |         :submit-text="$tc('recipe.add-to-timeline')" | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |         @submit="createTimelineEvent" | 
					
						
							|  |  |  |         > | 
					
						
							|  |  |  |         <v-card-text> | 
					
						
							|  |  |  |           <v-form ref="domMadeThisForm"> | 
					
						
							|  |  |  |             <v-textarea | 
					
						
							|  |  |  |               v-model="newTimelineEvent.eventMessage" | 
					
						
							|  |  |  |               autofocus | 
					
						
							|  |  |  |               :label="$tc('recipe.comment')" | 
					
						
							|  |  |  |               :hint="$tc('recipe.how-did-it-turn-out')" | 
					
						
							|  |  |  |               persistent-hint | 
					
						
							|  |  |  |               rows="4" | 
					
						
							|  |  |  |             ></v-textarea> | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |             <v-container> | 
					
						
							|  |  |  |               <v-row> | 
					
						
							|  |  |  |                 <v-col cols="auto"> | 
					
						
							|  |  |  |                   <v-menu | 
					
						
							|  |  |  |                     v-model="datePickerMenu" | 
					
						
							|  |  |  |                     :close-on-content-click="false" | 
					
						
							|  |  |  |                     transition="scale-transition" | 
					
						
							|  |  |  |                     offset-y | 
					
						
							|  |  |  |                     max-width="290px" | 
					
						
							|  |  |  |                     min-width="auto" | 
					
						
							|  |  |  |                   > | 
					
						
							|  |  |  |                     <template #activator="{ on, attrs }"> | 
					
						
							|  |  |  |                       <v-text-field | 
					
						
							|  |  |  |                         v-model="newTimelineEventTimestamp" | 
					
						
							|  |  |  |                         :prepend-icon="$globals.icons.calendar" | 
					
						
							|  |  |  |                         v-bind="attrs" | 
					
						
							|  |  |  |                         readonly | 
					
						
							|  |  |  |                         v-on="on" | 
					
						
							|  |  |  |                       ></v-text-field> | 
					
						
							|  |  |  |                     </template> | 
					
						
							|  |  |  |                     <v-date-picker | 
					
						
							|  |  |  |                       v-model="newTimelineEventTimestamp" | 
					
						
							|  |  |  |                       no-title | 
					
						
							| 
									
										
										
										
											2024-03-12 17:46:34 -05:00
										 |  |  |                       :first-day-of-week="firstDayOfWeek" | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |                       :local="$i18n.locale" | 
					
						
							|  |  |  |                       @input="datePickerMenu = false" | 
					
						
							|  |  |  |                     /> | 
					
						
							|  |  |  |                   </v-menu> | 
					
						
							|  |  |  |                 </v-col> | 
					
						
							|  |  |  |                 <v-spacer /> | 
					
						
							|  |  |  |                 <v-col cols="auto" align-self="center"> | 
					
						
							|  |  |  |                   <AppButtonUpload | 
					
						
							| 
									
										
										
										
											2023-08-21 10:00:37 -05:00
										 |  |  |                     v-if="!newTimelineEventImage" | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |                     class="ml-auto" | 
					
						
							|  |  |  |                     url="none" | 
					
						
							|  |  |  |                     file-name="image" | 
					
						
							|  |  |  |                     accept="image/*" | 
					
						
							|  |  |  |                     :text="$i18n.tc('recipe.upload-image')" | 
					
						
							|  |  |  |                     :text-btn="false" | 
					
						
							|  |  |  |                     :post="false" | 
					
						
							|  |  |  |                     @uploaded="uploadImage" | 
					
						
							|  |  |  |                   /> | 
					
						
							| 
									
										
										
										
											2023-08-21 10:00:37 -05:00
										 |  |  |                   <v-btn | 
					
						
							|  |  |  |                     v-if="!!newTimelineEventImage" | 
					
						
							|  |  |  |                     color="error" | 
					
						
							|  |  |  |                     @click="clearImage" | 
					
						
							|  |  |  |                   > | 
					
						
							|  |  |  |                     <v-icon left>{{ $globals.icons.close }}</v-icon> | 
					
						
							|  |  |  |                     {{ $i18n.tc('recipe.remove-image') }} | 
					
						
							|  |  |  |                   </v-btn> | 
					
						
							|  |  |  |                 </v-col> | 
					
						
							|  |  |  |               </v-row> | 
					
						
							|  |  |  |               <v-row v-if="newTimelineEventImage && newTimelineEventImagePreviewUrl"> | 
					
						
							|  |  |  |                 <v-col cols="12" align-self="center"> | 
					
						
							|  |  |  |                   <ImageCropper | 
					
						
							|  |  |  |                     :img="newTimelineEventImagePreviewUrl" | 
					
						
							|  |  |  |                     cropper-height="20vh" | 
					
						
							|  |  |  |                     cropper-width="100%" | 
					
						
							|  |  |  |                     @save="updateUploadedImage" | 
					
						
							|  |  |  |                   /> | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |                 </v-col> | 
					
						
							|  |  |  |               </v-row> | 
					
						
							|  |  |  |             </v-container> | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |           </v-form> | 
					
						
							|  |  |  |         </v-card-text> | 
					
						
							|  |  |  |       </BaseDialog> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |     <div> | 
					
						
							|  |  |  |       <div class="d-flex justify-center flex-wrap"> | 
					
						
							|  |  |  |         <BaseButton :small="$vuetify.breakpoint.smAndDown" @click="madeThisDialog = true"> | 
					
						
							|  |  |  |           <template #icon> {{ $globals.icons.chefHat }} </template> | 
					
						
							| 
									
										
										
										
											2023-01-29 02:39:51 +01:00
										 |  |  |           {{ $t('recipe.made-this') }} | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |         </BaseButton> | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  |       </div> | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |       <div class="d-flex justify-center flex-wrap"> | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  |         <v-chip | 
					
						
							|  |  |  |           label | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |           :small="$vuetify.breakpoint.smAndDown" | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  |           color="accent custom-transparent" | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |           class="ma-1 pa-3" | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  |         > | 
					
						
							|  |  |  |           <v-icon left> | 
					
						
							|  |  |  |             {{ $globals.icons.calendar }} | 
					
						
							|  |  |  |           </v-icon> | 
					
						
							| 
									
										
										
										
											2023-01-29 02:39:51 +01:00
										 |  |  |             {{ $t('recipe.last-made-date', { date: value ? new Date(value+"Z").toLocaleDateString($i18n.locale) : $t("general.never") } ) }} | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  |         </v-chip> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |   </div> | 
					
						
							|  |  |  | </template> | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  | <script lang="ts"> | 
					
						
							| 
									
										
										
										
											2024-03-12 17:46:34 -05:00
										 |  |  | import { computed, defineComponent, reactive, ref, toRefs, useContext } from "@nuxtjs/composition-api"; | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  | import { whenever } from "@vueuse/core"; | 
					
						
							|  |  |  | import { VForm } from "~/types/vuetify"; | 
					
						
							|  |  |  | import { useUserApi } from "~/composables/api"; | 
					
						
							| 
									
										
										
										
											2024-03-12 17:46:34 -05:00
										 |  |  | import { useGroupSelf } from "~/composables/use-groups"; | 
					
						
							| 
									
										
										
										
											2023-04-25 12:46:00 -05:00
										 |  |  | import { Recipe, RecipeTimelineEventIn } from "~/lib/api/types/recipe"; | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  | export default defineComponent({ | 
					
						
							|  |  |  |   props: { | 
					
						
							|  |  |  |     value: { | 
					
						
							|  |  |  |       type: String, | 
					
						
							|  |  |  |       default: null, | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2023-04-25 12:46:00 -05:00
										 |  |  |     recipe: { | 
					
						
							|  |  |  |       type: Object as () => Recipe, | 
					
						
							|  |  |  |       default: null, | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |     }, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   setup(props, context) { | 
					
						
							|  |  |  |     const madeThisDialog = ref(false); | 
					
						
							|  |  |  |     const userApi = useUserApi(); | 
					
						
							| 
									
										
										
										
											2024-03-12 17:46:34 -05:00
										 |  |  |     const { group } = useGroupSelf(); | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |     const { $auth, i18n } = useContext(); | 
					
						
							|  |  |  |     const domMadeThisForm = ref<VForm>(); | 
					
						
							|  |  |  |     const newTimelineEvent = ref<RecipeTimelineEventIn>({ | 
					
						
							| 
									
										
										
										
											2024-03-03 22:41:25 +00:00
										 |  |  |       subject: "", | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |       eventType: "comment", | 
					
						
							|  |  |  |       eventMessage: "", | 
					
						
							|  |  |  |       timestamp: undefined, | 
					
						
							| 
									
										
										
										
											2023-04-25 12:46:00 -05:00
										 |  |  |       recipeId: props.recipe?.id || "", | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-08-21 10:00:37 -05:00
										 |  |  |     const newTimelineEventImage = ref<Blob | File>(); | 
					
						
							|  |  |  |     const newTimelineEventImageName = ref<string>(""); | 
					
						
							|  |  |  |     const newTimelineEventImagePreviewUrl = ref<string>(); | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |     const newTimelineEventTimestamp = ref<string>(); | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |     whenever( | 
					
						
							|  |  |  |       () => madeThisDialog.value, | 
					
						
							|  |  |  |       () => { | 
					
						
							|  |  |  |         // Set timestamp to now
 | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |         newTimelineEventTimestamp.value = ( | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |           new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000) | 
					
						
							|  |  |  |         ).toISOString().substring(0, 10); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-12 17:46:34 -05:00
										 |  |  |     const firstDayOfWeek = computed(() => { | 
					
						
							|  |  |  |       return group.value?.preferences?.firstDayOfWeek || 0; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-21 10:00:37 -05:00
										 |  |  |     function clearImage() { | 
					
						
							|  |  |  |       newTimelineEventImage.value = undefined; | 
					
						
							|  |  |  |       newTimelineEventImageName.value = ""; | 
					
						
							|  |  |  |       newTimelineEventImagePreviewUrl.value = undefined; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |     function uploadImage(fileObject: File) { | 
					
						
							|  |  |  |       newTimelineEventImage.value = fileObject; | 
					
						
							| 
									
										
										
										
											2023-08-21 10:00:37 -05:00
										 |  |  |       newTimelineEventImageName.value = fileObject.name; | 
					
						
							|  |  |  |       newTimelineEventImagePreviewUrl.value = URL.createObjectURL(fileObject); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function updateUploadedImage(fileObject: Blob) { | 
					
						
							|  |  |  |       newTimelineEventImage.value = fileObject; | 
					
						
							|  |  |  |       newTimelineEventImagePreviewUrl.value = URL.createObjectURL(fileObject); | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |     const state = reactive({datePickerMenu: false}); | 
					
						
							|  |  |  |     async function createTimelineEvent() { | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |       if (!(newTimelineEventTimestamp.value && props.recipe?.id && props.recipe?.slug)) { | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-25 12:46:00 -05:00
										 |  |  |       newTimelineEvent.value.recipeId = props.recipe.id | 
					
						
							| 
									
										
										
										
											2024-03-03 22:41:25 +00:00
										 |  |  |       // @ts-expect-error - TS doesn't like the $auth global user attribute
 | 
					
						
							|  |  |  |       newTimelineEvent.value.subject = i18n.t("recipe.user-made-this", { user: $auth.user.fullName }) | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |       // the user only selects the date, so we set the time to end of day local time
 | 
					
						
							|  |  |  |       // we choose the end of day so it always comes after "new recipe" events
 | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |       newTimelineEvent.value.timestamp = new Date(newTimelineEventTimestamp.value + "T23:59:59").toISOString(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const eventResponse = await userApi.recipes.createTimelineEvent(newTimelineEvent.value); | 
					
						
							|  |  |  |       const newEvent = eventResponse.data; | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |       // we also update the recipe's last made value
 | 
					
						
							|  |  |  |       if (!props.value || newTimelineEvent.value.timestamp > props.value) { | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |         await userApi.recipes.updateLastMade(props.recipe.slug,  newTimelineEvent.value.timestamp); | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |         // update recipe in parent so the user can see it
 | 
					
						
							|  |  |  |         // we remove the trailing "Z" since this is how the API returns it
 | 
					
						
							|  |  |  |         context.emit( | 
					
						
							|  |  |  |           "input", newTimelineEvent.value.timestamp | 
					
						
							|  |  |  |             .substring(0, newTimelineEvent.value.timestamp.length - 1) | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |       // update the image, if provided
 | 
					
						
							|  |  |  |       if (newTimelineEventImage.value && newEvent) { | 
					
						
							| 
									
										
										
										
											2023-08-21 10:00:37 -05:00
										 |  |  |         const imageResponse = await userApi.recipes.updateTimelineEventImage( | 
					
						
							|  |  |  |           newEvent.id, | 
					
						
							|  |  |  |           newTimelineEventImage.value, | 
					
						
							|  |  |  |           newTimelineEventImageName.value, | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |         if (imageResponse.data) { | 
					
						
							|  |  |  |           // @ts-ignore the image response data will always match a value of TimelineEventImage
 | 
					
						
							|  |  |  |           newEvent.image = imageResponse.data.image; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |       // reset form
 | 
					
						
							|  |  |  |       newTimelineEvent.value.eventMessage = ""; | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |       newTimelineEvent.value.timestamp = undefined; | 
					
						
							| 
									
										
										
										
											2023-08-21 10:00:37 -05:00
										 |  |  |       clearImage(); | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |       madeThisDialog.value = false; | 
					
						
							|  |  |  |       domMadeThisForm.value?.reset(); | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |       context.emit("eventCreated", newEvent); | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-13 17:12:53 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |     return { | 
					
						
							|  |  |  |       ...toRefs(state), | 
					
						
							|  |  |  |       domMadeThisForm, | 
					
						
							|  |  |  |       madeThisDialog, | 
					
						
							| 
									
										
										
										
											2024-03-12 17:46:34 -05:00
										 |  |  |       firstDayOfWeek, | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |       newTimelineEvent, | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |       newTimelineEventImage, | 
					
						
							| 
									
										
										
										
											2023-08-21 10:00:37 -05:00
										 |  |  |       newTimelineEventImagePreviewUrl, | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |       newTimelineEventTimestamp, | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |       createTimelineEvent, | 
					
						
							| 
									
										
										
										
											2023-08-21 10:00:37 -05:00
										 |  |  |       clearImage, | 
					
						
							| 
									
										
										
										
											2023-08-06 12:49:30 -05:00
										 |  |  |       uploadImage, | 
					
						
							| 
									
										
										
										
											2023-08-21 10:00:37 -05:00
										 |  |  |       updateUploadedImage, | 
					
						
							| 
									
										
										
										
											2022-12-11 15:16:55 -06:00
										 |  |  |     }; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | </script> |