Update package-lock.json and package.json to include 'globals' dependency and improve code formatting in various components for better readability.
Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 54s

This commit is contained in:
Torsten Schulz (local)
2025-12-20 10:17:16 +01:00
parent 861802b716
commit b20b89d333
72 changed files with 5338 additions and 2008 deletions

View File

@@ -1,5 +1,8 @@
<template>
<section id="about" class="py-16 sm:py-20 bg-gradient-to-b from-white to-gray-50">
<section
id="about"
class="py-16 sm:py-20 bg-gradient-to-b from-white to-gray-50"
>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center mb-16">
<h2 class="text-4xl sm:text-5xl font-display font-bold text-gray-900 mb-4">
@@ -36,7 +39,9 @@
Jährlich finden außerdem unsere Vereinsmeisterschaften statt.
</p>
<div class="bg-primary-50 border-l-4 border-primary-600 p-6 rounded-lg">
<h4 class="text-xl font-semibold text-primary-800 mb-3">Wir suchen Verstärkung!</h4>
<h4 class="text-xl font-semibold text-primary-800 mb-3">
Wir suchen Verstärkung!
</h4>
<p class="text-primary-700 mb-4">
Wir suchen ständig Verstärkungen für unsere Mannschaften!
</p>
@@ -63,7 +68,11 @@
class="bg-white p-6 rounded-xl shadow-lg hover:shadow-xl transition-shadow border border-gray-100"
>
<div class="w-12 h-12 bg-primary-100 rounded-lg flex items-center justify-center mb-4">
<component :is="value.icon" :size="24" class="text-primary-600" />
<component
:is="value.icon"
:size="24"
class="text-primary-600"
/>
</div>
<h4 class="text-xl font-display font-bold text-gray-900 mb-2">
{{ value.title }}

View File

@@ -1,5 +1,8 @@
<template>
<section id="calendar" class="py-16 sm:py-20 bg-white">
<section
id="calendar"
class="py-16 sm:py-20 bg-white"
>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center mb-16">
<h2 class="text-4xl sm:text-5xl font-display font-bold text-gray-900 mb-4">
@@ -28,7 +31,11 @@
<div class="bg-white rounded-2xl shadow-lg hover:shadow-2xl transition-shadow p-6 border border-gray-100">
<div class="flex items-start space-x-4">
<div :class="['flex-shrink-0 w-14 h-14 bg-gradient-to-br rounded-xl flex items-center justify-center', event.color]">
<component :is="event.icon" :size="28" class="text-white" />
<component
:is="event.icon"
:size="28"
class="text-white"
/>
</div>
<div class="flex-1">
<div class="text-sm font-semibold text-primary-600 mb-1">
@@ -57,7 +64,10 @@
<div class="mt-16 text-center">
<div class="bg-gray-50 rounded-2xl p-8 max-w-2xl mx-auto">
<CalendarIcon :size="48" class="text-primary-600 mx-auto mb-4" />
<CalendarIcon
:size="48"
class="text-primary-600 mx-auto mb-4"
/>
<h3 class="text-2xl font-display font-bold text-gray-900 mb-3">
Regelmäßige Angebote
</h3>

View File

