feat: add global event listener for mannschaften updates in Navigation component feat: notify app of mannschaften changes after CSV save and handle visibility changes refactor: remove unused anlagen page fix: update CmsMannschaften reference in sportbetrieb page for reactivity fix: enhance authentication token retrieval in passkey API endpoints feat: implement refresh session and access token generation for Android clients in passkey login fix: unify token retrieval method across passkey API endpoints feat: add MediaTypes utility for JSON content type in Android app feat: create PasskeyRepository for handling passkey authentication and registration in Android app feat: add validated text field and rich text components for Android UI feat: implement newsletter subscription and unsubscription screens in Android app feat: create public pages including Impressum with dynamic content loading
73 lines
2.1 KiB
Vue
73 lines
2.1 KiB
Vue
<template>
|
||
<div class="min-h-screen bg-gray-50">
|
||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||
<div class="mb-6">
|
||
<h1 class="text-3xl font-display font-bold text-gray-900">
|
||
Sportbetrieb verwalten
|
||
</h1>
|
||
<p class="mt-1 text-sm text-gray-500">
|
||
Termine, Mannschaften und Spielpläne pflegen
|
||
</p>
|
||
</div>
|
||
|
||
<!-- Tabs -->
|
||
<div class="border-b border-gray-200 mb-6">
|
||
<nav
|
||
class="-mb-px flex space-x-8 overflow-x-auto"
|
||
aria-label="Tabs"
|
||
>
|
||
<button
|
||
v-for="tab in tabs"
|
||
:key="tab.id"
|
||
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm transition-colors"
|
||
:class="activeTab === tab.id
|
||
? 'border-primary-600 text-primary-600'
|
||
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'"
|
||
@click="activeTab = tab.id"
|
||
>
|
||
{{ tab.label }}
|
||
</button>
|
||
</nav>
|
||
</div>
|
||
|
||
<!-- Tab Content -->
|
||
<div>
|
||
<CmsTermine v-if="activeTab === 'termine'" />
|
||
<CmsMannschaften ref="cmsMannschaftenRef" v-if="activeTab === 'mannschaften'" />
|
||
<CmsSpielplaene v-if="activeTab === 'spielplaene'" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, watch } from 'vue'
|
||
import CmsTermine from '~/components/cms/CmsTermine.vue'
|
||
import CmsMannschaften from '~/components/cms/CmsMannschaften.vue'
|
||
import CmsSpielplaene from '~/components/cms/CmsSpielplaene.vue'
|
||
|
||
definePageMeta({
|
||
middleware: 'auth',
|
||
layout: 'default'
|
||
})
|
||
|
||
useHead({
|
||
title: 'Sportbetrieb verwalten – CMS'
|
||
})
|
||
|
||
const activeTab = ref('termine')
|
||
const cmsMannschaftenRef = ref(null)
|
||
|
||
watch(activeTab, (v) => {
|
||
if (v === 'mannschaften' && cmsMannschaftenRef?.value?.loadMannschaften) {
|
||
try { cmsMannschaftenRef.value.loadMannschaften() } catch (e) { /* no-op */ }
|
||
}
|
||
})
|
||
|
||
const tabs = [
|
||
{ id: 'termine', label: 'Termine' },
|
||
{ id: 'mannschaften', label: 'Mannschaften' },
|
||
{ id: 'spielplaene', label: 'Spielpläne' }
|
||
]
|
||
</script>
|