Files
harheimertc/components/Navigation.vue
2025-12-20 10:17:16 +01:00

985 lines
41 KiB
Vue

<template>
<nav
class="fixed top-0 left-0 right-0 z-50 bg-gradient-to-r from-gray-900 via-primary-900 to-gray-900 shadow-xl h-20"
>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-full">
<div class="flex flex-col justify-between h-full py-2">
<!-- Hauptmenü -->
<div class="flex justify-between items-center">
<!-- Logo -->
<NuxtLink
to="/"
class="flex items-center space-x-3 hover:scale-105 transition-transform"
>
<img
src="~/assets/images/logos/Harheimer TC.svg"
alt="Harheimer TC Logo"
class="w-12 h-12"
>
<div class="hidden sm:block">
<span class="text-xl font-display font-bold text-white">Harheimer <span
class="text-primary-400"
>TC</span></span>
</div>
</NuxtLink>
<div style="display:flex;flex-direction:column;">
<!-- Desktop Navigation -->
<div class="hidden lg:flex items-center space-x-1">
<NuxtLink
to="/"
class="px-4 py-2 text-gray-300 hover:text-white font-medium transition-all rounded-lg hover:bg-primary-700/50"
active-class="text-white bg-primary-600"
>
Start
</NuxtLink>
<button
class="px-4 py-2 text-gray-300 hover:text-white font-medium transition-all rounded-lg hover:bg-primary-700/50"
:class="(route.path.startsWith('/verein/') || route.path.startsWith('/vorstand') || route.path.startsWith('/vereinsmeisterschaften') || currentSubmenu === 'verein') ? 'text-white bg-primary-600' : ''"
@click="toggleSubmenu('verein')"
>
Verein
</button>
<button
class="px-4 py-2 text-gray-300 hover:text-white font-medium transition-all rounded-lg hover:bg-primary-700/50"
:class="(route.path.startsWith('/mannschaften') || route.path.startsWith('/spielsysteme') || currentSubmenu === 'mannschaften') ? 'text-white bg-primary-600' : ''"
@click="toggleSubmenu('mannschaften')"
>
Mannschaften
</button>
<button
class="px-4 py-2 text-gray-300 hover:text-white font-medium transition-all rounded-lg hover:bg-primary-700/50"
:class="(route.path.startsWith('/training') || route.path.startsWith('/tt-regeln') || currentSubmenu === 'training') ? 'text-white bg-primary-600' : ''"
@click="toggleSubmenu('training')"
>
Training
</button>
<NuxtLink
to="/mitgliedschaft"
class="px-4 py-2 text-gray-300 hover:text-white font-medium transition-all rounded-lg hover:bg-primary-700/50"
active-class="text-white bg-primary-600"
>
Mitgliedschaft
</NuxtLink>
<NuxtLink
to="/termine"
class="px-4 py-2 text-gray-300 hover:text-white font-medium transition-all rounded-lg hover:bg-primary-700/50"
active-class="text-white bg-primary-600"
@click="currentSubmenu = null"
>
Termine
</NuxtLink>
<NuxtLink
v-if="hasGalleryImages"
to="/verein/galerie"
class="px-4 py-2 text-gray-300 hover:text-white font-medium transition-all rounded-lg hover:bg-primary-700/50"
active-class="text-white bg-primary-600"
@click="currentSubmenu = null"
>
Galerie
</NuxtLink>
<button
class="px-4 py-2 text-gray-300 hover:text-white font-medium transition-all rounded-lg hover:bg-primary-700/50"
:class="(route.path.startsWith('/newsletter') || currentSubmenu === 'newsletter') ? 'text-white bg-primary-600' : ''"
@click="toggleSubmenu('newsletter')"
>
Newsletter
</button>
<button
v-if="isLoggedIn"
class="px-4 py-2 text-gray-300 hover:text-white font-medium transition-all rounded-lg hover:bg-primary-700/50"
:class="(route.path.startsWith('/mitgliederbereich') || route.path.startsWith('/cms') || currentSubmenu === 'intern') ? 'text-white bg-primary-600' : ''"
@click="toggleSubmenu('intern')"
>
Intern
</button>
<NuxtLink
to="/kontakt"
class="px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-semibold transition-all rounded-lg shadow-lg"
@click="currentSubmenu = null"
>
Kontakt
</NuxtLink>
</div>
<div class="hidden lg:flex items-center h-6 border-t border-primary-700/20">
<div
v-if="currentSubmenu"
class="flex items-center space-x-1"
>
<!-- Newsletter Submenu -->
<template v-if="currentSubmenu === 'newsletter'">
<NuxtLink
to="/newsletter/subscribe"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Abonnieren
</NuxtLink>
<NuxtLink
to="/newsletter/unsubscribe"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Abmelden
</NuxtLink>
</template>
<!-- Verein Submenu -->
<template v-if="currentSubmenu === 'verein'">
<NuxtLink
to="/verein/ueber-uns"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Über uns
</NuxtLink>
<NuxtLink
to="/vorstand"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Vorstand
</NuxtLink>
<NuxtLink
to="/verein/geschichte"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Geschichte
</NuxtLink>
<NuxtLink
to="/verein/satzung"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Satzung
</NuxtLink>
<NuxtLink
to="/vereinsmeisterschaften"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Vereinsmeisterschaften
</NuxtLink>
<NuxtLink
to="/verein/galerie"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Galerie
</NuxtLink>
</template>
<!-- Mannschaften Submenu -->
<template v-if="currentSubmenu === 'mannschaften'">
<NuxtLink
to="/mannschaften"
class="px-2.5 py-1 text-xs font-semibold text-white hover:bg-primary-700/50 rounded transition-all"
active-class="bg-primary-600"
>
Übersicht
</NuxtLink>
<div class="h-3 w-px bg-primary-700" />
<template
v-for="mannschaft in mannschaften"
:key="mannschaft.slug"
>
<NuxtLink
:to="`/mannschaften/${mannschaft.slug}`"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
{{ mannschaft.mannschaft }}
</NuxtLink>
</template>
<div class="h-3 w-px bg-primary-700" />
<NuxtLink
to="/mannschaften/spielplaene"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Spielpläne
</NuxtLink>
<NuxtLink
to="/spielsysteme"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Spielsysteme
</NuxtLink>
</template>
<!-- Training Submenu -->
<template v-if="currentSubmenu === 'training'">
<NuxtLink
to="/training"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Trainingszeiten
</NuxtLink>
<NuxtLink
to="/training/trainer"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Trainer
</NuxtLink>
<NuxtLink
to="/training/anfaenger"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Anfänger
</NuxtLink>
<NuxtLink
to="/tt-regeln"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
TT-Regeln
</NuxtLink>
</template>
<!-- Intern Submenu -->
<template v-if="currentSubmenu === 'intern'">
<NuxtLink
to="/mitgliederbereich"
class="px-2.5 py-1 text-xs font-semibold text-white hover:bg-primary-700/50 rounded transition-all"
active-class="bg-primary-600"
>
Übersicht
</NuxtLink>
<div class="h-3 w-px bg-primary-700" />
<NuxtLink
to="/mitgliederbereich/mitglieder"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Mitgliederliste
</NuxtLink>
<NuxtLink
to="/mitgliederbereich/news"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
News
</NuxtLink>
<NuxtLink
to="/mitgliederbereich/profil"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Mein Profil
</NuxtLink>
<div class="h-3 w-px bg-primary-700" />
<NuxtLink
to="/mitgliederbereich/api"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
API-Dokumentation
</NuxtLink>
<template v-if="canAccessNewsletter">
<div class="h-3 w-px bg-primary-700" />
<NuxtLink
to="/cms/newsletter"
class="px-2.5 py-1 text-xs text-gray-300 hover:text-white hover:bg-primary-700/50 rounded transition-all"
active-class="text-white bg-primary-600"
>
Newsletter
</NuxtLink>
</template>
<template v-if="isAdmin">
<div class="h-3 w-px bg-primary-700" />
<div class="relative inline-block">
<button
class="px-2.5 py-1 text-xs text-yellow-300 hover:text-white hover:bg-primary-700/50 rounded transition-all flex items-center"
:class="route.path.startsWith('/cms') ? 'text-white bg-primary-600' : ''"
@click.stop="toggleCmsDropdown"
>
CMS
<ChevronDown
:size="12"
class="ml-1"
:class="['transition-transform', showCmsDropdown ? 'rotate-180' : '']"
/>
</button>
<!-- CMS Dropdown -->
<div
v-if="showCmsDropdown"
class="absolute left-0 top-full mt-1 w-48 bg-gray-800 border border-gray-700 rounded-lg shadow-xl overflow-hidden z-50"
>
<NuxtLink
to="/cms"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="showCmsDropdown = false"
>
Übersicht
</NuxtLink>
<div class="border-t border-gray-700 my-1" />
<NuxtLink
to="/cms/ueber-uns"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="showCmsDropdown = false"
>
Über uns
</NuxtLink>
<NuxtLink
to="/cms/geschichte"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="showCmsDropdown = false"
>
Geschichte
</NuxtLink>
<NuxtLink
to="/cms/tt-regeln"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="showCmsDropdown = false"
>
TT-Regeln
</NuxtLink>
<NuxtLink
to="/cms/satzung"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="showCmsDropdown = false"
>
Satzung
</NuxtLink>
<NuxtLink
to="/cms/vereinsmeisterschaften"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="showCmsDropdown = false"
>
Vereinsmeisterschaften
</NuxtLink>
<div class="border-t border-gray-700 my-1" />
<NuxtLink
to="/mitgliederbereich/news"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="showCmsDropdown = false"
>
News
</NuxtLink>
<NuxtLink
to="/cms/termine"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="showCmsDropdown = false"
>
Termine
</NuxtLink>
<NuxtLink
to="/cms/spielplaene"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="showCmsDropdown = false"
>
Spielpläne
</NuxtLink>
<NuxtLink
to="/mitgliederbereich/mitglieder"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="showCmsDropdown = false"
>
Mitglieder
</NuxtLink>
<div class="border-t border-gray-700 my-1" />
<NuxtLink
to="/cms/einstellungen"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="showCmsDropdown = false"
>
Einstellungen
</NuxtLink>
<NuxtLink
to="/cms/mitgliedschaftsantraege"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="showCmsDropdown = false"
>
Mitgliedschaftsanträge
</NuxtLink>
<NuxtLink
to="/cms/benutzer"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="showCmsDropdown = false"
>
Benutzerverwaltung
</NuxtLink>
</div>
</div>
</template>
</template>
</div>
</div>
<!-- Mobile Menu Button -->
<button
class="lg:hidden p-2 rounded-lg hover:bg-primary-700/50 transition-colors"
aria-label="Toggle menu"
@click="isMobileMenuOpen = !isMobileMenuOpen"
>
<X
v-if="isMobileMenuOpen"
:size="24"
class="text-white"
/>
<Menu
v-else
:size="24"
class="text-white"
/>
</button>
</div>
<!-- Untermenü (Desktop) - im gleichen Block, immer gleiche Höhe -->
</div>
</div>
</div>
<!-- Mobile Menu -->
<Transition
enter-active-class="transition duration-200 ease-out"
enter-from-class="opacity-0 transform -translate-y-2"
enter-to-class="opacity-100 transform translate-y-0"
leave-active-class="transition duration-150 ease-in"
leave-from-class="opacity-100 transform translate-y-0"
leave-to-class="opacity-0 transform -translate-y-2"
>
<div
v-if="isMobileMenuOpen"
class="lg:hidden bg-gray-800 border-t border-primary-700/30 max-h-[80vh] overflow-y-auto"
>
<div class="px-4 py-4 space-y-2">
<NuxtLink
to="/"
class="block px-4 py-3 text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg font-medium transition-colors"
@click="isMobileMenuOpen = false"
>
Start
</NuxtLink>
<!-- Verein Mobile -->
<div>
<button
class="w-full flex items-center justify-between px-4 py-3 text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg font-medium transition-colors"
@click="toggleMobileSubmenu('verein')"
>
Verein
<ChevronDown
:size="16"
:class="['transition-transform', mobileSubmenu === 'verein' ? 'rotate-180' : '']"
/>
</button>
<div
v-if="mobileSubmenu === 'verein'"
class="pl-4 space-y-1 mt-1 bg-primary-900/30 rounded-lg p-2"
>
<NuxtLink
to="/verein/ueber-uns"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Über uns
</NuxtLink>
<NuxtLink
to="/vorstand"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Vorstand
</NuxtLink>
<NuxtLink
to="/verein/geschichte"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Geschichte
</NuxtLink>
<NuxtLink
to="/verein/satzung"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Satzung
</NuxtLink>
<NuxtLink
to="/vereinsmeisterschaften"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Vereinsmeisterschaften
</NuxtLink>
<NuxtLink
to="/verein/galerie"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Galerie
</NuxtLink>
<NuxtLink
to="/newsletter/subscribe"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Newsletter abonnieren
</NuxtLink>
<NuxtLink
to="/newsletter/unsubscribe"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Newsletter abmelden
</NuxtLink>
</div>
</div>
<!-- Mannschaften Mobile -->
<div>
<button
class="w-full flex items-center justify-between px-4 py-3 text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg font-medium transition-colors"
@click="toggleMobileSubmenu('mannschaften')"
>
Mannschaften
<ChevronDown
:size="16"
:class="['transition-transform', mobileSubmenu === 'mannschaften' ? 'rotate-180' : '']"
/>
</button>
<div
v-if="mobileSubmenu === 'mannschaften'"
class="pl-4 space-y-1 mt-1 bg-primary-900/30 rounded-lg p-2"
>
<NuxtLink
to="/mannschaften"
class="block px-4 py-2 text-sm font-semibold text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Übersicht
</NuxtLink>
<template
v-for="mannschaft in mannschaften"
:key="mannschaft.slug"
>
<NuxtLink
:to="`/mannschaften/${mannschaft.slug}`"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
{{ mannschaft.mannschaft }}
</NuxtLink>
</template>
<div class="border-t border-primary-700/20 my-2" />
<NuxtLink
to="/mannschaften/spielplaene"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Spielpläne
</NuxtLink>
<NuxtLink
to="/spielsysteme"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Spielsysteme
</NuxtLink>
</div>
</div>
<!-- Training Mobile -->
<div>
<button
class="w-full flex items-center justify-between px-4 py-3 text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg font-medium transition-colors"
@click="toggleMobileSubmenu('training')"
>
Training
<ChevronDown
:size="16"
:class="['transition-transform', mobileSubmenu === 'training' ? 'rotate-180' : '']"
/>
</button>
<div
v-if="mobileSubmenu === 'training'"
class="pl-4 space-y-1 mt-1 bg-primary-900/30 rounded-lg p-2"
>
<NuxtLink
to="/training"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Trainingszeiten
</NuxtLink>
<NuxtLink
to="/training/trainer"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Trainer
</NuxtLink>
<NuxtLink
to="/training/anfaenger"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Anfänger
</NuxtLink>
<NuxtLink
to="/tt-regeln"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
TT-Regeln
</NuxtLink>
</div>
</div>
<NuxtLink
to="/mitgliedschaft"
class="block px-4 py-3 text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg font-medium transition-colors"
@click="isMobileMenuOpen = false"
>
Mitgliedschaft
</NuxtLink>
<NuxtLink
to="/termine"
class="block px-4 py-3 text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg font-medium transition-colors"
@click="isMobileMenuOpen = false"
>
Termine
</NuxtLink>
<NuxtLink
v-if="hasGalleryImages"
to="/verein/galerie"
class="block px-4 py-3 text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg font-medium transition-colors"
@click="isMobileMenuOpen = false"
>
Galerie
</NuxtLink>
<NuxtLink
to="/newsletter/subscribe"
class="block px-4 py-3 text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg font-medium transition-colors"
@click="isMobileMenuOpen = false"
>
Newsletter abonnieren
</NuxtLink>
<NuxtLink
to="/newsletter/unsubscribe"
class="block px-4 py-3 text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg font-medium transition-colors"
@click="isMobileMenuOpen = false"
>
Newsletter abmelden
</NuxtLink>
<!-- Intern Mobile -->
<div v-if="isLoggedIn">
<button
class="w-full flex items-center justify-between px-4 py-3 text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg font-medium transition-colors"
@click="toggleMobileSubmenu('intern')"
>
Intern
<ChevronDown
:size="16"
:class="['transition-transform', mobileSubmenu === 'intern' ? 'rotate-180' : '']"
/>
</button>
<div
v-if="mobileSubmenu === 'intern'"
class="pl-4 space-y-1 mt-1 bg-primary-900/30 rounded-lg p-2"
>
<NuxtLink
to="/mitgliederbereich"
class="block px-4 py-2 text-sm font-semibold text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Übersicht
</NuxtLink>
<NuxtLink
to="/mitgliederbereich/mitglieder"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Mitgliederliste
</NuxtLink>
<NuxtLink
to="/mitgliederbereich/news"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
News
</NuxtLink>
<NuxtLink
to="/mitgliederbereich/profil"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Mein Profil
</NuxtLink>
<template v-if="canAccessNewsletter">
<div class="border-t border-primary-700/20 my-2" />
<NuxtLink
to="/cms/newsletter"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Newsletter
</NuxtLink>
</template>
<template v-if="isAdmin">
<div class="border-t border-primary-700/20 my-2" />
<NuxtLink
to="/cms"
class="block px-4 py-2 text-sm font-semibold text-yellow-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
CMS Übersicht
</NuxtLink>
<NuxtLink
to="/mitgliederbereich/news"
class="block px-4 py-2 text-sm text-yellow-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
News
</NuxtLink>
<NuxtLink
to="/cms/termine"
class="block px-4 py-2 text-sm text-yellow-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Termine
</NuxtLink>
<NuxtLink
to="/cms/spielplaene"
class="block px-4 py-2 text-sm text-yellow-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Spielpläne
</NuxtLink>
<NuxtLink
to="/mitgliederbereich/mitglieder"
class="block px-4 py-2 text-sm text-yellow-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Mitglieder
</NuxtLink>
<NuxtLink
to="/cms/ueber-uns"
class="block px-4 py-2 text-sm text-yellow-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Über uns
</NuxtLink>
<NuxtLink
to="/cms/geschichte"
class="block px-4 py-2 text-sm text-yellow-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Geschichte
</NuxtLink>
<NuxtLink
to="/cms/tt-regeln"
class="block px-4 py-2 text-sm text-yellow-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
TT-Regeln
</NuxtLink>
<NuxtLink
to="/cms/satzung"
class="block px-4 py-2 text-sm text-yellow-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Satzung
</NuxtLink>
<NuxtLink
to="/cms/vereinsmeisterschaften"
class="block px-4 py-2 text-sm text-yellow-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Vereinsmeisterschaften
</NuxtLink>
<NuxtLink
to="/cms/einstellungen"
class="block px-4 py-2 text-sm text-yellow-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Einstellungen
</NuxtLink>
<NuxtLink
to="/cms/mitgliedschaftsantraege"
class="block px-4 py-2 text-sm text-yellow-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Mitgliedschaftsanträge
</NuxtLink>
<NuxtLink
to="/cms/benutzer"
class="block px-4 py-2 text-sm text-yellow-300 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors"
@click="isMobileMenuOpen = false"
>
Benutzerverwaltung
</NuxtLink>
</template>
</div>
</div>
<NuxtLink
to="/kontakt"
class="block px-4 py-3 bg-primary-600 hover:bg-primary-700 text-white rounded-lg font-semibold transition-colors"
@click="isMobileMenuOpen = false"
>
Kontakt
</NuxtLink>
</div>
</div>
</Transition>
</nav>
</template>
<script setup>
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { useRoute } from 'vue-router'
import { Menu, X, ChevronDown } from 'lucide-vue-next'
const route = useRoute()
const authStore = useAuthStore()
const isMobileMenuOpen = ref(false)
const mobileSubmenu = ref(null)
const mannschaften = ref([])
const hasGalleryImages = ref(false)
const showCmsDropdown = ref(false)
// Reactive auth state from store
const isLoggedIn = computed(() => authStore.isLoggedIn)
const isAdmin = computed(() => authStore.isAdmin)
const canAccessNewsletter = computed(() => authStore.hasAnyRole('admin', 'vorstand', 'newsletter'))
// Automatisches Setzen des Submenus basierend auf der Route
const currentSubmenu = computed(() => {
const path = route.path
if (path.startsWith('/verein/') || path.startsWith('/vorstand') ||
path.startsWith('/vereinsmeisterschaften')) {
return 'verein'
}
if (path.startsWith('/mannschaften') || path.startsWith('/spielsysteme')) {
return 'mannschaften'
}
if (path.startsWith('/training') || path.startsWith('/tt-regeln')) {
return 'training'
}
if (path.startsWith('/mitgliederbereich') || path.startsWith('/cms')) {
return 'intern'
}
if (path.startsWith('/newsletter')) {
return 'newsletter'
}
return null
})
const toggleMobileSubmenu = (menu) => {
mobileSubmenu.value = mobileSubmenu.value === menu ? null : menu
}
const loadMannschaften = async () => {
try {
const response = await fetch('/data/mannschaften.csv')
if (!response.ok) return
const csv = await response.text()
const lines = csv.split('\n').filter(line => line.trim() !== '')
if (lines.length < 2) return
mannschaften.value = lines.slice(1).map(line => {
// Besserer CSV-Parser: Respektiert Anführungszeichen
const values = []
let current = ''
let inQuotes = false
for (let i = 0; i < line.length; i++) {
const char = line[i]
if (char === '"') {
inQuotes = !inQuotes
} else if (char === ',' && !inQuotes) {
values.push(current.trim())
current = ''
} else {
current += char
}
}
values.push(current.trim())
if (!values[0]) return null
return {
mannschaft: values[0].trim(),
slug: values[0].trim().toLowerCase().replace(/\s+/g, '-')
}
}).filter(mannschaft => mannschaft !== null)
} catch (error) {
console.error('Fehler beim Laden der Mannschaften:', error)
}
}
const checkGalleryImages = async () => {
try {
const response = await $fetch('/api/galerie')
hasGalleryImages.value = response && response.length > 0
} catch (error) {
console.error('Fehler beim Prüfen der Galerie-Bilder:', error)
hasGalleryImages.value = false
}
}
const toggleCmsDropdown = () => {
showCmsDropdown.value = !showCmsDropdown.value
}
const handleDocumentClick = (e) => {
if (!e.target.closest('.relative.inline-block')) {
showCmsDropdown.value = false
}
}
onMounted(() => {
loadMannschaften()
checkGalleryImages()
authStore.checkAuth()
// Close CMS dropdown when clicking outside
document.addEventListener('click', handleDocumentClick)
})
onUnmounted(() => {
document.removeEventListener('click', handleDocumentClick)
})
const toggleSubmenu = (menu) => {
// Wenn wir schon im richtigen Bereich sind, nichts tun (Submenu bleibt offen)
// Wenn nicht, zur Hauptseite navigieren
const path = route.path
if (menu === 'newsletter' && !path.startsWith('/newsletter')) {
navigateTo('/newsletter/subscribe')
} else if (menu === 'verein' && !path.startsWith('/verein/') && !path.startsWith('/vorstand') && !path.startsWith('/vereinsmeisterschaften')) {
navigateTo('/verein/ueber-uns')
} else if (menu === 'mannschaften' && !path.startsWith('/mannschaften') && !path.startsWith('/spielsysteme')) {
navigateTo('/mannschaften')
} else if (menu === 'training' && !path.startsWith('/training') && !path.startsWith('/tt-regeln')) {
navigateTo('/training')
} else if (menu === 'intern' && !path.startsWith('/mitgliederbereich') && !path.startsWith('/cms')) {
navigateTo('/mitgliederbereich')
}
}
</script>