@@ -1,5 +1,8 @@
<template>
<section id="contact" class="py-16 sm:py-20 bg-white">
<section
id="contact"
class="py-16 sm:py-20 bg-white"
>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center mb-16">
<h2 class="text-4xl sm:text-5xl font-display font-bold text-gray-900 mb-4">
@@ -20,13 +23,21 @@
class="flex items-start space-x-4 bg-gray-50 p-6 rounded-xl hover:shadow-lg transition-shadow"
>
<div :class="['flex-shrink-0 w-12 h-12 bg-gradient-to-br rounded-lg flex items-center justify-center', info.color]">
<component :is="info.icon" :size="24" class="text-white" />
<component
:is="info.icon"
:size="24"
class="text-white"
/>
</div>
<div>
<h3 class="font-display font-bold text-gray-900 mb-2">
{{ info.title }}
</h3>
<p v-for="(line, i) in info.content" :key="i" class="text-gray-600">
<p
v-for="(line, i) in info.content"
:key="i"
class="text-gray-600"
>
{{ line }}
</p>
</div>
@@ -61,60 +72,78 @@
<h3 class="text-2xl font-display font-bold text-gray-900 mb-6">
Senden Sie uns eine Nachricht
</h3>
<form class="space-y-4" @submit.prevent="sendEmail">
<form
class="space-y-4"
@submit.prevent="sendEmail"
>
<div>
<label for="name" class="block text-sm font-medium text-gray-700 mb-1">
<label
for="name"
class="block text-sm font-medium text-gray-700 mb-1"
>
Name *
</label>
<input
type="text"
id="name"
v-model="formData.name"
type="text"
required
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-all"
placeholder="Ihr Name"
/>
>
</div>
<div>
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">
<label
for="email"
class="block text-sm font-medium text-gray-700 mb-1"
>
E-Mail *
</label>
<input
type="email"
id="email"
v-model="formData.email"
type="email"
required
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-all"
placeholder="ihre@email.de"
/>
>
</div>
<div>
<label for="phone" class="block text-sm font-medium text-gray-700 mb-1">
<label
for="phone"
class="block text-sm font-medium text-gray-700 mb-1"
>
Telefon
</label>
<input
type="tel"
id="phone"
v-model="formData.phone"
type="tel"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-all"
placeholder="+49 123 456789"
/>
>
</div>
<div>
<label for="subject" class="block text-sm font-medium text-gray-700 mb-1">
<label
for="subject"
class="block text-sm font-medium text-gray-700 mb-1"
>
Betreff *
</label>
<input
type="text"
id="subject"
v-model="formData.subject"
type="text"
required
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-all"
placeholder="Worum geht es?"
/>
>
</div>
<div>
<label for="message" class="block text-sm font-medium text-gray-700 mb-1">
<label
for="message"
class="block text-sm font-medium text-gray-700 mb-1"
>
Nachricht *
</label>
<textarea
@@ -127,11 +156,26 @@
/>
</div>
<!-- Status Message -->
<div v-if="submitStatus" class="p-4 rounded-lg" :class="submitStatus === 'success' ? 'bg-green-50 border border-green-200' : 'bg-red-50 border border-red-200'">
<div
v-if="submitStatus"
class="p-4 rounded-lg"
:class="submitStatus === 'success' ? 'bg-green-50 border border-green-200' : 'bg-red-50 border border-red-200'"
>
<div class="flex items-center">
<CheckCircle v-if="submitStatus === 'success'" :size="20" class="text-green-600 mr-2" />
<AlertCircle v-else :size="20" class="text-red-600 mr-2" />
<p :class="submitStatus === 'success' ? 'text-green-800' : 'text-red-800'" class="text-sm font-medium">
<CheckCircle
v-if="submitStatus === 'success'"
:size="20"
class="text-green-600 mr-2"
/>
<AlertCircle
v-else
:size="20"
class="text-red-600 mr-2"
/>
<p
:class="submitStatus === 'success' ? 'text-green-800' : 'text-red-800'"
class="text-sm font-medium"
>
{{ submitMessage }}
</p>
</div>
@@ -142,8 +186,15 @@
:disabled="isSubmitting"
class="w-full px-6 py-4 bg-primary-600 hover:bg-primary-700 disabled:bg-gray-400 disabled:cursor-not-allowed text-white font-semibold rounded-lg shadow-lg hover:shadow-xl transition-all duration-300 flex items-center justify-center"
>
<Send v-if="!isSubmitting" :size="20" class="mr-2" />
<div v-else class="animate-spin rounded-full h-5 w-5 border-b-2 border-white mr-2"></div>
<Send
v-if="!isSubmitting"
:size="20"
class="mr-2"
/>
<div
v-else
class="animate-spin rounded-full h-5 w-5 border-b-2 border-white mr-2"
/>
{{ isSubmitting ? 'Wird gesendet...' : 'E-Mail senden' }}
</button>
<p class="text-sm text-gray-600 text-center">

View File

@@ -1,5 +1,8 @@
<template>
<section id="facilities" class="py-16 sm:py-20 bg-white">
<section
id="facilities"
class="py-16 sm:py-20 bg-white"
>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center mb-16">
<h2 class="text-4xl sm:text-5xl font-display font-bold text-gray-900 mb-4">
@@ -20,7 +23,11 @@
<div :class="['absolute top-0 left-0 right-0 h-1 bg-gradient-to-r opacity-0 group-hover:opacity-100 transition-opacity', facility.color]" />
<div class="p-8">
<div :class="['w-16 h-16 bg-gradient-to-br rounded-xl flex items-center justify-center mb-4 group-hover:scale-110 transition-transform', facility.color]">
<component :is="facility.icon" :size="32" class="text-white" />
<component
:is="facility.icon"
:size="32"
class="text-white"
/>
</div>
<h3 class="text-2xl font-display font-bold text-gray-900 mb-3">
{{ facility.title }}
@@ -40,7 +47,9 @@
style="background-image: url('https://images.unsplash.com/photo-1534438097545-77fef53fe2e8?q=80&w=2070')"
/>
<div class="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent flex items-end">
<p class="text-white font-semibold text-xl p-6">Hochwertige Wettkampftische</p>
<p class="text-white font-semibold text-xl p-6">
Hochwertige Wettkampftische
</p>
</div>
</div>
<div class="relative h-[300px] rounded-2xl overflow-hidden shadow-xl group">
@@ -49,7 +58,9 @@
style="background-image: url('https://images.unsplash.com/photo-1611004275469-8583ed5d7b8d?q=80&w=2070')"
/>
<div class="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent flex items-end">
<p class="text-white font-semibold text-xl p-6">Moderne Tischtennishalle</p>
<p class="text-white font-semibold text-xl p-6">
Moderne Tischtennishalle
</p>
</div>
</div>
</div>

View File

