| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- <template>
- <div class="app-container">
- <v-app class="navigation-sm">
- <!-- Top bar -->
- <v-app-bar>
- <template #prepend>
- <v-app-bar-nav-icon @click="toggleMenu" />
- </template>
- <v-app-bar-title>
- <nuxt-link to="/">
- <v-img
- class="logo-md"
- src="/images/logos/opentalent/Logo_Opentalent-gris.png"
- />
- </nuxt-link>
- </v-app-bar-title>
- <template #append>
- <v-btn
- href="https://admin.opentalent.fr/#/login/"
- icon="fas fa-user"
- class="icon"
- aria-label="Se connecter"
- />
- <v-btn
- to="/nous-contacter"
- icon="fas fa-phone"
- aria-label="Nous contacter"
- class="icon"
- />
- <v-btn
- :href="runtimeConfig.public.agendaBaseUrl"
- icon="fas fa-calendar"
- aria-label="L'agenda culturel"
- class="icon"
- />
- </template>
- </v-app-bar>
- <!-- Tiroir de navigation principal -->
- <v-navigation-drawer v-model="isMenuOpen" app temporary>
- <v-list nav dense>
- <v-list-item
- v-if="isSubMenu"
- class="menuItem back-item"
- @click="onBackItemClick"
- >
- <v-list-item-title>
- <v-icon icon="fas fa-caret-left" class="mr-1" /> Retour
- </v-list-item-title>
- </v-list-item>
- <v-list-item
- v-for="(item, index) in activeMenu"
- :key="item.label"
- :to="item.to"
- class="menuItem"
- @click="onMenuItemClick(index, item)"
- >
- <v-list-item-title class="d-flex flex-row w-100">
- <span class="flex-grow-1">
- {{ item.label }}
- </span>
- <span v-if="item.children?.length! > 0">
- <v-icon icon="fa fa-angle-right" />
- </span>
- </v-list-item-title>
- </v-list-item>
- </v-list>
- </v-navigation-drawer>
- </v-app>
- </div>
- </template>
- <script setup lang="ts">
- import type { PropType, Ref } from 'vue'
- import type { MainMenuItem } from '~/types/interface'
- const runtimeConfig = useRuntimeConfig()
- const props = defineProps({
- menu: {
- type: Array as PropType<Array<MainMenuItem>>,
- required: true,
- },
- })
- const isMenuOpen: Ref<boolean> = ref(false)
- const toggleMenu = () => {
- isMenuOpen.value = !isMenuOpen.value
- }
- const activeMenuIndex: Ref<number | null> = ref(null)
- const activeMenu = computed(() =>
- activeMenuIndex.value !== null
- ? props.menu![activeMenuIndex.value].children
- : props.menu
- )
- /**
- * Determines if the is active menu is a sub-menu .
- *
- * @function isSubMenu
- * @returns {boolean} - True if a sub-menu is active, otherwise false.
- */
- const isSubMenu = computed(() => activeMenuIndex.value !== null)
- /**
- * Handles the click event on a menu item.
- *
- * @param {number} index - The index of the clicked menu item.
- * @param {MainMenuItem} item - The clicked menu item.
- * @returns {void}
- */
- const onMenuItemClick = (index: number, item: MainMenuItem): void => {
- if (!item.children) {
- return
- }
- withAnimation(() => (activeMenuIndex.value = index))
- }
- /**
- * Function to handle back button click event.
- */
- const onBackItemClick = (): void => {
- withAnimation(() => (activeMenuIndex.value = null))
- }
- /**
- * Déclenche une animation de changement de menu en fermant et rouvrant le drawer
- * @param callback
- */
- const withAnimation = (callback: () => void) => {
- isMenuOpen.value = false
- callback()
- setTimeout(() => {
- isMenuOpen.value = true
- }, 85)
- }
- </script>
- <style scoped lang="scss">
- .app-container {
- height: 54px;
- }
- .v-app-bar {
- max-width: 100vw;
- }
- .navigation-sm {
- background-color: var(--neutral-color);
- position: fixed;
- top: 0;
- z-index: 1000;
- }
- .logo-md {
- width: 150px;
- height: 50px;
- }
- .back-item {
- border-bottom: solid 1px var(--on-neutral-color-light);
- border-radius: 0;
- .v-list-item-title {
- display: flex;
- align-items: center;
- }
- }
- .icon {
- color: var(--on-neutral-color-light);
- }
- </style>
|