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
Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 54s
This commit is contained in:
@@ -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 }}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user