@@ -6,31 +6,43 @@
© {{ currentYear }} Harheimer TC 1954 e.V.
</p>
<div class="flex items-center space-x-6 text-sm relative">
<NuxtLink to="/impressum" class="text-gray-400 hover:text-primary-400 transition-colors">
<NuxtLink
to="/impressum"
class="text-gray-400 hover:text-primary-400 transition-colors"
>
Impressum
</NuxtLink>
<NuxtLink to="/kontakt" class="text-gray-400 hover:text-primary-400 transition-colors">
<NuxtLink
to="/kontakt"
class="text-gray-400 hover:text-primary-400 transition-colors"
>
Kontakt
</NuxtLink>
<!-- Login/Logout -->
<template v-if="isLoggedIn">
<button
@click="handleLogout"
class="flex items-center space-x-1 text-gray-400 hover:text-primary-400 transition-colors"
@click="handleLogout"
>
<User :size="16" />
<span>Abmelden</span>
</button>
</template>
<div v-else class="relative">
<div
v-else
class="relative"
>
<button
@click="toggleMemberMenu"
class="flex items-center space-x-1 text-gray-400 hover:text-primary-400 transition-colors"
@click="toggleMemberMenu"
>
<User :size="16" />
<span>Mitglieder</span>
<ChevronUp :size="14" :class="['transition-transform', isMemberMenuOpen ? 'rotate-0' : 'rotate-180']" />
<ChevronUp
:size="14"
:class="['transition-transform', isMemberMenuOpen ? 'rotate-0' : 'rotate-180']"
/>
</button>
<!-- Dropdown Menu (appears above) - Only when NOT logged in -->
@@ -48,22 +60,22 @@
>
<NuxtLink
to="/login"
@click="isMemberMenuOpen = false"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="isMemberMenuOpen = false"
>
Anmelden
</NuxtLink>
<NuxtLink
to="/registrieren"
@click="isMemberMenuOpen = false"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="isMemberMenuOpen = false"
>
Registrieren
</NuxtLink>
<NuxtLink
to="/passwort-vergessen"
@click="isMemberMenuOpen = false"
class="block px-4 py-2 text-sm text-gray-300 hover:bg-primary-600 hover:text-white transition-colors"
@click="isMemberMenuOpen = false"
>
Passwort vergessen
</NuxtLink>

View File

@@ -1,5 +1,9 @@
<template>
<section v-if="images.length > 0" id="gallery" class="py-16 sm:py-20 bg-gradient-to-b from-white to-gray-50">
<section
v-if="images.length > 0"
id="gallery"
class="py-16 sm:py-20 bg-gradient-to-b from-white to-gray-50"
>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center mb-16">
<h2 class="text-4xl sm:text-5xl font-display font-bold text-gray-900 mb-4">
@@ -22,9 +26,11 @@
:src="`/galerie/${image.filename}`"
:alt="image.title"
class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700"
/>
>
<div class="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-end">
<p class="text-white font-semibold text-xs p-1 truncate">{{ image.title }}</p>
<p class="text-white font-semibold text-xs p-1 truncate">
{{ image.title }}
</p>
</div>
</div>
</div>
@@ -37,8 +43,8 @@
>
<div class="relative w-full h-full flex items-center justify-center">
<button
@click.stop="closeLightbox"
class="absolute top-4 right-4 z-10 w-10 h-10 bg-white/20 hover:bg-white/30 rounded-full flex items-center justify-center text-white transition-colors"
@click.stop="closeLightbox"
>
<X :size="24" />
</button>
@@ -47,7 +53,7 @@
:alt="lightboxImage.title"
class="max-w-[80vw] max-h-[80vh] object-contain rounded-lg"
@click.stop
/>
>
<div class="absolute bottom-4 left-4 right-4 text-center">
<p class="text-white font-semibold text-lg bg-black/50 rounded-lg px-4 py-2">
{{ lightboxImage.title }}

View File

@@ -1,5 +1,8 @@
<template>
<section id="home" class="relative min-h-full flex items-center justify-center overflow-hidden bg-gradient-to-br from-gray-50 to-gray-100">
<section
id="home"
class="relative min-h-full flex items-center justify-center overflow-hidden bg-gradient-to-br from-gray-50 to-gray-100"
>
<!-- Decorative Elements -->
<div class="absolute inset-0 z-0">
<div class="absolute top-0 right-0 w-96 h-96 bg-primary-200/30 rounded-full blur-3xl" />
@@ -15,14 +18,13 @@
<div class="relative z-20 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20 sm:py-8">
<div class="text-center">
<h1 class="text-5xl sm:text-6xl lg:text-7xl font-display font-bold text-gray-900 mb-6 leading-tight animate-fade-in">
Willkommen beim<br />
Willkommen beim<br>
<span class="text-primary-600">Harheimer TC</span>
</h1>
<p class="text-xl sm:text-2xl text-gray-700 mb-8 max-w-3xl mx-auto animate-fade-in-delay-1">
Tradition trifft Moderne - Ihr Tischtennisverein in Frankfurt-Harheim seit {{ yearsSinceFounding }} Jahren
</p>
</div>
</div>
</section>

View File

@@ -9,7 +9,10 @@
>
<div class="flex items-center mb-4">
<div class="w-16 h-16 bg-primary-100 rounded-xl flex items-center justify-center group-hover:bg-primary-600 transition-colors">
<UserPlus :size="32" class="text-primary-600 group-hover:text-white transition-colors" />
<UserPlus
:size="32"
class="text-primary-600 group-hover:text-white transition-colors"
/>
</div>
<h3 class="ml-4 text-2xl font-display font-bold text-gray-900">
Mitglied werden
@@ -21,7 +24,10 @@
</p>
<div class="flex items-center text-primary-600 font-semibold group-hover:translate-x-2 transition-transform">
Mehr erfahren
<ArrowRight :size="20" class="ml-2" />
<ArrowRight
:size="20"
class="ml-2"
/>
</div>
</NuxtLink>
@@ -32,7 +38,10 @@
>
<div class="flex items-center mb-4">
<div class="w-16 h-16 bg-primary-100 rounded-xl flex items-center justify-center group-hover:bg-primary-600 transition-colors">
<Mail :size="32" class="text-primary-600 group-hover:text-white transition-colors" />
<Mail
:size="32"
class="text-primary-600 group-hover:text-white transition-colors"
/>
</div>
<h3 class="ml-4 text-2xl font-display font-bold text-gray-900">
Kontakt aufnehmen
@@ -44,7 +53,10 @@
</p>
<div class="flex items-center text-primary-600 font-semibold group-hover:translate-x-2 transition-transform">
Jetzt kontaktieren
<ArrowRight :size="20" class="ml-2" />
<ArrowRight
:size="20"
class="ml-2"
/>
</div>
</NuxtLink>
</div>

