|
@@ -2,128 +2,25 @@
|
|
|
Menu Navigation
|
|
Menu Navigation
|
|
|
-->
|
|
-->
|
|
|
<template>
|
|
<template>
|
|
|
- <!-- Navigation (écran large) -->
|
|
|
|
|
- <div v-if="mdAndUp" v-intersect="onIntersect">
|
|
|
|
|
- <LayoutNavigationTopbar />
|
|
|
|
|
-
|
|
|
|
|
- <v-row class="navigation-lg" style="margin-top: 0 !important;">
|
|
|
|
|
- <!-- Logo Opentalent -->
|
|
|
|
|
- <v-col cols="2">
|
|
|
|
|
- <nuxt-link to="/">
|
|
|
|
|
- <v-img class="logo" src="/images/logo/navigation-logo.png" />
|
|
|
|
|
- </nuxt-link>
|
|
|
|
|
- </v-col>
|
|
|
|
|
-
|
|
|
|
|
- <!-- Menu principal -->
|
|
|
|
|
- <v-col cols="10" class="pl-6">
|
|
|
|
|
- <v-menu
|
|
|
|
|
- v-for="item in menu"
|
|
|
|
|
- :key="item.label"
|
|
|
|
|
- :open-on-hover="true"
|
|
|
|
|
- >
|
|
|
|
|
- <template v-slot:activator="{ props }">
|
|
|
|
|
- <nuxt-link
|
|
|
|
|
- v-bind="props"
|
|
|
|
|
- class="menuItem first-level"
|
|
|
|
|
- :to="item.to"
|
|
|
|
|
- >
|
|
|
|
|
- {{ item.label }}
|
|
|
|
|
- </nuxt-link>
|
|
|
|
|
- </template>
|
|
|
|
|
-
|
|
|
|
|
- <v-list
|
|
|
|
|
- v-if="item.children?.length > 0"
|
|
|
|
|
- class="menu-list"
|
|
|
|
|
- >
|
|
|
|
|
- <v-list-item
|
|
|
|
|
- v-for="child in item.children"
|
|
|
|
|
- :key="child.label"
|
|
|
|
|
- :to="child.to"
|
|
|
|
|
- class="menuItem"
|
|
|
|
|
- >
|
|
|
|
|
- <v-list-item-title>{{ child.label }}</v-list-item-title>
|
|
|
|
|
- </v-list-item>
|
|
|
|
|
- </v-list>
|
|
|
|
|
- </v-menu>
|
|
|
|
|
- </v-col>
|
|
|
|
|
- </v-row>
|
|
|
|
|
|
|
+ <div v-intersect="onIntersect">
|
|
|
|
|
+ <!-- Navigation (écran large) -->
|
|
|
|
|
+ <div v-if="lgAndUp">
|
|
|
|
|
+ <LayoutNavigationLg :menu="menu" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Navigation (petit écran) -->
|
|
|
|
|
+ <div v-else>
|
|
|
|
|
+ <LayoutNavigationMd :menu="menu" />
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
-
|
|
|
|
|
- <!-- Navigation (petit écran) -->
|
|
|
|
|
- <v-app
|
|
|
|
|
- v-else
|
|
|
|
|
- class="navigation-sm"
|
|
|
|
|
- >
|
|
|
|
|
- <!-- Top bar -->
|
|
|
|
|
- <v-app-bar app>
|
|
|
|
|
- <v-app-bar-nav-icon
|
|
|
|
|
- @click="toggleMenu"
|
|
|
|
|
- />
|
|
|
|
|
-
|
|
|
|
|
- <nuxt-link to="/">
|
|
|
|
|
- <v-img class="logo-md" src="/images/logo/navigation-logo.png" />
|
|
|
|
|
- </nuxt-link>
|
|
|
|
|
-
|
|
|
|
|
- <nuxt-link
|
|
|
|
|
- to="https://admin.opentalent.fr/#/login/"
|
|
|
|
|
- style="text-decoration: none"
|
|
|
|
|
- >
|
|
|
|
|
- <v-btn text>
|
|
|
|
|
- <v-icon left class="fas fa-user icon"></v-icon>
|
|
|
|
|
- </v-btn>
|
|
|
|
|
- </nuxt-link>
|
|
|
|
|
-
|
|
|
|
|
- <v-btn text>
|
|
|
|
|
- <v-icon left class="fas fa-phone icon"></v-icon>
|
|
|
|
|
- </v-btn>
|
|
|
|
|
-
|
|
|
|
|
- <AgendaLink href="/agenda-culturel" style="text-decoration: none">
|
|
|
|
|
- <v-btn text>
|
|
|
|
|
- <v-icon left class="fas fa-calendar icon"></v-icon>
|
|
|
|
|
- </v-btn>
|
|
|
|
|
- </AgendaLink>
|
|
|
|
|
- </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>
|
|
|
|
|
- {{ item.label }}
|
|
|
|
|
- </v-list-item-title>
|
|
|
|
|
- </v-list-item>
|
|
|
|
|
- </v-list>
|
|
|
|
|
- </v-navigation-drawer>
|
|
|
|
|
- </v-app>
|
|
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
import { useDisplay } from "vuetify";
|
|
import { useDisplay } from "vuetify";
|
|
|
import type { MainMenuItem } from "~/types/interface";
|
|
import type { MainMenuItem } from "~/types/interface";
|
|
|
-import AgendaLink from "~/components/Common/AgendaLink.vue";
|
|
|
|
|
-import Footer from "~/components/Layout/Footer/Footer.vue";
|
|
|
|
|
import { useLayoutStore } from "~/stores/layoutStore";
|
|
import { useLayoutStore } from "~/stores/layoutStore";
|
|
|
-const { mdAndUp } = useDisplay();
|
|
|
|
|
|
|
+
|
|
|
|
|
+const { lgAndUp } = useDisplay();
|
|
|
|
|
|
|
|
const menu: Array<MainMenuItem> = [
|
|
const menu: Array<MainMenuItem> = [
|
|
|
{
|
|
{
|
|
@@ -152,57 +49,6 @@ const menu: Array<MainMenuItem> = [
|
|
|
{ label: "Contact", to: "/nous-contacter" },
|
|
{ label: "Contact", to: "/nous-contacter" },
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
-// Menu dépliant (petit écran)
|
|
|
|
|
-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 ? menu[activeMenuIndex.value].children : 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)
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
const layoutStore = useLayoutStore()
|
|
const layoutStore = useLayoutStore()
|
|
|
const onIntersect = (isIntersecting: boolean) => {
|
|
const onIntersect = (isIntersecting: boolean) => {
|
|
|
layoutStore.setIsHeaderVisible(isIntersecting)
|
|
layoutStore.setIsHeaderVisible(isIntersecting)
|
|
@@ -212,66 +58,4 @@ const onIntersect = (isIntersecting: boolean) => {
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
|
|
|
|
|
-.logo {
|
|
|
|
|
- height: 100px;
|
|
|
|
|
- width: 300px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.logo-md {
|
|
|
|
|
- width: 150px;
|
|
|
|
|
- height: 300px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.icon {
|
|
|
|
|
- color: var(--on-neutral-color);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.menuItem, .menuItem .v-list-item-title {
|
|
|
|
|
- font-weight: 500;
|
|
|
|
|
- font-size: 0.9rem;
|
|
|
|
|
- letter-spacing: 0.1em;
|
|
|
|
|
- text-transform: uppercase;
|
|
|
|
|
- color: var(--primary-color);
|
|
|
|
|
- cursor: pointer;
|
|
|
|
|
- text-decoration: none !important;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/**
|
|
|
|
|
- Navigation grands écrans
|
|
|
|
|
- */
|
|
|
|
|
-.navigation-lg {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- background-color: var(--neutral-color);
|
|
|
|
|
-
|
|
|
|
|
- .menuItem {
|
|
|
|
|
- padding: 18px;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .menuItem.first-level {
|
|
|
|
|
- font-size: 1.3rem;
|
|
|
|
|
- margin-right: 1rem;
|
|
|
|
|
- font-weight: 700;
|
|
|
|
|
- letter-spacing: 0.05em;
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/**
|
|
|
|
|
- Navigation petits écrans
|
|
|
|
|
- */
|
|
|
|
|
-.navigation-sm {
|
|
|
|
|
- background-color: var(--neutral-color);
|
|
|
|
|
- position: fixed;
|
|
|
|
|
- top: 0;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.back-item {
|
|
|
|
|
- border-bottom: solid 1px var(--on-neutral-color-light);
|
|
|
|
|
- border-radius: 0;
|
|
|
|
|
-
|
|
|
|
|
- .v-list-item-title {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
</style>
|
|
</style>
|