dml_frontend/components/template/NavigationBar.vue
2025-06-07 14:49:23 +02:00

436 lines
11 KiB
Vue

<template>
<div
class="navigationBox"
:class="[
isMenuOpen ? 'menu-active' : '',
screenWidth < 1350 ? 'mobile' : 'desk'
]"
role="navigation"
aria-label="Hauptnavigation"
tabindex="0"
>
<div
class="closer"
role="button"
tabindex="0"
aria-label="Navigation schließen"
@click="toggleMenu"
@keydown.enter="toggleMenu"
/>
<nav
v-if="isMenuOpen || screenWidth > 1350"
:aria-expanded="screenWidth < 1350 ? 'true' : undefined"
@mouseleave="screenWidth >= 1350 && hideSubNav()"
>
<!-- <div class="mobilNavLogo">
<NuxtImg
v-if="screenWidth < 1350"
provider="strapi"
src="/uploads/DML_Logo_mint_negative_2024_9257db5430.svg"
alt="digimedialoop Logo"
width="120"
/>
</div> -->
<span
v-for="link in navigationLinks"
:key="link.routeKey"
class="main-nav-item"
@mouseenter="screenWidth >= 1350 && showSubNav(link.routeKey)"
@mouseleave="screenWidth >= 1350 && hideSubNav(link.routeKey)"
>
<NuxtLinkLocale
:to="link.routeKey"
class="main-nav-link"
:aria-haspopup="link.subNav && link.subNav.length > 0 ? 'true' : undefined"
:aria-expanded="isSubNavOpen === link.routeKey ? 'true' : 'false'"
@click="handleMobileClose"
>
{{ $t(link.label) }}
</NuxtLinkLocale>
<!-- PFEIL FÜR MOBILE UND TOGGLE -->
<button
v-if="link.subNav && link.subNav.length > 0 && screenWidth < 1350"
class="submenu-toggle"
@click.prevent="toggleMobileSubNav(link.routeKey)"
:aria-expanded="isMobileSubNavOpen === link.routeKey ? 'true' : 'false'"
aria-label="Untermenü öffnen/schließen"
>
<svg
:class="{ 'open': isMobileSubNavOpen === link.routeKey }"
xmlns="http://www.w3.org/2000/svg"
width="12"
height="8"
viewBox="0 0 12 8"
fill="none"
>
<path d="M1 1L6 6L11 1" stroke="currentColor" stroke-width="2"/>
</svg>
</button>
<!-- SUBNAVIGATION -->
<ul
v-if="link.subNav && link.subNav.length > 0"
v-show="(screenWidth >= 1350 && isSubNavOpen === link.routeKey) || (screenWidth < 1350 && isMobileSubNavOpen === link.routeKey)"
class="sub-nav"
>
<li v-for="subLink in link.subNav" :key="subLink.routeKey" class="sub-nav-item">
<NuxtLinkLocale
:to="subLink.routeKey"
class="sub-nav-link"
@click="handleMobileClose"
>
{{ $t(subLink.label) }}
</NuxtLinkLocale>
</li>
</ul>
</span>
<a
class="menu_link" href="#"
role="button"
aria-label="Kontaktformular öffnen"
@click="toggleContactBubble"
>
{{ $t('contact') }}
</a>
<SettingsPanel v-if="screenWidth < 1350" />
</nav>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import { useMainStore } from '@/stores/main'
const mainStore = useMainStore()
const screenWidth = computed(() => mainStore.screenWidth)
const scrollPosition = computed(() => mainStore.scrollPosition)
const isSubNavOpen = ref(null) // speichert, welches Submenü auf Desktop offen ist
const isMobileSubNavOpen = ref(null) // Trackt, welches Submenü auf Mobile offen ist
function toggleMobileSubNav(routeKey) {
if (screenWidth.value < 1350) {
isMobileSubNavOpen.value = isMobileSubNavOpen.value === routeKey ? null : routeKey
}
}
// Funktionen zum Öffnen und Schließen der Subnavigation auf Desktop
function showSubNav(routeKey) {
isSubNavOpen.value = routeKey
}
function hideSubNav(routeKey) {
if (isSubNavOpen.value === routeKey) {
isSubNavOpen.value = null
}
}
const isMenuOpen = computed(() => mainStore.menuOpen)
const toggleMenu = () => mainStore.toggleMenu()
const toggleContactBubble = () => mainStore.toggleContactBubble()
const handleMobileClose = () => {
if (screenWidth.value < 1350 && isMenuOpen.value) {
toggleMenu()
} else {
hideSubNav()
}
}
const navigationLinks = [
{
routeKey: 'webagency',
label: 'webagency'
},
{
routeKey: '',
label: 'services',
subNav: [
{ routeKey: 'services-cms', label: 'menuCms' },
{ routeKey: 'services-seo', label: 'menuSEO' },
{ routeKey: 'services-accessibility', label: 'menuAccessibility' },
{ routeKey: 'services-ai', label: 'menuAi' },
]
},
{
routeKey: '',
label: 'sectors',
subNav: [
{ routeKey: 'sectors-schools', label: 'menuSchools' },
{ routeKey: 'sectors-film', label: 'menuFilm' }
]
},
{ routeKey: 'references', label: 'references' }
]
</script>
<style lang="sass">
.navigationBox
position: relative
display: flex
align-items: center
justify-content: flex-end
width: 80%
transition: .8s
margin-top: 1.2rem // -1rem
nav
display: block
z-index: 102
//background: linear-gradient(to right, rgba($lightgrey, 0.8), rgba(white, 0.9), rgba(white, 0.9))
background: white
border: 1px solid adjust-color($beige, $lightness: 5%)
padding: 1rem 2rem
text-align: center
border-radius: 1rem
margin: 4.8rem 1rem 0 1rem
transition: .8s
a
margin: 0 1.2rem
text-decoration: none
color: $darkgrey
text-transform: uppercase
font-family: 'Comfortaa-Bold'
font-size: 1.1rem
letter-spacing: .05rem
transition: .6s
display: inline-block
&:hover
transform: scale(1.15)
background-image: radial-gradient(rgba(white, .5), rgba(white, .1))
box-shadow: 0 0 10px 10px rgba(white, 0.2)
border-radius: 10px
&.desk
.sub-nav
display: block
position: absolute
top: 3rem
right: 5%
background-color: rgba(white, .95)
padding: 2rem 2rem 1rem 2rem
text-align: left
cursor: pointer
border-bottom-left-radius: 1rem
border-bottom-right-radius: 1rem
list-style: none
.sub-nav-item
padding: 0 0 1.5rem 0
.sub-nav-link
position: relative
margin-left: 1.2rem
&::before
content: ''
width: .5rem
height: .4rem
background-color: rgba($primaryColor, .9)
border-radius: $loopShape
position: absolute
top: .4rem
left: -1.3rem
border-radius: 20px
&:hover
transform: scale(1.025)
&.mobile
top: 0
&.navigationBox
display: block
position: relative
background-color: $darkgrey
width: 4rem
height: 4rem
z-index: 8
border-radius: 50%
margin-right: 5vw
margin-top: 2rem
.closer
position: relative
width: 100%
height: 4rem
&::after, &::before
position: absolute
content: ''
width: 2rem
z-index: 12
height: 5px
border-radius: 4px
background-color: white
right: 75%
transform: translateX(100%)
transition: .8s
&::before
top: 35%
&::after
top: 55%
nav
display: none
background-image: none
background: transparent
border: none
padding-top: 0rem !important
.submenu-toggle
background: none
border: none
padding: 0 0 0 0.5rem
margin-top: -1rem
cursor: pointer
display: inline-flex
align-items: center
color: white
transition: transform 0.3s ease
svg
transition: transform 0.3s ease
&.open svg,
svg.open
transform: rotate(180deg) // Pfeil zeigt nach oben, wenn offen
.sub-nav
overflow: hidden
max-height: 0
opacity: 0
transition: max-height 0.4s ease, opacity 0.4s ease
&.open
max-height: 500px
opacity: 1
.sub-nav
list-style: none
padding-left: 1.8rem
margin: 0
.sub-nav-item
padding-left: 1rem
margin-bottom: 0.2rem
.sub-nav-link
color: white
font-size: 1rem !important
line-height: 1.5rem
padding: 0.5rem 1.5rem
&:hover
&::before
content: ''
width: .5rem
height: .4rem
background-color: rgba($primaryColor, .9)
border-radius: $loopShape
position: absolute
top: 1rem
left: 0
border-radius: 20px
.menu_link
margin-left: 1.5rem
transition: .8s
&:hover
transform: scale(1.06)
background-image: radial-gradient(rgba($primaryColor, .1), transparent, transparent)
box-shadow: 0 0 0 0 transparent
border-radius: 20px
a, .menu_link
display: block
color: white
text-align: left
margin-bottom: .2rem
padding: 1rem 2.8rem .5rem 1.2rem
position: relative
font-size: 1.25rem !important
width: auto
max-width: 18rem
text-transform: uppercase
font-family: 'Mainfont-Bold'
&::before
content: ''
width: .8rem
height: .6rem
background-color: rgba($primaryColor, .9)
border-radius: $loopShape
position: absolute
top: 1.5rem
left: -.5rem
border-radius: 20px
&:hover
transform: scale(1.06)
background-image: radial-gradient(rgba($primaryColor, .1), transparent, transparent)
box-shadow: 0 0 0 0 transparent
border-radius: 20px
&.menu-active
width: 100vw
height: 98vh
border-radius: 5px
margin: 0
background-color: rgba($darkgrey, .97)
.closer
&::before, &::after
top: 2rem
right: 2rem
&::before
transform: rotate(45deg)
&::after
transform: rotate(-45deg)
nav
display: block
padding: 10vh 0
margin: 0 5vw
.navigationBox
margin-top: .5rem
nav
display: flex
margin: 2.5rem 0 0 0
padding: 1rem .5rem
border-top-right-radius: 0
border-top-left-radius: 0
border-bottom-left-radius: 50px
border-bottom-right-radius: 0
background: transparent
border: 1px solid transparent
a
font-size: 1rem
font-weight: bold
margin: 0 .8rem
&.desk
.sub-nav
top: 1.5rem
right: 2%
background-color: transparent
background-image: linear-gradient(to bottom, transparent 0%, white 15%)
</style>