View File

@@ -18,7 +18,10 @@
class="inline-flex items-center px-6 py-3 bg-primary-600 hover:bg-primary-700 text-white font-semibold rounded-lg transition-colors"
>
Alle Termine anzeigen
<ArrowRight :size="20" class="ml-2" />
<ArrowRight
:size="20"
class="ml-2"
/>
</NuxtLink>
</div>
</div>

View File

@@ -2,22 +2,28 @@
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
{{ label }}
<span v-if="!required" class="text-gray-500 text-xs">(optional)</span>
<span
v-if="!required"
class="text-gray-500 text-xs"
>(optional)</span>
</label>
<div v-if="imageFilename" class="mb-2">
<div
v-if="imageFilename"
class="mb-2"
>
<div class="relative inline-block">
<img
:src="`/api/personen/${imageFilename}?width=100&height=100`"
:alt="label"
class="w-24 h-24 object-cover rounded-lg border-2 border-gray-300"
/>
>
<button
v-if="!uploading"
@click="removeImage"
class="absolute -top-2 -right-2 bg-red-600 text-white rounded-full p-1 hover:bg-red-700 transition-colors"
type="button"
title="Bild entfernen"
@click="removeImage"
>
<X :size="14" />
</button>
@@ -40,13 +46,22 @@
class="hidden"
:disabled="uploading"
@change="handleFileSelect"
/>
>
<div class="text-center">
<div v-if="uploading" class="flex items-center justify-center gap-2 text-gray-600">
<Loader2 :size="16" class="animate-spin" />
<div
v-if="uploading"
class="flex items-center justify-center gap-2 text-gray-600"
>
<Loader2
:size="16"
class="animate-spin"
/>
<span>Wird hochgeladen...</span>
</div>
<div v-else class="text-sm text-gray-600">
<div
v-else
class="text-sm text-gray-600"
>
<span v-if="!imageFilename">📷 Bild auswählen oder hier ablegen</span>
<span v-else>🔄 Bild ändern</span>
</div>
@@ -54,7 +69,12 @@
</label>
</div>
<p v-if="error" class="mt-1 text-sm text-red-600">{{ error }}</p>
<p
v-if="error"
class="mt-1 text-sm text-red-600"
>
{{ error }}
</p>
</div>
</template>

View File

@@ -1,6 +1,9 @@
<template>
<div>
<div v-if="mannschaften.length > 0" class="space-y-8">
<div
v-if="mannschaften.length > 0"
class="space-y-8"
>
<div
v-for="(mannschaft, index) in mannschaften"
:key="index"
@@ -11,7 +14,9 @@
<h2 class="text-2xl font-display font-bold text-white mb-2">
{{ mannschaft.mannschaft }}
</h2>
<p class="text-primary-100 text-lg">{{ mannschaft.liga }}</p>
<p class="text-primary-100 text-lg">
{{ mannschaft.liga }}
</p>
</div>
<!-- Content -->
@@ -20,24 +25,24 @@
<div class="grid md:grid-cols-2 gap-6 mb-6">
<div class="space-y-3">
<div class="flex items-center space-x-3">
<div class="w-2 h-2 bg-primary-600 rounded-full"></div>
<div class="w-2 h-2 bg-primary-600 rounded-full" />
<span class="text-gray-600">Staffelleiter:</span>
<span class="font-semibold text-gray-900">{{ mannschaft.staffelleiter }}</span>
</div>
<div class="flex items-center space-x-3">
<div class="w-2 h-2 bg-primary-600 rounded-full"></div>
<div class="w-2 h-2 bg-primary-600 rounded-full" />
<span class="text-gray-600">Telefon:</span>
<span class="font-semibold text-gray-900">{{ mannschaft.telefon }}</span>
</div>
</div>
<div class="space-y-3">
<div class="flex items-center space-x-3">
<div class="w-2 h-2 bg-primary-600 rounded-full"></div>
<div class="w-2 h-2 bg-primary-600 rounded-full" />
<span class="text-gray-600">Heimspieltag:</span>
<span class="font-semibold text-gray-900">{{ mannschaft.heimspieltag }}</span>
</div>
<div class="flex items-center space-x-3">
<div class="w-2 h-2 bg-primary-600 rounded-full"></div>
<div class="w-2 h-2 bg-primary-600 rounded-full" />
<span class="text-gray-600">Spielsystem:</span>
<span class="font-semibold text-gray-900">{{ mannschaft.spielsystem }}</span>
</div>
@@ -56,8 +61,13 @@
class="bg-gray-50 rounded-lg p-4 text-center"
:class="spieler === mannschaft.mannschaftsfuehrer ? 'ring-2 ring-primary-500 bg-primary-50' : ''"
>
<div class="font-semibold text-gray-900">{{ spieler }}</div>
<div v-if="spieler === mannschaft.mannschaftsfuehrer" class="text-xs text-primary-600 font-medium mt-1">
<div class="font-semibold text-gray-900">
{{ spieler }}
</div>
<div
v-if="spieler === mannschaft.mannschaftsfuehrer"
class="text-xs text-primary-600 font-medium mt-1"
>
Mannschaftsführer
</div>
</div>
@@ -76,9 +86,17 @@
</div>
</div>
<div v-else class="text-center py-12 bg-gray-50 rounded-xl">
<Users :size="48" class="text-gray-400 mx-auto mb-4" />
<p class="text-gray-600">Keine Mannschaftsdaten geladen</p>
<div
v-else
class="text-center py-12 bg-gray-50 rounded-xl"
>
<Users
:size="48"
class="text-gray-400 mx-auto mb-4"
/>
<p class="text-gray-600">
Keine Mannschaftsdaten geladen
</p>
</div>
</div>
</template>

