Update dependencies to include TinyMCE and Quill, enhance Navigation component with a new Newsletter submenu, and implement role-based access control for CMS features. Refactor user role handling to support multiple roles and improve user management functionality across various API endpoints.

This commit is contained in:
Torsten Schulz (local)
2025-12-19 09:51:28 +01:00
parent baf6c59c0d
commit 435e28fd55
69 changed files with 5034 additions and 276 deletions

View File

@@ -53,11 +53,17 @@
Termine
</NuxtLink>
<NuxtLink v-if="hasGalleryImages" to="/galerie" @click="currentSubmenu = null"
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">
Galerie
</NuxtLink>
<NuxtLink v-if="hasGalleryImages" to="/verein/galerie" @click="currentSubmenu = null"
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">
Galerie
</NuxtLink>
<button @click="toggleSubmenu('newsletter')"
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' : ''">
Newsletter
</button>
<button v-if="isLoggedIn" @click="toggleSubmenu('intern')"
class="px-4 py-2 text-gray-300 hover:text-white font-medium transition-all rounded-lg hover:bg-primary-700/50"
@@ -73,6 +79,19 @@
<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"
@@ -188,6 +207,14 @@
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">
@@ -323,6 +350,14 @@
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors">
Galerie
</NuxtLink>
<NuxtLink to="/newsletter/subscribe" @click="isMobileMenuOpen = false"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors">
Newsletter abonnieren
</NuxtLink>
<NuxtLink to="/newsletter/unsubscribe" @click="isMobileMenuOpen = false"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors">
Newsletter abmelden
</NuxtLink>
</div>
</div>
@@ -395,10 +430,18 @@
Termine
</NuxtLink>
<NuxtLink v-if="hasGalleryImages" to="/galerie" @click="isMobileMenuOpen = false"
<NuxtLink v-if="hasGalleryImages" to="/verein/galerie" @click="isMobileMenuOpen = false"
class="block px-4 py-3 text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg font-medium transition-colors">
Galerie
</NuxtLink>
<NuxtLink to="/newsletter/subscribe" @click="isMobileMenuOpen = false"
class="block px-4 py-3 text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg font-medium transition-colors">
Newsletter abonnieren
</NuxtLink>
<NuxtLink to="/newsletter/unsubscribe" @click="isMobileMenuOpen = false"
class="block px-4 py-3 text-gray-300 hover:text-white hover:bg-primary-700/50 rounded-lg font-medium transition-colors">
Newsletter abmelden
</NuxtLink>
<!-- Intern Mobile -->
<div v-if="isLoggedIn">
@@ -425,6 +468,13 @@
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors">
Mein Profil
</NuxtLink>
<template v-if="canAccessNewsletter">
<div class="border-t border-primary-700/20 my-2" />
<NuxtLink to="/cms/newsletter" @click="isMobileMenuOpen = false"
class="block px-4 py-2 text-sm text-gray-400 hover:text-white hover:bg-primary-700/50 rounded-lg transition-colors">
Newsletter
</NuxtLink>
</template>
<template v-if="isAdmin">
<div class="border-t border-primary-700/20 my-2" />
<NuxtLink to="/cms" @click="isMobileMenuOpen = false"
@@ -509,6 +559,7 @@ 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(() => {
@@ -526,6 +577,9 @@ const currentSubmenu = computed(() => {
if (path.startsWith('/mitgliederbereich') || path.startsWith('/cms')) {
return 'intern'
}
if (path.startsWith('/newsletter')) {
return 'newsletter'
}
return null
})
@@ -613,7 +667,9 @@ const toggleSubmenu = (menu) => {
// Wenn nicht, zur Hauptseite navigieren
const path = route.path
if (menu === 'verein' && !path.startsWith('/verein/') && !path.startsWith('/vorstand') && !path.startsWith('/vereinsmeisterschaften')) {
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')