| 
									
										
										
										
											2021-07-31 14:45:28 -08:00
										 |  |  | <template> | 
					
						
							| 
									
										
										
										
											2025-09-03 11:11:36 +02:00
										 |  |  |   <v-navigation-drawer v-model="showDrawer" class="d-flex flex-column d-print-none position-fixed" touchless> | 
					
						
							| 
									
										
										
										
											2025-09-03 17:07:06 +02:00
										 |  |  |     <LanguageDialog v-model="languageDialog" /> | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |     <!-- User Profile --> | 
					
						
							| 
									
										
										
										
											2023-11-05 19:07:02 -06:00
										 |  |  |     <template v-if="loggedIn"> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       <v-list-item lines="two" :to="userProfileLink" exact> | 
					
						
							|  |  |  |         <div class="d-flex align-center ga-2"> | 
					
						
							|  |  |  |           <UserAvatar list :user-id="sessionUser.id" :tooltip="false" /> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           <div class="d-flex flex-column justify-start"> | 
					
						
							|  |  |  |             <v-list-item-title class="pr-2 pl-1"> | 
					
						
							|  |  |  |               {{ sessionUser.fullName }} | 
					
						
							|  |  |  |             </v-list-item-title> | 
					
						
							|  |  |  |             <v-list-item-subtitle class="opacity-100"> | 
					
						
							|  |  |  |               <v-btn v-if="isOwnGroup" class="px-2 pa-0" variant="text" :to="userFavoritesLink" size="small"> | 
					
						
							|  |  |  |                 <v-icon start size="small"> | 
					
						
							|  |  |  |                   {{ $globals.icons.heart }} | 
					
						
							|  |  |  |                 </v-icon> | 
					
						
							|  |  |  |                 {{ $t("user.favorite-recipes") }} | 
					
						
							|  |  |  |               </v-btn> | 
					
						
							|  |  |  |             </v-list-item-subtitle> | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |         </div> | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |       </v-list-item> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       <v-divider /> | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |     </template> | 
					
						
							| 
									
										
										
										
											2021-08-06 16:28:12 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     <slot /> | 
					
						
							| 
									
										
										
										
											2021-10-02 11:37:04 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |     <!-- Primary Links --> | 
					
						
							| 
									
										
										
										
											2021-08-23 12:24:38 -08:00
										 |  |  |     <template v-if="topLink"> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       <v-list v-model:selected="secondarySelected" nav density="comfortable" color="primary"> | 
					
						
							| 
									
										
										
										
											2021-08-23 12:24:38 -08:00
										 |  |  |         <template v-for="nav in topLink"> | 
					
						
							| 
									
										
										
										
											2024-09-15 06:42:58 -05:00
										 |  |  |           <div v-if="!nav.restricted || isOwnGroup" :key="nav.key || nav.title"> | 
					
						
							| 
									
										
										
										
											2023-09-14 09:01:24 -05:00
										 |  |  |             <!-- Multi Items --> | 
					
						
							| 
									
										
										
										
											2025-09-27 13:57:53 -05:00
										 |  |  |             <v-list-group | 
					
						
							|  |  |  |               v-if="nav.children" | 
					
						
							|  |  |  |               :key="(nav.key || nav.title) + 'multi-item'" | 
					
						
							|  |  |  |               v-model="dropDowns[nav.title]" | 
					
						
							|  |  |  |               color="primary" | 
					
						
							|  |  |  |               :prepend-icon="nav.icon" | 
					
						
							|  |  |  |               :fluid="true" | 
					
						
							|  |  |  |             > | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |               <template #activator="{ props }"> | 
					
						
							|  |  |  |                 <v-list-item v-bind="props" :prepend-icon="nav.icon" :title="nav.title" /> | 
					
						
							| 
									
										
										
										
											2023-09-14 09:01:24 -05:00
										 |  |  |               </template> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-27 13:57:53 -05:00
										 |  |  |               <v-list-item | 
					
						
							|  |  |  |                 v-for="child in nav.children" | 
					
						
							|  |  |  |                 :key="child.key || child.title" | 
					
						
							|  |  |  |                 exact | 
					
						
							|  |  |  |                 :to="child.to" | 
					
						
							|  |  |  |                 :prepend-icon="child.icon" | 
					
						
							|  |  |  |                 :title="child.title" | 
					
						
							|  |  |  |                 class="ml-4" | 
					
						
							|  |  |  |               /> | 
					
						
							| 
									
										
										
										
											2023-09-14 09:01:24 -05:00
										 |  |  |             </v-list-group> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             <!-- Single Item --> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |             <template v-else> | 
					
						
							| 
									
										
										
										
											2025-09-27 13:57:53 -05:00
										 |  |  |               <v-list-item | 
					
						
							|  |  |  |                 :key="(nav.key || nav.title) + 'single-item'" | 
					
						
							|  |  |  |                 exact | 
					
						
							|  |  |  |                 link | 
					
						
							|  |  |  |                 :to="nav.to" | 
					
						
							|  |  |  |                 :prepend-icon="nav.icon" | 
					
						
							|  |  |  |                 :title="nav.title" | 
					
						
							|  |  |  |               /> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |             </template> | 
					
						
							| 
									
										
										
										
											2023-09-14 09:01:24 -05:00
										 |  |  |           </div> | 
					
						
							| 
									
										
										
										
											2021-08-23 12:24:38 -08:00
										 |  |  |         </template> | 
					
						
							|  |  |  |       </v-list> | 
					
						
							|  |  |  |     </template> | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     <!-- Secondary Links --> | 
					
						
							| 
									
										
										
										
											2024-04-01 10:16:52 +02:00
										 |  |  |     <template v-if="secondaryLinks.length > 0"> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       <v-divider class="mt-2" /> | 
					
						
							|  |  |  |       <v-list v-model:selected="secondarySelected" nav density="compact" exact> | 
					
						
							| 
									
										
										
										
											2021-08-06 16:28:12 -08:00
										 |  |  |         <template v-for="nav in secondaryLinks"> | 
					
						
							| 
									
										
										
										
											2024-09-15 06:42:58 -05:00
										 |  |  |           <div v-if="!nav.restricted || isOwnGroup" :key="nav.key || nav.title"> | 
					
						
							| 
									
										
										
										
											2023-09-14 09:01:24 -05:00
										 |  |  |             <!-- Multi Items --> | 
					
						
							| 
									
										
										
										
											2025-09-27 13:57:53 -05:00
										 |  |  |             <v-list-group | 
					
						
							|  |  |  |               v-if="nav.children" | 
					
						
							|  |  |  |               :key="(nav.key || nav.title) + 'multi-item'" | 
					
						
							|  |  |  |               v-model="dropDowns[nav.title]" | 
					
						
							|  |  |  |               color="primary" | 
					
						
							|  |  |  |               :prepend-icon="nav.icon" | 
					
						
							|  |  |  |               fluid | 
					
						
							|  |  |  |             > | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |               <template #activator="{ props }"> | 
					
						
							|  |  |  |                 <v-list-item v-bind="props" :prepend-icon="nav.icon" :title="nav.title" /> | 
					
						
							| 
									
										
										
										
											2023-09-14 09:01:24 -05:00
										 |  |  |               </template> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-27 13:57:53 -05:00
										 |  |  |               <v-list-item | 
					
						
							|  |  |  |                 v-for="child in nav.children" | 
					
						
							|  |  |  |                 :key="child.key || child.title" | 
					
						
							|  |  |  |                 exact | 
					
						
							|  |  |  |                 :to="child.to" | 
					
						
							|  |  |  |                 class="ml-2" | 
					
						
							|  |  |  |                 :prepend-icon="child.icon" | 
					
						
							|  |  |  |                 :title="child.title" | 
					
						
							|  |  |  |               /> | 
					
						
							| 
									
										
										
										
											2023-09-14 09:01:24 -05:00
										 |  |  |             </v-list-group> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             <!-- Single Item --> | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |             <v-list-item v-else :key="(nav.key || nav.title) + 'single-item'" exact link :to="nav.to"> | 
					
						
							|  |  |  |               <template #prepend> | 
					
						
							|  |  |  |                 <v-icon>{{ nav.icon }}</v-icon> | 
					
						
							|  |  |  |               </template> | 
					
						
							|  |  |  |               <v-list-item-title>{{ nav.title }}</v-list-item-title> | 
					
						
							|  |  |  |             </v-list-item> | 
					
						
							| 
									
										
										
										
											2023-09-14 09:01:24 -05:00
										 |  |  |           </div> | 
					
						
							| 
									
										
										
										
											2021-08-06 16:28:12 -08:00
										 |  |  |         </template> | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |       </v-list> | 
					
						
							|  |  |  |     </template> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <!-- Bottom Navigation Links --> | 
					
						
							| 
									
										
										
										
											2025-09-03 17:07:06 +02:00
										 |  |  |     <template #append> | 
					
						
							|  |  |  |       <v-list v-model:selected="bottomSelected" nav density="comfortable"> | 
					
						
							|  |  |  |         <v-menu location="end bottom" :offset="15"> | 
					
						
							|  |  |  |           <template #activator="{ props }"> | 
					
						
							|  |  |  |             <v-list-item v-bind="props" :prepend-icon="$globals.icons.cog" :title="$t('general.settings')" /> | 
					
						
							|  |  |  |           </template> | 
					
						
							|  |  |  |           <v-list density="comfortable" color="primary"> | 
					
						
							|  |  |  |             <v-list-item :prepend-icon="$globals.icons.translate" :title="$t('sidebar.language')" @click="languageDialog=true" /> | 
					
						
							|  |  |  |             <v-list-item :prepend-icon="$vuetify.theme.current.dark ? $globals.icons.weatherSunny : $globals.icons.weatherNight" :title="$vuetify.theme.current.dark ? $t('settings.theme.light-mode') : $t('settings.theme.dark-mode')" @click="toggleDark" /> | 
					
						
							|  |  |  |             <v-divider v-if="loggedIn" class="my-2" /> | 
					
						
							|  |  |  |             <v-list-item v-if="loggedIn" :prepend-icon="$globals.icons.cog" :title="$t('profile.user-settings')" to="/user/profile" /> | 
					
						
							|  |  |  |             <v-list-item v-if="canManage" :prepend-icon="$globals.icons.manageData" :title="$t('data-pages.data-management')" to="/group/data" /> | 
					
						
							|  |  |  |             <v-divider v-if="isAdmin" class="my-2" /> | 
					
						
							|  |  |  |             <v-list-item v-if="isAdmin" :prepend-icon="$globals.icons.wrench" :title="$t('settings.admin-settings')" to="/admin/site-settings" /> | 
					
						
							|  |  |  |           </v-list> | 
					
						
							|  |  |  |         </v-menu> | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |       </v-list> | 
					
						
							|  |  |  |     </template> | 
					
						
							|  |  |  |   </v-navigation-drawer> | 
					
						
							| 
									
										
										
										
											2021-07-31 14:45:28 -08:00
										 |  |  | </template> | 
					
						
							| 
									
										
										
										
											2022-01-07 22:09:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-31 14:45:28 -08:00
										 |  |  | <script lang="ts"> | 
					
						
							| 
									
										
										
										
											2023-11-05 19:07:02 -06:00
										 |  |  | import { useLoggedInState } from "~/composables/use-logged-in-state"; | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  | import type { SidebarLinks } from "~/types/application-types"; | 
					
						
							| 
									
										
										
										
											2021-12-18 19:04:36 -09:00
										 |  |  | import UserAvatar from "~/components/Domain/User/UserAvatar.vue"; | 
					
						
							| 
									
										
										
										
											2025-09-03 17:07:06 +02:00
										 |  |  | import { useToggleDarkMode } from "~/composables/use-utils"; | 
					
						
							| 
									
										
										
										
											2021-07-31 14:45:28 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  | export default defineNuxtComponent({ | 
					
						
							| 
									
										
										
										
											2021-12-18 19:04:36 -09:00
										 |  |  |   components: { | 
					
						
							|  |  |  |     UserAvatar, | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |   props: { | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     modelValue: { | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |       type: Boolean, | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       required: false, | 
					
						
							|  |  |  |       default: false, | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |     }, | 
					
						
							|  |  |  |     user: { | 
					
						
							|  |  |  |       type: Object, | 
					
						
							|  |  |  |       default: null, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     topLink: { | 
					
						
							|  |  |  |       type: Array as () => SidebarLinks, | 
					
						
							|  |  |  |       required: true, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     secondaryLinks: { | 
					
						
							|  |  |  |       type: Array as () => SidebarLinks, | 
					
						
							|  |  |  |       required: false, | 
					
						
							|  |  |  |       default: null, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |   emits: ["update:modelValue"], | 
					
						
							| 
									
										
										
										
											2022-01-07 22:09:34 +01:00
										 |  |  |   setup(props, context) { | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     const $auth = useMealieAuth(); | 
					
						
							| 
									
										
										
										
											2023-11-05 19:07:02 -06:00
										 |  |  |     const { loggedIn, isOwnGroup } = useLoggedInState(); | 
					
						
							| 
									
										
										
										
											2025-09-03 17:07:06 +02:00
										 |  |  |     const isAdmin = computed(() => $auth.user.value?.admin); | 
					
						
							|  |  |  |     const canManage = computed(() => $auth.user.value?.canManage); | 
					
						
							| 
									
										
										
										
											2023-11-05 19:07:02 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     const userFavoritesLink = computed(() => $auth.user.value ? `/user/${$auth.user.value.id}/favorites` : undefined); | 
					
						
							|  |  |  |     const userProfileLink = computed(() => $auth.user.value ? "/user/profile" : undefined); | 
					
						
							| 
									
										
										
										
											2023-09-14 09:01:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-03 17:07:06 +02:00
										 |  |  |     const toggleDark = useToggleDarkMode(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-07 22:09:34 +01:00
										 |  |  |     const state = reactive({ | 
					
						
							| 
									
										
										
										
											2024-11-05 13:57:30 -06:00
										 |  |  |       dropDowns: {} as Record<string, boolean>, | 
					
						
							| 
									
										
										
										
											2022-01-07 22:09:34 +01:00
										 |  |  |       topSelected: null as string[] | null, | 
					
						
							|  |  |  |       secondarySelected: null as string[] | null, | 
					
						
							|  |  |  |       bottomSelected: null as string[] | null, | 
					
						
							| 
									
										
										
										
											2022-11-11 01:41:16 +01:00
										 |  |  |       hasOpenedBefore: false as boolean, | 
					
						
							| 
									
										
										
										
											2025-09-03 17:07:06 +02:00
										 |  |  |       languageDialog: false as boolean, | 
					
						
							| 
									
										
										
										
											2022-01-07 22:09:34 +01:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |     // model to control the drawer
 | 
					
						
							|  |  |  |     const showDrawer = computed({ | 
					
						
							|  |  |  |       get: () => props.modelValue, | 
					
						
							|  |  |  |       set: value => context.emit("update:modelValue", value), | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-01-07 22:09:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-03 17:07:06 +02:00
										 |  |  |     const allLinks = computed(() => [...props.topLink, ...(props.secondaryLinks || [])]); | 
					
						
							| 
									
										
										
										
											2024-11-05 13:57:30 -06:00
										 |  |  |     function initDropdowns() { | 
					
						
							|  |  |  |       allLinks.value.forEach((link) => { | 
					
						
							|  |  |  |         state.dropDowns[link.title] = link.childrenStartExpanded || false; | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       }); | 
					
						
							| 
									
										
										
										
											2024-11-05 13:57:30 -06:00
										 |  |  |     } | 
					
						
							|  |  |  |     watch( | 
					
						
							|  |  |  |       () => allLinks, | 
					
						
							|  |  |  |       () => { | 
					
						
							|  |  |  |         initDropdowns(); | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         deep: true, | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2024-11-05 13:57:30 -06:00
										 |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-07 22:09:34 +01:00
										 |  |  |     return { | 
					
						
							|  |  |  |       ...toRefs(state), | 
					
						
							| 
									
										
										
										
											2023-11-05 19:07:02 -06:00
										 |  |  |       userFavoritesLink, | 
					
						
							|  |  |  |       userProfileLink, | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       showDrawer, | 
					
						
							| 
									
										
										
										
											2023-09-14 09:01:24 -05:00
										 |  |  |       loggedIn, | 
					
						
							| 
									
										
										
										
											2025-09-03 17:07:06 +02:00
										 |  |  |       isAdmin, | 
					
						
							|  |  |  |       canManage, | 
					
						
							| 
									
										
										
										
											2023-11-05 19:07:02 -06:00
										 |  |  |       isOwnGroup, | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  |       sessionUser: $auth.user, | 
					
						
							| 
									
										
										
										
											2025-09-03 17:07:06 +02:00
										 |  |  |       toggleDark, | 
					
						
							| 
									
										
										
										
											2022-01-09 21:04:24 -09:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |   }, | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2021-07-31 14:45:28 -08:00
										 |  |  | </script> | 
					
						
							| 
									
										
										
										
											2022-01-07 22:09:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-20 00:09:12 +07:00
										 |  |  | <style scoped> | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  | @media print { | 
					
						
							|  |  |  |   .no-print { | 
					
						
							|  |  |  |     display: none; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-06-13 09:33:46 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | .favorites-link { | 
					
						
							|  |  |  |   text-decoration: none; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .favorites-link:hover { | 
					
						
							|  |  |  |   text-decoration: underline; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  | </style> |