View File

@@ -1,5 +1,8 @@
<template>
<section id="membership" class="py-16 sm:py-20 bg-gradient-to-b from-gray-50 to-white">
<section
id="membership"
class="py-16 sm:py-20 bg-gradient-to-b from-gray-50 to-white"
>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center mb-16">
<h2 class="text-4xl sm:text-5xl font-display font-bold text-gray-900 mb-4">
@@ -20,7 +23,10 @@
plan.popular ? 'ring-4 ring-primary-500 scale-105' : ''
]"
>
<div v-if="plan.popular" class="absolute top-0 right-0 bg-primary-600 text-white px-4 py-1 text-sm font-semibold rounded-bl-lg">
<div
v-if="plan.popular"
class="absolute top-0 right-0 bg-primary-600 text-white px-4 py-1 text-sm font-semibold rounded-bl-lg"
>
Beliebt
</div>
@@ -28,7 +34,11 @@
<div class="p-8">
<div :class="['w-12 h-12 bg-gradient-to-br rounded-xl flex items-center justify-center mb-4', plan.gradient]">
<component :is="plan.icon" :size="24" class="text-white" />
<component
:is="plan.icon"
:size="24"
class="text-white"
/>
</div>
<h3 class="text-2xl font-display font-bold text-gray-900 mb-2">
@@ -46,8 +56,15 @@
</div>
<ul class="space-y-3 mb-8">
<li v-for="feature in plan.features" :key="feature" class="flex items-start">
<Check :size="20" class="text-primary-600 mr-3 flex-shrink-0 mt-0.5" />
<li
v-for="feature in plan.features"
:key="feature"
class="flex items-start"
>
<Check
:size="20"
class="text-primary-600 mr-3 flex-shrink-0 mt-0.5"
/>
<span class="text-gray-700">{{ feature }}</span>
</li>
</ul>
@@ -84,7 +101,10 @@
target="_blank"
class="inline-flex items-center px-6 py-3 bg-primary-600 hover:bg-primary-700 text-white font-semibold rounded-lg transition-colors"
>
<FileText :size="20" class="mr-2" />
<FileText
:size="20"
class="mr-2"
/>
Satzung herunterladen (PDF)
</a>
<span class="text-sm text-gray-500">oder</span>
@@ -92,7 +112,10 @@
to="/satzung"
class="inline-flex items-center px-6 py-3 bg-gray-100 hover:bg-gray-200 text-gray-900 font-semibold rounded-lg transition-colors"
>
<Eye :size="20" class="mr-2" />
<Eye
:size="20"
class="mr-2"
/>
Online ansehen
</NuxtLink>
</div>

View File

@@ -1,5 +1,8 @@
<template>
<section id="membership" class="py-16 sm:py-20 bg-gradient-to-b from-gray-50 to-white">
<section
id="membership"
class="py-16 sm:py-20 bg-gradient-to-b from-gray-50 to-white"
>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center mb-16">
<h2 class="text-4xl sm:text-5xl font-display font-bold text-gray-900 mb-4">
@@ -20,7 +23,10 @@
plan.popular ? 'ring-4 ring-primary-500 scale-105' : ''
]"
>
<div v-if="plan.popular" class="absolute top-0 right-0 bg-primary-600 text-white px-4 py-1 text-sm font-semibold rounded-bl-lg">
<div
v-if="plan.popular"
class="absolute top-0 right-0 bg-primary-600 text-white px-4 py-1 text-sm font-semibold rounded-bl-lg"
>
Beliebt
</div>
@@ -28,7 +34,11 @@
<div class="p-8">
<div :class="['w-12 h-12 bg-gradient-to-br rounded-xl flex items-center justify-center mb-4', plan.gradient]">
<component :is="plan.icon" :size="24" class="text-white" />
<component
:is="plan.icon"
:size="24"
class="text-white"
/>
</div>
<h3 class="text-2xl font-display font-bold text-gray-900 mb-2">
@@ -46,8 +56,15 @@
</div>
<ul class="space-y-3 mb-8">
<li v-for="feature in plan.features" :key="feature" class="flex items-start">
<Check :size="20" class="text-primary-600 mr-3 flex-shrink-0 mt-0.5" />
<li
v-for="feature in plan.features"
:key="feature"
class="flex items-start"
>
<Check
:size="20"
class="text-primary-600 mr-3 flex-shrink-0 mt-0.5"
/>
<span class="text-gray-700">{{ feature }}</span>
</li>
</ul>
@@ -84,7 +101,10 @@
target="_blank"
class="inline-flex items-center px-6 py-3 bg-primary-600 hover:bg-primary-700 text-white font-semibold rounded-lg transition-colors"
>
<FileText :size="20" class="mr-2" />
<FileText
:size="20"
class="mr-2"
/>
Satzung herunterladen (PDF)
</a>
<span class="text-sm text-gray-500">oder</span>
@@ -92,7 +112,10 @@
to="/satzung"
class="inline-flex items-center px-6 py-3 bg-gray-100 hover:bg-gray-200 text-gray-900 font-semibold rounded-lg transition-colors"
>
<Eye :size="20" class="mr-2" />
<Eye
:size="20"
class="mr-2"
/>
Online ansehen
</NuxtLink>
</div>

