| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | <template> | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |   <div class="print-container"> | 
					
						
							|  |  |  |     <section> | 
					
						
							|  |  |  |       <v-card-title class="headline pl-0"> | 
					
						
							|  |  |  |         <v-icon left color="primary"> | 
					
						
							|  |  |  |           {{ $globals.icons.primary }} | 
					
						
							|  |  |  |         </v-icon> | 
					
						
							|  |  |  |         {{ recipe.name }} | 
					
						
							|  |  |  |       </v-card-title> | 
					
						
							|  |  |  |       <RecipeTimeCard :prep-time="recipe.prepTime" :total-time="recipe.totalTime" :perform-time="recipe.performTime" /> | 
					
						
							|  |  |  |     </section> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <v-card-text class="px-0"> | 
					
						
							|  |  |  |       <VueMarkdown :source="recipe.description" /> | 
					
						
							|  |  |  |     </v-card-text> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-10 19:48:07 -05:00
										 |  |  |     <!-- Ingredients --> | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |     <section> | 
					
						
							|  |  |  |       <v-card-title class="headline pl-0"> {{ $t("recipe.ingredients") }} </v-card-title> | 
					
						
							| 
									
										
										
										
											2022-06-12 19:43:09 -05:00
										 |  |  |       <div | 
					
						
							|  |  |  |         v-for="(ingredientSection, sectionIndex) in ingredientSections" | 
					
						
							|  |  |  |         :key="`ingredient-section-${sectionIndex}`" | 
					
						
							|  |  |  |         class="print-section" | 
					
						
							|  |  |  |       > | 
					
						
							|  |  |  |         <div class="ingredient-grid"> | 
					
						
							|  |  |  |           <template v-for="(ingredient, ingredientIndex) in ingredientSection.ingredients"> | 
					
						
							|  |  |  |             <h4 v-if="ingredient.title" :key="`ingredient-title-${ingredientIndex}`" class="ingredient-title mt-2"> | 
					
						
							|  |  |  |               {{ ingredient.title }} | 
					
						
							|  |  |  |             </h4> | 
					
						
							|  |  |  |             <p :key="`ingredient-${ingredientIndex}`" class="ingredient-body" v-html="parseText(ingredient)" /> | 
					
						
							|  |  |  |           </template> | 
					
						
							|  |  |  |         </div> | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  |       </div> | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |     </section> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-12 19:43:09 -05:00
										 |  |  |     <!-- Instructions --> | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |     <section> | 
					
						
							|  |  |  |       <v-card-title class="headline pl-0">{{ $t("recipe.instructions") }}</v-card-title> | 
					
						
							| 
									
										
										
										
											2022-06-12 19:43:09 -05:00
										 |  |  |       <div | 
					
						
							|  |  |  |         v-for="(instructionSection, sectionIndex) in instructionSections" | 
					
						
							|  |  |  |         :key="`instruction-section-${sectionIndex}`" | 
					
						
							|  |  |  |         :class="{ 'print-section': instructionSection.sectionName }" | 
					
						
							|  |  |  |       > | 
					
						
							|  |  |  |         <div v-for="(step, stepIndex) in instructionSection.instructions" :key="`instruction-${stepIndex}`"> | 
					
						
							|  |  |  |           <div class="print-section"> | 
					
						
							|  |  |  |             <h4 v-if="step.title" :key="`instruction-title-${stepIndex}`" class="instruction-title mb-2"> | 
					
						
							|  |  |  |               {{ step.title }} | 
					
						
							|  |  |  |             </h4> | 
					
						
							|  |  |  |             <h5>{{ $t("recipe.step-index", { step: stepIndex + instructionSection.stepOffset + 1 }) }}</h5> | 
					
						
							|  |  |  |             <VueMarkdown :source="step.text" class="recipe-step-body" /> | 
					
						
							|  |  |  |           </div> | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  |         </div> | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |       </div> | 
					
						
							|  |  |  |     </section> | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-12 19:43:09 -05:00
										 |  |  |     <!-- Notes --> | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |     <v-divider v-if="hasNotes" class="grey my-4"></v-divider> | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |     <section> | 
					
						
							|  |  |  |       <div v-for="(note, index) in recipe.notes" :key="index + 'note'"> | 
					
						
							| 
									
										
										
										
											2022-06-12 19:43:09 -05:00
										 |  |  |         <div class="print-section"> | 
					
						
							|  |  |  |           <h4>{{ note.title }}</h4> | 
					
						
							|  |  |  |           <VueMarkdown :source="note.text" class="note-body" /> | 
					
						
							|  |  |  |         </div> | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  |       </div> | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |     </section> | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  |   </div> | 
					
						
							|  |  |  | </template> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  | <script lang="ts"> | 
					
						
							| 
									
										
										
										
											2022-05-29 09:09:36 -08:00
										 |  |  | import { defineComponent, computed } from "@nuxtjs/composition-api"; | 
					
						
							| 
									
										
										
										
											2022-01-16 03:38:11 +01:00
										 |  |  | // @ts-ignore vue-markdown has no types
 | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | import VueMarkdown from "@adapttive/vue-markdown"; | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  | import RecipeTimeCard from "~/components/Domain/Recipe/RecipeTimeCard.vue"; | 
					
						
							| 
									
										
										
										
											2022-06-12 19:43:09 -05:00
										 |  |  | import { Recipe, RecipeIngredient, RecipeStep } from "~/types/api-types/recipe"; | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  | import { parseIngredientText } from "~/composables/recipes"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-12 19:43:09 -05:00
										 |  |  | type IngredientSection = { | 
					
						
							|  |  |  |   sectionName: string; | 
					
						
							|  |  |  |   ingredients: RecipeIngredient[]; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type InstructionSection = { | 
					
						
							|  |  |  |   sectionName: string; | 
					
						
							|  |  |  |   stepOffset: number; | 
					
						
							|  |  |  |   instructions: RecipeStep[]; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  | export default defineComponent({ | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  |   components: { | 
					
						
							|  |  |  |     RecipeTimeCard, | 
					
						
							|  |  |  |     VueMarkdown, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   props: { | 
					
						
							| 
									
										
										
										
											2021-08-07 16:49:55 -08:00
										 |  |  |     recipe: { | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  |       type: Object as () => Recipe, | 
					
						
							| 
									
										
										
										
											2021-08-07 16:49:55 -08:00
										 |  |  |       required: true, | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  |   }, | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |   setup(props) { | 
					
						
							| 
									
										
										
										
											2022-06-12 19:43:09 -05:00
										 |  |  |     // Group ingredients by section so we can style them independently
 | 
					
						
							|  |  |  |     const ingredientSections = computed<IngredientSection[]>(() => { | 
					
						
							|  |  |  |       if (!props.recipe.recipeIngredient) { | 
					
						
							|  |  |  |         return []; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return props.recipe.recipeIngredient.reduce((sections, ingredient) => { | 
					
						
							|  |  |  |         // if title append new section to the end of the array
 | 
					
						
							|  |  |  |         if (ingredient.title) { | 
					
						
							|  |  |  |           sections.push({ | 
					
						
							|  |  |  |             sectionName: ingredient.title, | 
					
						
							|  |  |  |             ingredients: [ingredient], | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return sections; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // append new section if first
 | 
					
						
							|  |  |  |         if (sections.length === 0) { | 
					
						
							|  |  |  |           sections.push({ | 
					
						
							|  |  |  |             sectionName: "", | 
					
						
							|  |  |  |             ingredients: [ingredient], | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return sections; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // otherwise add ingredient to last section in the array
 | 
					
						
							|  |  |  |         sections[sections.length - 1].ingredients.push(ingredient); | 
					
						
							|  |  |  |         return sections; | 
					
						
							|  |  |  |       }, [] as IngredientSection[]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Group instructions by section so we can style them independently
 | 
					
						
							|  |  |  |     const instructionSections = computed<InstructionSection[]>(() => { | 
					
						
							|  |  |  |       if (!props.recipe.recipeInstructions) { | 
					
						
							|  |  |  |         return []; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return props.recipe.recipeInstructions.reduce((sections, step) => { | 
					
						
							|  |  |  |         const offset = (() => { | 
					
						
							|  |  |  |           if (sections.length === 0) { | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           const lastOffset = sections[sections.length - 1].stepOffset; | 
					
						
							|  |  |  |           const lastNumSteps = sections[sections.length - 1].instructions.length; | 
					
						
							|  |  |  |           return lastOffset + lastNumSteps; | 
					
						
							|  |  |  |         })(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // if title append new section to the end of the array
 | 
					
						
							|  |  |  |         if (step.title) { | 
					
						
							|  |  |  |           sections.push({ | 
					
						
							|  |  |  |             sectionName: step.title, | 
					
						
							|  |  |  |             stepOffset: offset, | 
					
						
							|  |  |  |             instructions: [step], | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return sections; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // append if first element
 | 
					
						
							|  |  |  |         if (sections.length === 0) { | 
					
						
							|  |  |  |           sections.push({ | 
					
						
							|  |  |  |             sectionName: "", | 
					
						
							|  |  |  |             stepOffset: offset, | 
					
						
							|  |  |  |             instructions: [step], | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return sections; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // otherwise add step to last section in the array
 | 
					
						
							|  |  |  |         sections[sections.length - 1].instructions.push(step); | 
					
						
							|  |  |  |         return sections; | 
					
						
							|  |  |  |       }, [] as InstructionSection[]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |     const hasNotes = computed(() => { | 
					
						
							|  |  |  |       return props.recipe.notes && props.recipe.notes.length > 0; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-10 19:48:07 -05:00
										 |  |  |     function parseText(ingredient: RecipeIngredient) { | 
					
						
							|  |  |  |       return parseIngredientText(ingredient, props.recipe.settings?.disableAmount || false); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |     return { | 
					
						
							|  |  |  |       hasNotes, | 
					
						
							| 
									
										
										
										
											2022-06-10 19:48:07 -05:00
										 |  |  |       parseText, | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |       parseIngredientText, | 
					
						
							| 
									
										
										
										
											2022-06-12 19:43:09 -05:00
										 |  |  |       ingredientSections, | 
					
						
							|  |  |  |       instructionSections, | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |     }; | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2021-11-04 18:15:23 -08:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <style> | 
					
						
							|  |  |  | @media print { | 
					
						
							|  |  |  |   body, | 
					
						
							|  |  |  |   html { | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |     margin-top: 0 !important; | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |   .print-container { | 
					
						
							|  |  |  |     display: block !important; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |   .v-main { | 
					
						
							|  |  |  |     display: block; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |   .v-main__wrap { | 
					
						
							|  |  |  |     position: absolute; | 
					
						
							|  |  |  |     top: 0; | 
					
						
							|  |  |  |     left: 0; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  | </style> | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  | <style scoped> | 
					
						
							| 
									
										
										
										
											2022-06-12 19:43:09 -05:00
										 |  |  | /* Makes all text solid black */ | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  | .print-container { | 
					
						
							|  |  |  |   display: none; | 
					
						
							|  |  |  |   background-color: white; | 
					
						
							| 
									
										
										
										
											2022-06-10 19:48:07 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .print-container, | 
					
						
							|  |  |  | .print-container >>> * { | 
					
						
							|  |  |  |   opacity: 1 !important; | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |   color: black !important; | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-12 19:43:09 -05:00
										 |  |  | /* Prevents sections from being broken up between pages */ | 
					
						
							|  |  |  | .print-section { | 
					
						
							|  |  |  |   page-break-inside: avoid; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | p { | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  |   padding-bottom: 0 !important; | 
					
						
							|  |  |  |   margin-bottom: 0 !important; | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  | .v-card__text { | 
					
						
							|  |  |  |   padding-bottom: 0; | 
					
						
							|  |  |  |   margin-bottom: 0; | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  | .ingredient-grid { | 
					
						
							|  |  |  |   display: grid; | 
					
						
							|  |  |  |   grid-template-columns: 1fr 1fr; | 
					
						
							| 
									
										
										
										
											2022-06-10 19:48:07 -05:00
										 |  |  |   grid-gap: 0.5rem; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-12 19:43:09 -05:00
										 |  |  | .ingredient-title, | 
					
						
							|  |  |  | .instruction-title { | 
					
						
							| 
									
										
										
										
											2022-06-10 19:48:07 -05:00
										 |  |  |   grid-column: 1 / span 2; | 
					
						
							| 
									
										
										
										
											2022-06-12 19:43:09 -05:00
										 |  |  |   text-decoration: underline; | 
					
						
							|  |  |  |   text-underline-offset: 4px; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .ingredient-body, | 
					
						
							|  |  |  | .recipe-step-body, | 
					
						
							|  |  |  | .note-body { | 
					
						
							|  |  |  |   font-size: 14px; | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  | ul { | 
					
						
							|  |  |  |   padding-left: 1rem; | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  | li { | 
					
						
							|  |  |  |   list-style-type: none; | 
					
						
							|  |  |  |   margin-bottom: 0.25rem; | 
					
						
							| 
									
										
										
										
											2021-05-14 21:10:03 -08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-05-28 17:00:37 -08:00
										 |  |  | </style> |