|
|
@@ -2,82 +2,64 @@
|
|
|
Menu Navigation
|
|
|
-->
|
|
|
<template>
|
|
|
- <LayoutNavigationTopbar />
|
|
|
|
|
|
- <v-row class="menu" v-if="!mdAndDown" style="margin-top: 0 !important;">
|
|
|
- <v-col cols="3">
|
|
|
- <nuxt-link to="/">
|
|
|
- <v-img class="logo" src="/images/logo/navigation-logo.png" />
|
|
|
- </nuxt-link>
|
|
|
- </v-col>
|
|
|
-
|
|
|
- <v-col cols="9">
|
|
|
- <v-menu open-on-hover>
|
|
|
- <template v-slot:activator="{ props }">
|
|
|
- <nuxt-link v-bind="props" class="link-style"
|
|
|
- >Nos logiciels
|
|
|
- </nuxt-link>
|
|
|
- </template>
|
|
|
-
|
|
|
- <v-list class="menu-list">
|
|
|
- <nuxt-link
|
|
|
- v-for="software in softwareLinks"
|
|
|
- :key="software.name"
|
|
|
- :to="software.href"
|
|
|
- class="link-styles"
|
|
|
- >
|
|
|
- <v-list-item>
|
|
|
- <v-list-item-title>{{ software.name }}</v-list-item-title>
|
|
|
- </v-list-item>
|
|
|
- </nuxt-link>
|
|
|
- </v-list>
|
|
|
- </v-menu>
|
|
|
-
|
|
|
- <v-menu open-on-hover>
|
|
|
- <template v-slot:activator="{ props }">
|
|
|
- <nuxt-link v-bind="props" class="link-style">Nos services </nuxt-link>
|
|
|
- </template>
|
|
|
-
|
|
|
- <v-list>
|
|
|
- <nuxt-link
|
|
|
- v-for="service in serviceLinks"
|
|
|
- :key="service.name"
|
|
|
- :to="service.href"
|
|
|
- class="link-styles"
|
|
|
- >
|
|
|
- <v-list-item>
|
|
|
- <v-list-item-title>{{ service.name }}</v-list-item-title>
|
|
|
- </v-list-item>
|
|
|
- </nuxt-link>
|
|
|
- </v-list>
|
|
|
- </v-menu>
|
|
|
-
|
|
|
- <v-menu open-on-hover>
|
|
|
- <template v-slot:activator="{ props }">
|
|
|
- <nuxt-link v-bind="props" class="link-style">à propos</nuxt-link>
|
|
|
- </template>
|
|
|
-
|
|
|
- <v-list>
|
|
|
- <nuxt-link
|
|
|
- v-for="info in aboutLinks"
|
|
|
- :key="info.name"
|
|
|
- :to="info.href"
|
|
|
- class="link-styles"
|
|
|
+ <!-- Navigation (écran large) -->
|
|
|
+ <div v-if="mdAndUp">
|
|
|
+ <LayoutNavigationTopbar />
|
|
|
+
|
|
|
+ <v-row class="navigation-lg" style="margin-top: 0 !important;">
|
|
|
+ <!-- Logo Opentalent -->
|
|
|
+ <v-col cols="3">
|
|
|
+ <nuxt-link to="/">
|
|
|
+ <v-img class="logo" src="/images/logo/navigation-logo.png" />
|
|
|
+ </nuxt-link>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <!-- Menu principal -->
|
|
|
+ <v-col cols="9">
|
|
|
+ <v-menu
|
|
|
+ v-for="item in menu"
|
|
|
+ :key="item.label"
|
|
|
+ open-on-hover
|
|
|
+ >
|
|
|
+ <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-list-item-title>{{ info.name }}</v-list-item-title>
|
|
|
+ <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>
|
|
|
- </nuxt-link>
|
|
|
- </v-list>
|
|
|
- </v-menu>
|
|
|
-
|
|
|
- <nuxt-link class="link-style" to="/actualites">Actualités</nuxt-link>
|
|
|
- <nuxt-link class="link-style" to="/nous-contacter">Contact</nuxt-link>
|
|
|
- </v-col>
|
|
|
- </v-row>
|
|
|
- <v-app v-if="mdAndDown" class="navigation-sm">
|
|
|
+ </v-list>
|
|
|
+ </v-menu>
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- Navigation (petit écran) -->
|
|
|
+ <v-app
|
|
|
+ v-else
|
|
|
+ class="navigation-sm"
|
|
|
+ >
|
|
|
+ <!-- Top bar -->
|
|
|
<v-app-bar app>
|
|
|
- <v-app-bar-nav-icon @click="toggleDrawer"></v-app-bar-nav-icon>
|
|
|
+ <v-app-bar-nav-icon
|
|
|
+ @click="toggleMenu"
|
|
|
+ />
|
|
|
|
|
|
<nuxt-link to="/">
|
|
|
<v-img class="logo-md" src="/images/logo/navigation-logo.png" />
|
|
|
@@ -104,36 +86,33 @@ Menu Navigation
|
|
|
</v-app-bar>
|
|
|
|
|
|
<!-- Tiroir de navigation principal -->
|
|
|
- <v-navigation-drawer v-model="drawer" app>
|
|
|
+ <v-navigation-drawer
|
|
|
+ v-model="isMenuOpen"
|
|
|
+ app
|
|
|
+ temporary
|
|
|
+ >
|
|
|
<v-list nav dense>
|
|
|
<v-list-item
|
|
|
- v-for="(item, index) in menuItems"
|
|
|
- :key="item.id"
|
|
|
- @click="selectMenu(item.id)"
|
|
|
+ v-if="isSubMenu"
|
|
|
+ class="menuItem back-item"
|
|
|
+ @click="onBackItemClick"
|
|
|
>
|
|
|
<v-list-item-title>
|
|
|
- {{ item.label }}
|
|
|
+ <v-icon icon="fas fa-caret-left" class="mr-1"/> Retour
|
|
|
</v-list-item-title>
|
|
|
</v-list-item>
|
|
|
- </v-list>
|
|
|
- </v-navigation-drawer>
|
|
|
|
|
|
- <!-- Tiroir de sous-menu -->
|
|
|
- <v-navigation-drawer v-model="subMenuDrawer" app right temporary>
|
|
|
- <v-list nav dense>
|
|
|
- <v-list-item>
|
|
|
- <v-list-item-title @click="closeSubMenu">Retour</v-list-item-title>
|
|
|
- </v-list-item>
|
|
|
- <nuxt-link
|
|
|
- v-for="(subItem, subIndex) in subMenus[currentMenu]"
|
|
|
- :key="subIndex"
|
|
|
- :to="subItem.href"
|
|
|
- style="text-decoration: none !important; color: black"
|
|
|
+ <v-list-item
|
|
|
+ v-for="(item, index) in activeMenu"
|
|
|
+ :key="item.label"
|
|
|
+ :to="item.to"
|
|
|
+ class="menuItem"
|
|
|
+ @click="onMenuItemClick(index, item)"
|
|
|
>
|
|
|
- <v-list-item>
|
|
|
- <v-list-item-title>{{ subItem.name }}</v-list-item-title>
|
|
|
- </v-list-item>
|
|
|
- </nuxt-link>
|
|
|
+ <v-list-item-title>
|
|
|
+ {{ item.label }}
|
|
|
+ </v-list-item-title>
|
|
|
+ </v-list-item>
|
|
|
</v-list>
|
|
|
</v-navigation-drawer>
|
|
|
</v-app>
|
|
|
@@ -141,139 +120,152 @@ Menu Navigation
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
import { useDisplay } from "vuetify";
|
|
|
-const { mdAndDown } = useDisplay();
|
|
|
-
|
|
|
-const softwareLinks = ref([
|
|
|
- { name: "Opentalent Artist", href: "/opentalent_artist" },
|
|
|
- { name: "Opentalent School", href: "/opentalent_school" },
|
|
|
- { name: "Opentalent Manager", href: "/opentalent_manager" },
|
|
|
-]);
|
|
|
-
|
|
|
-const serviceLinks = ref([
|
|
|
- { name: "Formations", href: "/formations" },
|
|
|
- { name: "Webinaires", href: "/webinaires" },
|
|
|
-]);
|
|
|
-
|
|
|
-const aboutLinks = ref([
|
|
|
- { name: "Qui sommes-nous", href: "/qui-sommes-nous" },
|
|
|
- { name: "Nous rejoindre", href: "/nous-rejoindre" },
|
|
|
-]);
|
|
|
-
|
|
|
-const drawer = ref(false);
|
|
|
-const subMenuDrawer = ref(false);
|
|
|
-const currentMenu = ref("");
|
|
|
-const menuItems = ref([
|
|
|
- { id: "logiciels", label: "Nos logiciels" },
|
|
|
- { id: "services", label: "Nos services" },
|
|
|
- { id: "about", label: "À propos" },
|
|
|
- { id: "actualites", label: "Actualités" },
|
|
|
- { id: "contact", label: "Contact" },
|
|
|
-]);
|
|
|
-
|
|
|
-const subMenus = ref({
|
|
|
- logiciels: [
|
|
|
- { name: "Opentalent Artist", href: "/opentalent_artist" },
|
|
|
- { name: "Opentalent School", href: "/opentalent_school" },
|
|
|
- { name: "Opentalent Manager", href: "/opentalent_manager" },
|
|
|
- ],
|
|
|
- services: [
|
|
|
- { name: "Formations", href: "/formations" },
|
|
|
- { name: "Webinaires", href: "/webinaires" },
|
|
|
- ],
|
|
|
- propos: [
|
|
|
- { name: "Qui sommes-nous", href: "/qui-sommes-nous" },
|
|
|
- { name: "Nous rejoindre", href: "/nous-rejoindre" },
|
|
|
- ],
|
|
|
-});
|
|
|
-
|
|
|
-const toggleDrawer = () => {
|
|
|
- drawer.value = !drawer.value;
|
|
|
+import { MainMenuItem } from "~/types/interface";
|
|
|
+const { mdAndUp } = useDisplay();
|
|
|
+
|
|
|
+const menu: Array<MainMenuItem> = [
|
|
|
+ {
|
|
|
+ label: "Nos logiciels",
|
|
|
+ children: [
|
|
|
+ { label: "Opentalent Artist", to: "/opentalent_artist" },
|
|
|
+ { label: "Opentalent School", to: "/opentalent_school" },
|
|
|
+ { label: "Opentalent Manager", to: "/opentalent_manager" },
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "Nos services",
|
|
|
+ children: [
|
|
|
+ { label: "Formations", to: "/formations" },
|
|
|
+ { label: "Webinaires", to: "/webinaires" },
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "À propos",
|
|
|
+ children: [
|
|
|
+ { label: "Qui sommes-nous", to: "/qui-sommes-nous" },
|
|
|
+ { label: "Nous rejoindre", to: "/nous-rejoindre" },
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ { label: "Actualités", to: "/actualites" },
|
|
|
+ { label: "Contact", to: "/nous-contacter" },
|
|
|
+]
|
|
|
+
|
|
|
+// Menu dépliant (petit écran)
|
|
|
+const isMenuOpen: Ref<boolean> = ref(false);
|
|
|
+const toggleMenu = () => {
|
|
|
+ isMenuOpen.value = !isMenuOpen.value;
|
|
|
};
|
|
|
|
|
|
-const selectMenu = (id) => {
|
|
|
- if (subMenus.value[id]) {
|
|
|
- currentMenu.value = id;
|
|
|
- subMenuDrawer.value = true;
|
|
|
- drawer.value = false;
|
|
|
- } else {
|
|
|
- switch (id) {
|
|
|
- case "actualites":
|
|
|
- window.location.href = "/actualites";
|
|
|
- break;
|
|
|
- case "contact":
|
|
|
- window.location.href = "/nous-contacter";
|
|
|
- break;
|
|
|
- }
|
|
|
+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 closeSubMenu = () => {
|
|
|
- subMenuDrawer.value = false;
|
|
|
- drawer.value = true;
|
|
|
-};
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
-.navigation-sm {
|
|
|
- background-color: #ffffff;
|
|
|
- position: fixed;
|
|
|
- top: 0;
|
|
|
+
|
|
|
+.logo {
|
|
|
+ height: 8rem;
|
|
|
}
|
|
|
-/* =============== menu Styles =============== */
|
|
|
|
|
|
-.menu {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- background-color: #ffffff;
|
|
|
+.logo-md {
|
|
|
+ width: 150px;
|
|
|
+ height: 300px;
|
|
|
}
|
|
|
-.v-list-item-title {
|
|
|
- font-family: "Barlow";
|
|
|
+
|
|
|
+.icon {
|
|
|
+ color: #000000;
|
|
|
+}
|
|
|
+
|
|
|
+.menuItem, .menuItem .v-list-item-title {
|
|
|
+ font-family: "Barlow", serif;
|
|
|
font-style: normal;
|
|
|
font-weight: 500;
|
|
|
font-size: 0.9rem;
|
|
|
letter-spacing: 0.1em;
|
|
|
text-transform: uppercase;
|
|
|
color: #0e2d32;
|
|
|
-}
|
|
|
-.common-styles {
|
|
|
- font-family: "Barlow";
|
|
|
- font-style: normal;
|
|
|
- font-size: 1.1rem;
|
|
|
- padding: 0.1rem;
|
|
|
- font-weight: 700;
|
|
|
- letter-spacing: 0.1em;
|
|
|
- text-transform: uppercase;
|
|
|
- color: #0e2d32;
|
|
|
- text-decoration: none !important;
|
|
|
-}
|
|
|
-.link-style {
|
|
|
- font-family: "Barlow";
|
|
|
- font-style: normal;
|
|
|
- font-size: 1rem;
|
|
|
- margin-right: 3rem;
|
|
|
- font-weight: 700;
|
|
|
- letter-spacing: 0.05em;
|
|
|
- text-transform: uppercase;
|
|
|
- color: #0e2d32;
|
|
|
- text-decoration: none !important;
|
|
|
cursor: pointer;
|
|
|
-}
|
|
|
-.link-styles {
|
|
|
- font-family: "Barlow";
|
|
|
- font-style: normal;
|
|
|
text-decoration: none !important;
|
|
|
- color: #0e2d32;
|
|
|
}
|
|
|
-.logo {
|
|
|
- height: 8rem;
|
|
|
+
|
|
|
+/**
|
|
|
+ Navigation grands écrans
|
|
|
+ */
|
|
|
+.navigation-lg {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ background-color: #ffffff;
|
|
|
+
|
|
|
+ .menuItem {
|
|
|
+ padding: 18px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .menuItem.first-level {
|
|
|
+ font-size: 1rem;
|
|
|
+ margin-right: 1rem;
|
|
|
+ font-weight: 700;
|
|
|
+ letter-spacing: 0.05em;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-.logo-md {
|
|
|
- width: 150px;
|
|
|
- height: 300px;
|
|
|
+/**
|
|
|
+ Navigation petits écrans
|
|
|
+ */
|
|
|
+.navigation-sm {
|
|
|
+ background-color: #ffffff;
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
}
|
|
|
|
|
|
-.icon {
|
|
|
- color: #000000;
|
|
|
+.back-item {
|
|
|
+ border-bottom: solid 1px darkgray;
|
|
|
+ border-radius: 0;
|
|
|
+
|
|
|
+ .v-list-item-title {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|