View File

@@ -8,18 +8,32 @@
<div class="bg-white rounded-lg max-w-md w-full p-6">
<div class="flex items-center mb-4">
<div class="flex-shrink-0 w-10 h-10 mx-auto bg-green-100 rounded-full flex items-center justify-center">
<svg class="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
<svg
class="w-6 h-6 text-green-600"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M5 13l4 4L19 7"
/>
</svg>
</div>
</div>
<div class="text-center">
<h3 class="text-lg font-medium text-gray-900 mb-2">{{ successTitle }}</h3>
<p class="text-sm text-gray-600 mb-6">{{ successMessage }}</p>
<h3 class="text-lg font-medium text-gray-900 mb-2">
{{ successTitle }}
</h3>
<p class="text-sm text-gray-600 mb-6">
{{ successMessage }}
</p>
<div class="flex justify-center">
<button
@click="closeSuccess"
class="px-6 py-2 bg-primary-600 hover:bg-primary-700 text-white rounded-lg transition-colors"
@click="closeSuccess"
>
OK
</button>
@@ -37,18 +51,32 @@
<div class="bg-white rounded-lg max-w-md w-full p-6">
<div class="flex items-center mb-4">
<div class="flex-shrink-0 w-10 h-10 mx-auto bg-red-100 rounded-full flex items-center justify-center">
<svg class="w-6 h-6 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
<svg
class="w-6 h-6 text-red-600"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</div>
</div>
<div class="text-center">
<h3 class="text-lg font-medium text-gray-900 mb-2">{{ errorTitle }}</h3>
<p class="text-sm text-gray-600 mb-6">{{ errorMessage }}</p>
<h3 class="text-lg font-medium text-gray-900 mb-2">
{{ errorTitle }}
</h3>
<p class="text-sm text-gray-600 mb-6">
{{ errorMessage }}
</p>
<div class="flex justify-center">
<button
@click="closeError"
class="px-6 py-2 bg-red-600 hover:bg-red-700 text-white rounded-lg transition-colors"
@click="closeError"
>
OK
</button>
@@ -66,24 +94,38 @@
<div class="bg-white rounded-lg max-w-md w-full p-6">
<div class="flex items-center mb-4">
<div class="flex-shrink-0 w-10 h-10 mx-auto bg-yellow-100 rounded-full flex items-center justify-center">
<svg class="w-6 h-6 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"></path>
<svg
class="w-6 h-6 text-yellow-600"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"
/>
</svg>
</div>
</div>
<div class="text-center">
<h3 class="text-lg font-medium text-gray-900 mb-2">{{ confirmTitle }}</h3>
<p class="text-sm text-gray-600 mb-6">{{ confirmMessage }}</p>
<h3 class="text-lg font-medium text-gray-900 mb-2">
{{ confirmTitle }}
</h3>
<p class="text-sm text-gray-600 mb-6">
{{ confirmMessage }}
</p>
<div class="flex space-x-3 justify-center">
<button
@click="closeConfirm"
class="px-4 py-2 text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors"
@click="closeConfirm"
>
Abbrechen
</button>
<button
@click="executeConfirm"
class="px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-lg transition-colors"
@click="executeConfirm"
>
Bestätigen
</button>

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,25 @@
<template>
<div class="bg-white p-6 rounded-xl shadow-lg border border-gray-100">
<div v-if="imageFilename" class="mb-4 flex justify-center">
<div
v-if="imageFilename"
class="mb-4 flex justify-center"
>
<img
:src="`/api/personen/${imageFilename}?width=200&height=200`"
:alt="`${title}: ${name}`"
class="w-32 h-32 object-cover rounded-full border-4 border-primary-100 shadow-md"
loading="lazy"
/>
>
</div>
<h3 v-if="title" class="text-xl font-display font-bold text-gray-900 mb-2">{{ title }}</h3>
<h4 class="text-lg font-semibold text-primary-600 mb-3">{{ name }}</h4>
<h3
v-if="title"
class="text-xl font-display font-bold text-gray-900 mb-2"
>
{{ title }}
</h3>
<h4 class="text-lg font-semibold text-primary-600 mb-3">
{{ name }}
</h4>
<div class="space-y-1 text-gray-600">
<slot />
</div>

View File

@@ -1,5 +1,8 @@
<template>
<section v-if="news.length > 0" class="py-16 sm:py-20 bg-white">
<section
v-if="news.length > 0"
class="py-16 sm:py-20 bg-white"
>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center mb-16">
<h2 class="text-4xl sm:text-5xl font-display font-bold text-gray-900 mb-4">
@@ -12,15 +15,21 @@
</div>
<div class="flex justify-center">
<div class="grid gap-8" :class="getGridClass()">
<div
class="grid gap-8"
:class="getGridClass()"
>
<article
v-for="item in news"
:key="item.id"
@click="openNewsModal(item)"
class="bg-gray-50 rounded-xl p-6 border border-gray-200 hover:shadow-lg transition-shadow w-full max-w-sm flex flex-col cursor-pointer"
@click="openNewsModal(item)"
>
<div class="flex items-center text-sm text-gray-500 mb-3">
<Calendar :size="16" class="mr-2" />
<Calendar
:size="16"
class="mr-2"
/>
{{ formatDate(item.created) }}
</div>
@@ -47,7 +56,10 @@
<div class="flex items-center justify-between p-6 border-b border-gray-200">
<div class="flex-1">
<div class="flex items-center text-sm text-gray-500 mb-2">
<Calendar :size="16" class="mr-2" />
<Calendar
:size="16"
class="mr-2"
/>
{{ formatDate(selectedNews.created) }}
</div>
<h2 class="text-2xl font-display font-bold text-gray-900">
@@ -55,8 +67,8 @@
</h2>
</div>
<button
@click="closeNewsModal"
class="ml-4 p-2 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg transition-colors"
@click="closeNewsModal"
>
<X :size="24" />
</button>

