2025-06-07 14:49:23 +02:00

313 lines
7.8 KiB
Vue

<template>
<nav class="mainNav" :class="[
isMenuOpen ? 'active' : '',
screenWidth < 1350 ? 'mobile-nav' : 'desk-nav',
scrollPosition > 50 ? 'scrolled' : ''
]">
<!-- Burger Icon nur bei Mobile sichtbar -->
<div class="burger" @click="toggleMenu" v-if="screenWidth < 1350" :class="{ open: isMenuOpen }">
<span></span>
<span></span>
</div>
<!-- Navigation -->
<ul
:class="[
screenWidth < 1350 && isMenuOpen ? 'mobile-menu active' :
screenWidth < 1350 ? 'mobile-menu' : 'desk-menu']"
v-show="screenWidth >= 1350 || isMenuOpen"
>
<li
v-for="link in navigationLinks"
:key="link.label"
class="nav-item"
@mouseenter="screenWidth >= 1350 && link.subNav && showSubNav(link.label)"
@mouseleave="screenWidth >= 1350 && link.subNav && hideSubNav(link.label)"
>
<!-- Mit SubNav -->
<template v-if="link.subNav">
<div @click="screenWidth < 1350 ? toggleMobileSubNav(link.label) : null">
{{ $t(link.label) }}
<span class="arrow" :class="{ open: (screenWidth < 1350 ? isMobileSubNavOpen : isSubNavOpen) === link.label }"></span>
</div>
<ul
v-show="isActiveSubNav(link.label)"
class="submenu"
:class="{ open: isActiveSubNav(link.label) }"
>
<li v-for="sublink in link.subNav" :key="sublink.label">
<NuxtLinkLocale :to="sublink.routeKey" @click.native="handleMobileClose">
{{ $t(sublink.label) }}
</NuxtLinkLocale>
</li>
</ul>
</template>
<!-- Ohne SubNav -->
<template v-else>
<NuxtLinkLocale :to="link.routeKey" @click.native="handleMobileClose">
{{ $t(link.label) }}
</NuxtLinkLocale>
</template>
</li>
</ul>
</nav>
</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)
const isMobileSubNavOpen = ref(null)
function toggleMobileSubNav(routeKey) {
if (screenWidth.value < 1350) {
isMobileSubNavOpen.value = isMobileSubNavOpen.value === routeKey ? null : routeKey
}
}
function showSubNav(routeKey) {
isSubNavOpen.value = routeKey
}
function hideSubNav(routeKey) {
if (isSubNavOpen.value === routeKey) {
isSubNavOpen.value = null
}
}
function isActiveSubNav(label) {
return (screenWidth.value < 1350 ? isMobileSubNavOpen.value : isSubNavOpen.value) === label
}
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: 'menu.webagency'
},
{
routeKey: '',
label: 'menu.services',
subNav: [
{ routeKey: 'services-cms', label: 'menu.menuCms' },
{ routeKey: 'services-seo', label: 'menu.menuSEO' },
{ routeKey: 'services-accessibility', label: 'menu.menuAccessibility' },
{ routeKey: 'services-ai', label: 'menu.menuAi' }
]
},
{
routeKey: '',
label: 'menu.sectors',
subNav: [
{ routeKey: 'sectors-schools', label: 'menu.menuSchools' },
{ routeKey: 'sectors-film', label: 'menu.menuFilm' }
]
},
{ routeKey: 'references', label: 'menu.references' }
]
</script>
<style lang="sass">
.mainNav
position: fixed
z-index: 50
display: flex
justify-content: flex-end
width: auto
&.desk-nav
top: 2rem
right: 2rem
background: rgba(white, .9)
border-radius: 1rem
transition: .8s
&.scrolled
top: -.5rem
right: -3rem
background: transparent
&.mobile-nav
top: 0
right: 0
background-color: transparent
.burger
width: 4rem
height: 4rem
border-radius: 50%
background-color: $darkgrey
display: flex
align-items: center
justify-content: center
flex-direction: column
cursor: pointer
z-index: 55
margin: 2rem 1.5rem
span
display: block
width: 25px
height: 5px
background-color: white
margin: 4px 0
border-radius: 2rem
transition: all 0.3s ease
&.open
background-color: transparent
margin: 1.2rem 1rem
span
height: 3px
&:nth-child(1)
transform: rotate(45deg) translate(2px, 5px)
&:nth-child(2)
transform: rotate(-45deg) translate(3px, -6px)
.nav-item
font-family: 'Comfortaa-Bold'
text-transform: uppercase
color: $darkgrey
font-size: 1.1rem
cursor: pointer
a
text-decoration: none
color: $darkgrey
&:hover
transform: scale(1.1)
.arrow
display: inline-block
margin-left: 0.5rem
transition: transform 0.8s ease
&::after
content: '\276F'
display: inline-block
transform: rotate(90deg)
&.open::after
transform: rotate(-90deg)
.submenu
max-height: 0
opacity: 0
overflow: hidden
visibility: hidden
transition: max-height 0.5s ease, opacity 0.5s ease
&.open
max-height: 500px // hoch genug für deinen Content
opacity: 1
visibility: visible
li
padding: .8rem 1rem .4rem 0
font-size: 1rem
line-height: 140%
position: relative
&::before
content: ''
width: .5rem
height: .4rem
background-color: rgba($primaryColor, .9)
border-radius: $loopShape
position: absolute
top: 1.2rem
left: -1rem
border-radius: 20px
.desk-menu
list-style: none
display: flex
flex-direction: row
padding: .2rem 3.5rem
.nav-item
position: relative
padding: .5rem 1rem
cursor: pointer
a
transition: .5s
:hover
transform: scale(1.1)
.submenu
position: absolute
top: 100%
left: -50%
width: 200%
background-image: linear-gradient(to bottom, rgba(#fff, 0.1) 0%, rgba(#fff, 0.9) 8%, rgba(#fff, .98) 100%)
border-bottom-right-radius: 1rem
border-bottom-left-radius: 1rem
list-style: none
padding: 1rem .5rem .5rem 2.5rem
box-shadow: 1px 4px 4px rgba(0, 0, 0, 0.1)
z-index: 10
.mobile-menu
list-style: none
padding: 5rem 8%
background-color: rgba($darkgrey, .95)
width: 6rem
display: flex
flex-direction: column
align-items: flex-start
transition: .8s
position: fixed
top: -1rem
right: 0
&.active
width: 80vw
max-height: 100vh
border-bottom-left-radius: 2rem
.nav-item
position: relative
padding: .5rem 1rem
cursor: pointer
color: white
&::before
content: ''
width: .7rem
height: .5rem
background-color: rgba($primaryColor, .9)
border-radius: $loopShape
position: absolute
top: .8rem
left: -.4rem
border-radius: 20px
.submenu
margin: 1rem 0 .2rem -1.8rem
list-style: none
a
text-transform: none
li, a
transition: .5s
color: white
:hover
transform: scale(1.1)
</style>