Files
harheimertc/components/Navigation.vue
Torsten Schulz (local) ee6b031c7b
Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 47s
Add Mannschaften link to Navigation and CMS index
This commit introduces a new link to the "Mannschaften" section in both the Navigation.vue and cms/index.vue components. The addition enhances navigation options for users, allowing easier access to manage and edit teams. The new link is styled consistently with existing navigation elements, improving the overall user experience.
2026-01-17 18:39:14 +01:00

1020 lines
42 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 || canAccessNewsletter"
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/mannschaften"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="showCmsDropdown = false"
>
Mannschaften
</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 || canAccessNewsletter"
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/mannschaften"
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"
>
Mannschaften
</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 isMobileMenuOpen = ref(false)
const mobileSubmenu = ref(null)
const mannschaften = ref([])
const hasGalleryImages = ref(false)
const showCmsDropdown = ref(false)
// Lazy store access to avoid Pinia initialization issues
const getAuthStore = () => {
try {
return useAuthStore()
} catch (e) {
// Fallback if Pinia is not yet initialized
return null
}
}
// Reactive auth state from store (lazy)
const isLoggedIn = computed(() => {
const store = getAuthStore()
return store?.isLoggedIn ?? false
})
const isAdmin = computed(() => {
const store = getAuthStore()
return store?.isAdmin ?? false
})
const canAccessNewsletter = computed(() => {
const store = getAuthStore()
return store?.hasAnyRole('admin', 'vorstand', 'newsletter') ?? false
})
// 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()
const store = getAuthStore()
if (store) {
store.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>