View File

@@ -1,11 +1,23 @@
<template>
<div>
<label v-if="label" class="block text-sm font-medium text-gray-700 mb-2">
<label
v-if="label"
class="block text-sm font-medium text-gray-700 mb-2"
>
{{ label }}
<span v-if="required" class="text-red-500">*</span>
<span
v-if="required"
class="text-red-500"
>*</span>
</label>
<div ref="editorContainer" class="border border-gray-300 rounded-lg bg-white"></div>
<input type="hidden" :value="modelValue" />
<div
ref="editorContainer"
class="border border-gray-300 rounded-lg bg-white"
/>
<input
type="hidden"
:value="modelValue"
>
</div>
</template>

View File

@@ -2,56 +2,137 @@
<section class="py-16 bg-white">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center mb-12">
<h2 class="text-3xl font-bold text-gray-900 mb-4">Nächste Spiele</h2>
<h2 class="text-3xl font-bold text-gray-900 mb-4">
Nächste Spiele
</h2>
</div>
<!-- Loading State -->
<div v-if="isLoading" class="text-center py-8">
<svg class="w-8 h-8 text-gray-400 mx-auto mb-4 animate-spin" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
<div
v-if="isLoading"
class="text-center py-8"
>
<svg
class="w-8 h-8 text-gray-400 mx-auto mb-4 animate-spin"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
/>
</svg>
<p class="text-gray-600">Spielplan wird geladen...</p>
<p class="text-gray-600">
Spielplan wird geladen...
</p>
</div>
<!-- Error State -->
<div v-else-if="error" class="text-center py-8">
<svg class="w-12 h-12 text-gray-400 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
<div
v-else-if="error"
class="text-center py-8"
>
<svg
class="w-12 h-12 text-gray-400 mx-auto mb-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"
/>
</svg>
<p class="text-gray-600 mb-4">{{ error }}</p>
<NuxtLink to="/mannschaften/spielplaene" class="inline-flex items-center px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors">
<p class="text-gray-600 mb-4">
{{ error }}
</p>
<NuxtLink
to="/mannschaften/spielplaene"
class="inline-flex items-center px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors"
>
Zum Spielplan
</NuxtLink>
</div>
<!-- Empty State -->
<div v-else-if="!upcomingGames || upcomingGames.length === 0" class="text-center py-8">
<svg class="w-12 h-12 text-gray-400 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
<div
v-else-if="!upcomingGames || upcomingGames.length === 0"
class="text-center py-8"
>
<svg
class="w-12 h-12 text-gray-400 mx-auto mb-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"
/>
</svg>
<h3 class="text-lg font-medium text-gray-900 mb-2">Keine kommenden Spiele</h3>
<p class="text-gray-600 mb-4">Derzeit sind keine Spiele geplant.</p>
<NuxtLink to="/mannschaften/spielplaene" class="inline-flex items-center px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors">
<h3 class="text-lg font-medium text-gray-900 mb-2">
Keine kommenden Spiele
</h3>
<p class="text-gray-600 mb-4">
Derzeit sind keine Spiele geplant.
</p>
<NuxtLink
to="/mannschaften/spielplaene"
class="inline-flex items-center px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors"
>
Zum Spielplan
</NuxtLink>
</div>
<!-- Games Grid -->
<div v-else class="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
<div v-for="game in upcomingGames" :key="`${game.Termin}-${game.HeimMannschaft}`"
class="bg-white rounded-xl shadow-lg border border-gray-200 hover:shadow-xl transition-shadow">
<div
v-else
class="grid gap-6 md:grid-cols-2 lg:grid-cols-3"
>
<div
v-for="game in upcomingGames"
:key="`${game.Termin}-${game.HeimMannschaft}`"
class="bg-white rounded-xl shadow-lg border border-gray-200 hover:shadow-xl transition-shadow"
>
<div class="p-6">
<!-- Date and Time -->
<div class="flex items-center justify-between mb-4">
<div class="flex items-center">
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
<svg
class="w-5 h-5 text-primary-600 mr-2"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
/>
</svg>
<span class="text-sm font-medium text-gray-900">{{ formatDate(game.Termin) }}</span>
</div>
<div class="flex items-center text-sm text-gray-600">
<svg class="w-4 h-4 text-gray-400 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
<svg
class="w-4 h-4 text-gray-400 mr-1"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
{{ formatTime(game.Termin) }}
</div>
@@ -61,8 +142,12 @@
<div class="mb-4">
<div class="flex items-center justify-between">
<div class="flex-1">
<p class="text-sm text-gray-600 mb-1">Heim</p>
<p class="font-semibold text-gray-900">{{ formatTeamName(game.HeimMannschaft, game.HeimMannschaftAltersklasse) }}</p>
<p class="text-sm text-gray-600 mb-1">
Heim
</p>
<p class="font-semibold text-gray-900">
{{ formatTeamName(game.HeimMannschaft, game.HeimMannschaftAltersklasse) }}
</p>
</div>
<div class="text-center mx-4">
<div class="w-8 h-8 bg-primary-100 rounded-full flex items-center justify-center">
@@ -70,16 +155,33 @@
</div>
</div>
<div class="flex-1 text-right">
<p class="text-sm text-gray-600 mb-1">Gast</p>
<p class="font-semibold text-gray-900">{{ formatTeamName(game.GastMannschaft, game.GastMannschaftAltersklasse) }}</p>
<p class="text-sm text-gray-600 mb-1">
Gast
</p>
<p class="font-semibold text-gray-900">
{{ formatTeamName(game.GastMannschaft, game.GastMannschaftAltersklasse) }}
</p>
</div>
</div>
</div>
<!-- Competition Info -->
<div v-if="game.Runde" class="flex items-center text-sm text-gray-600">
<svg class="w-4 h-4 text-gray-400 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
<div
v-if="game.Runde"
class="flex items-center text-sm text-gray-600"
>
<svg
class="w-4 h-4 text-gray-400 mr-2"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
{{ formatRunde(game.Runde) }}
</div>
@@ -88,12 +190,27 @@
</div>
<!-- View All Button -->
<div v-if="upcomingGames && upcomingGames.length > 0" class="text-center mt-8">
<NuxtLink to="/mannschaften/spielplaene"
class="inline-flex items-center px-6 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors">
<div
v-if="upcomingGames && upcomingGames.length > 0"
class="text-center mt-8"
>
<NuxtLink
to="/mannschaften/spielplaene"
class="inline-flex items-center px-6 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors"
>
Alle Spiele anzeigen
<svg class="w-4 h-4 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
<svg
class="w-4 h-4 ml-2"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5l7 7-7 7"
/>
</svg>
</NuxtLink>
</div>

