| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  | <template> | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  |   <div v-if="model.length > 0 || edit"> | 
					
						
							| 
									
										
										
										
											2023-11-24 10:40:35 +01:00
										 |  |  |     <v-card class="mt-4"> | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |       <v-card-title class="py-2"> | 
					
						
							|  |  |  |         {{ $t("asset.assets") }} | 
					
						
							|  |  |  |       </v-card-title> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       <v-divider class="mx-2" /> | 
					
						
							|  |  |  |       <v-list | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  |         v-if="model.length > 0" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         :flat="!edit" | 
					
						
							|  |  |  |       > | 
					
						
							|  |  |  |         <v-list-item | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  |           v-for="(item, i) in model" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           :key="i" | 
					
						
							|  |  |  |         > | 
					
						
							|  |  |  |           <template #prepend> | 
					
						
							|  |  |  |             <div class="ma-auto"> | 
					
						
							| 
									
										
										
										
											2025-07-29 16:53:33 -05:00
										 |  |  |               <v-tooltip location="bottom"> | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  |                 <template #activator="{ props: tooltipProps }"> | 
					
						
							|  |  |  |                   <v-icon v-bind="tooltipProps"> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |                     {{ getIconDefinition(item.icon).icon }} | 
					
						
							|  |  |  |                   </v-icon> | 
					
						
							|  |  |  |                 </template> | 
					
						
							|  |  |  |                 <span>{{ getIconDefinition(item.icon).title }}</span> | 
					
						
							|  |  |  |               </v-tooltip> | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |           </template> | 
					
						
							|  |  |  |           <v-list-item-title class="pl-2"> | 
					
						
							|  |  |  |             {{ item.name }} | 
					
						
							|  |  |  |           </v-list-item-title> | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |           <v-list-item-action> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |             <v-btn | 
					
						
							|  |  |  |               v-if="!edit" | 
					
						
							|  |  |  |               color="primary" | 
					
						
							|  |  |  |               icon | 
					
						
							|  |  |  |               :href="assetURL(item.fileName ?? '')" | 
					
						
							|  |  |  |               target="_blank" | 
					
						
							|  |  |  |               top | 
					
						
							|  |  |  |             > | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |               <v-icon> {{ $globals.icons.download }} </v-icon> | 
					
						
							|  |  |  |             </v-btn> | 
					
						
							|  |  |  |             <div v-else> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |               <v-btn | 
					
						
							|  |  |  |                 color="error" | 
					
						
							|  |  |  |                 icon | 
					
						
							|  |  |  |                 top | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  |                 @click="model.splice(i, 1)" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |               > | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |                 <v-icon>{{ $globals.icons.delete }}</v-icon> | 
					
						
							|  |  |  |               </v-btn> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |               <AppButtonCopy | 
					
						
							|  |  |  |                 color="" | 
					
						
							|  |  |  |                 :copy-text="assetEmbed(item.fileName ?? '')" | 
					
						
							|  |  |  |               /> | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |             </div> | 
					
						
							|  |  |  |           </v-list-item-action> | 
					
						
							|  |  |  |         </v-list-item> | 
					
						
							|  |  |  |       </v-list> | 
					
						
							|  |  |  |     </v-card> | 
					
						
							|  |  |  |     <div class="d-flex ml-auto mt-2"> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       <v-spacer /> | 
					
						
							| 
									
										
										
										
											2021-11-25 14:17:02 -09:00
										 |  |  |       <BaseDialog | 
					
						
							| 
									
										
										
										
											2022-05-25 11:50:45 -08:00
										 |  |  |         v-model="state.newAssetDialog" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         :title="$t('asset.new-asset')" | 
					
						
							| 
									
										
										
										
											2022-05-25 11:50:45 -08:00
										 |  |  |         :icon="getIconDefinition(state.newAsset.icon).icon" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |         can-submit | 
					
						
							| 
									
										
										
										
											2021-11-25 14:17:02 -09:00
										 |  |  |         @submit="addAsset" | 
					
						
							|  |  |  |       > | 
					
						
							|  |  |  |         <template #activator> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           <BaseButton | 
					
						
							|  |  |  |             v-if="edit" | 
					
						
							|  |  |  |             size="small" | 
					
						
							|  |  |  |             create | 
					
						
							|  |  |  |             @click="state.newAssetDialog = true" | 
					
						
							|  |  |  |           /> | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |         </template> | 
					
						
							| 
									
										
										
										
											2021-11-22 20:10:48 -09:00
										 |  |  |         <v-card-text class="pt-4"> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |           <v-text-field | 
					
						
							|  |  |  |             v-model="state.newAsset.name" | 
					
						
							|  |  |  |             density="compact" | 
					
						
							|  |  |  |             :label="$t('general.name')" | 
					
						
							|  |  |  |           /> | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |           <div class="d-flex justify-space-between"> | 
					
						
							|  |  |  |             <v-select | 
					
						
							| 
									
										
										
										
											2022-05-25 11:50:45 -08:00
										 |  |  |               v-model="state.newAsset.icon" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |               density="compact" | 
					
						
							| 
									
										
										
										
											2022-05-25 11:50:45 -08:00
										 |  |  |               :prepend-icon="getIconDefinition(state.newAsset.icon).icon" | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |               :items="iconOptions" | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |               item-title="title" | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |               item-value="name" | 
					
						
							|  |  |  |               class="mr-2" | 
					
						
							|  |  |  |             > | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |               <template #item="{ item }"> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |                 <v-avatar> | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |                   <v-icon class="mr-auto"> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |                     {{ item.raw.icon }} | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |                   </v-icon> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |                 </v-avatar> | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |                 {{ item.title }} | 
					
						
							|  |  |  |               </template> | 
					
						
							|  |  |  |             </v-select> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |             <AppButtonUpload | 
					
						
							|  |  |  |               :post="false" | 
					
						
							|  |  |  |               file-name="file" | 
					
						
							|  |  |  |               :text-btn="false" | 
					
						
							|  |  |  |               @uploaded="setFileObject" | 
					
						
							|  |  |  |             /> | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |           </div> | 
					
						
							| 
									
										
										
										
											2022-05-25 11:50:45 -08:00
										 |  |  |           {{ state.fileObject.name }} | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |         </v-card-text> | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |       </BaseDialog> | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |     </div> | 
					
						
							|  |  |  |   </div> | 
					
						
							|  |  |  | </template> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  | <script setup lang="ts"> | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  | import { useStaticRoutes, useUserApi } from "~/composables/api"; | 
					
						
							| 
									
										
										
										
											2021-11-22 20:10:48 -09:00
										 |  |  | import { alert } from "~/composables/use-toast"; | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  | import type { RecipeAsset } from "~/lib/api/types/recipe"; | 
					
						
							| 
									
										
										
										
											2021-11-22 20:10:48 -09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  | const props = defineProps({ | 
					
						
							|  |  |  |   slug: { | 
					
						
							|  |  |  |     type: String, | 
					
						
							|  |  |  |     required: true, | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  |   }, | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  |   recipeId: { | 
					
						
							|  |  |  |     type: String, | 
					
						
							|  |  |  |     required: true, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   edit: { | 
					
						
							|  |  |  |     type: Boolean, | 
					
						
							|  |  |  |     default: true, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2021-08-02 22:15:11 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  | const model = defineModel<RecipeAsset[]>({ required: true }); | 
					
						
							| 
									
										
										
										
											2021-11-22 20:10:48 -09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  | const api = useUserApi(); | 
					
						
							| 
									
										
										
										
											2021-11-22 20:10:48 -09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  | const state = reactive({ | 
					
						
							|  |  |  |   newAssetDialog: false, | 
					
						
							|  |  |  |   fileObject: {} as File, | 
					
						
							|  |  |  |   newAsset: { | 
					
						
							|  |  |  |     name: "", | 
					
						
							|  |  |  |     icon: "mdi-file", | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2021-11-22 20:10:48 -09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  | const i18n = useI18n(); | 
					
						
							|  |  |  | const { $globals } = useNuxtApp(); | 
					
						
							| 
									
										
										
										
											2022-08-28 13:54:32 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  | const iconOptions = [ | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     name: "mdi-file", | 
					
						
							|  |  |  |     title: i18n.t("asset.file"), | 
					
						
							|  |  |  |     icon: $globals.icons.file, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     name: "mdi-file-pdf-box", | 
					
						
							|  |  |  |     title: i18n.t("asset.pdf"), | 
					
						
							|  |  |  |     icon: $globals.icons.filePDF, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     name: "mdi-file-image", | 
					
						
							|  |  |  |     title: i18n.t("asset.image"), | 
					
						
							|  |  |  |     icon: $globals.icons.fileImage, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     name: "mdi-code-json", | 
					
						
							|  |  |  |     title: i18n.t("asset.code"), | 
					
						
							|  |  |  |     icon: $globals.icons.codeJson, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     name: "mdi-silverware-fork-knife", | 
					
						
							|  |  |  |     title: i18n.t("asset.recipe"), | 
					
						
							|  |  |  |     icon: $globals.icons.primary, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | ]; | 
					
						
							| 
									
										
										
										
											2021-11-22 20:10:48 -09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  | const serverBase = useRequestURL().origin; | 
					
						
							| 
									
										
										
										
											2021-11-22 20:10:48 -09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  | function getIconDefinition(icon: string) { | 
					
						
							|  |  |  |   return iconOptions.find(item => item.name === icon) || iconOptions[0]; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-11-22 20:10:48 -09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  | const { recipeAssetPath } = useStaticRoutes(); | 
					
						
							|  |  |  | function assetURL(assetName: string) { | 
					
						
							|  |  |  |   return recipeAssetPath(props.recipeId, assetName); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-11-22 20:10:48 -09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  | function assetEmbed(name: string) { | 
					
						
							|  |  |  |   return `<img src="${serverBase}${assetURL(name)}" height="100%" width="100%"> </img>`; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-11-22 20:10:48 -09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  | function setFileObject(fileObject: File) { | 
					
						
							|  |  |  |   state.fileObject = fileObject; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-11-22 20:10:48 -09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  | function validFields() { | 
					
						
							|  |  |  |   return state.newAsset.name.length > 0 && state.fileObject.name.length > 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-11-22 20:10:48 -09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  | async function addAsset() { | 
					
						
							|  |  |  |   if (!validFields()) { | 
					
						
							|  |  |  |     alert.error(i18n.t("asset.error-submitting-form") as string); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-11-22 20:10:48 -09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-05 03:37:42 +02:00
										 |  |  |   const { data } = await api.recipes.createAsset(props.slug, { | 
					
						
							|  |  |  |     name: state.newAsset.name, | 
					
						
							|  |  |  |     icon: state.newAsset.icon, | 
					
						
							|  |  |  |     file: state.fileObject, | 
					
						
							|  |  |  |     extension: state.fileObject.name.split(".").pop() || "", | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   if (data) { | 
					
						
							|  |  |  |     model.value = [...model.value, data]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   state.newAsset = { name: "", icon: "mdi-file" }; | 
					
						
							|  |  |  |   state.fileObject = {} as File; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-07-31 15:07:19 -08:00
										 |  |  | </script> |