View File

@@ -1,43 +1,60 @@
<template>
<div>
<div v-if="naechsteTermine.length > 0" class="space-y-2 mb-6">
<div
v-for="(termin, index) in naechsteTermine"
:key="index"
class="bg-gray-50 rounded-lg p-3 hover:bg-gray-100 transition-colors"
>
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<div class="w-16 h-16 bg-primary-600 rounded-lg flex flex-col items-center justify-center text-white text-[10px] font-bold leading-tight py-1.5 px-1.5">
<span class="text-lg leading-none">{{ formatDay(termin.datum) }}</span>
<span class="leading-none mt-0.5">{{ formatMonth(termin.datum) }}</span>
<span class="text-[10px] leading-none opacity-95 mt-0.5">{{ formatYear(termin.datum) }}</span>
<span
v-if="termin.uhrzeit"
class="text-[10px] leading-none mt-1 px-2 py-0.5 rounded-md bg-white/40 ring-1 ring-white/50 backdrop-blur-[1.5px] whitespace-nowrap"
>
{{ formatOnlyTime(termin.uhrzeit) }} Uhr
</span>
</div>
<div>
<h3 class="font-semibold text-gray-900">{{ termin.titel }}</h3>
<p class="text-sm text-gray-600">{{ termin.beschreibung }}</p>
</div>
<div
v-if="naechsteTermine.length > 0"
class="space-y-2 mb-6"
>
<div
v-for="(termin, index) in naechsteTermine"
:key="index"
class="bg-gray-50 rounded-lg p-3 hover:bg-gray-100 transition-colors"
>
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<div class="w-16 h-16 bg-primary-600 rounded-lg flex flex-col items-center justify-center text-white text-[10px] font-bold leading-tight py-1.5 px-1.5">
<span class="text-lg leading-none">{{ formatDay(termin.datum) }}</span>
<span class="leading-none mt-0.5">{{ formatMonth(termin.datum) }}</span>
<span class="text-[10px] leading-none opacity-95 mt-0.5">{{ formatYear(termin.datum) }}</span>
<span
v-if="termin.uhrzeit"
class="text-[10px] leading-none mt-1 px-2 py-0.5 rounded-md bg-white/40 ring-1 ring-white/50 backdrop-blur-[1.5px] whitespace-nowrap"
>
{{ formatOnlyTime(termin.uhrzeit) }} Uhr
</span>
</div>
<span :class="[
<div>
<h3 class="font-semibold text-gray-900">
{{ termin.titel }}
</h3>
<p class="text-sm text-gray-600">
{{ termin.beschreibung }}
</p>
</div>
</div>
<span
:class="[
'px-2 py-1 text-xs font-medium rounded-full',
termin.kategorie === 'Turnier' ? 'bg-yellow-100 text-yellow-800' : 'bg-blue-100 text-blue-800'
]">
{{ termin.kategorie }}
</span>
</div>
]"
>
{{ termin.kategorie }}
</span>
</div>
</div>
</div>
<div v-else class="text-center py-8 bg-gray-50 rounded-lg">
<Calendar :size="32" class="text-gray-400 mx-auto mb-2" />
<p class="text-gray-600 text-sm">Keine kommenden Termine</p>
</div>
<div
v-else
class="text-center py-8 bg-gray-50 rounded-lg"
>
<Calendar
:size="32"
class="text-gray-400 mx-auto mb-2"
/>
<p class="text-gray-600 text-sm">
Keine kommenden Termine
</p>
</div>
</div>
</template>