Refactor environment configuration for local development; update SMTP settings and add JWT secret, encryption key, and debug options. Enhance Nuxt configuration for development server and runtime settings. Introduce new membership application form with validation and PDF generation functionality. Update footer and navigation components to include new membership links. Revise user and session data in JSON files.
This commit is contained in:
149
components/MembershipNoQuestions.vue
Normal file
149
components/MembershipNoQuestions.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<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">
|
||||
Mitgliedschaft
|
||||
</h2>
|
||||
<div class="w-24 h-1 bg-primary-600 mx-auto mb-6" />
|
||||
<p class="text-xl text-gray-600 max-w-3xl mx-auto">
|
||||
Werden Sie Teil unserer Tischtennis-Familie - Wählen Sie die passende Mitgliedschaft für sich
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid md:grid-cols-3 gap-8 max-w-6xl mx-auto">
|
||||
<div
|
||||
v-for="plan in plans"
|
||||
:key="plan.name"
|
||||
:class="[
|
||||
'relative bg-white rounded-2xl shadow-xl overflow-hidden',
|
||||
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">
|
||||
Beliebt
|
||||
</div>
|
||||
|
||||
<div :class="['h-2 bg-gradient-to-r', plan.gradient]" />
|
||||
|
||||
<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" />
|
||||
</div>
|
||||
|
||||
<h3 class="text-2xl font-display font-bold text-gray-900 mb-2">
|
||||
{{ plan.name }}
|
||||
</h3>
|
||||
<p class="text-gray-600 mb-6 min-h-[3rem]">
|
||||
{{ plan.description }}
|
||||
</p>
|
||||
|
||||
<div class="mb-6">
|
||||
<div class="flex items-baseline">
|
||||
<span class="text-5xl font-bold text-gray-900">{{ plan.price }}€</span>
|
||||
<span class="text-gray-600 ml-2">/ {{ plan.period }}</span>
|
||||
</div>
|
||||
</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" />
|
||||
<span class="text-gray-700">{{ feature }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<NuxtLink
|
||||
to="/kontakt"
|
||||
:class="[
|
||||
'block w-full text-center px-6 py-3 rounded-lg font-semibold transition-all duration-300',
|
||||
plan.popular
|
||||
? 'bg-primary-600 hover:bg-primary-700 text-white shadow-lg hover:shadow-xl'
|
||||
: 'bg-gray-100 hover:bg-gray-200 text-gray-900'
|
||||
]"
|
||||
>
|
||||
Jetzt beitreten
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Satzung Download -->
|
||||
<div class="mt-16 bg-white rounded-2xl shadow-xl p-8 border border-gray-100">
|
||||
<div class="text-center mb-8">
|
||||
<h3 class="text-3xl font-display font-bold text-gray-900 mb-4">
|
||||
Vereinsatzung
|
||||
</h3>
|
||||
<p class="text-xl text-gray-600">
|
||||
Laden Sie unsere aktuelle Vereinsatzung herunter
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center items-center">
|
||||
<a
|
||||
href="/documents/satzung.pdf"
|
||||
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" />
|
||||
Satzung herunterladen (PDF)
|
||||
</a>
|
||||
<span class="text-sm text-gray-500">oder</span>
|
||||
<NuxtLink
|
||||
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" />
|
||||
Online ansehen
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { Check, Star, Heart, FileText, Eye, User, Users } from 'lucide-vue-next'
|
||||
|
||||
const config = ref(null)
|
||||
|
||||
const loadConfig = async () => {
|
||||
try {
|
||||
const response = await $fetch('/api/config')
|
||||
config.value = response
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Laden der Config:', error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadConfig()
|
||||
})
|
||||
|
||||
const plans = computed(() => {
|
||||
if (!config.value?.mitgliedschaft) return []
|
||||
|
||||
const icons = [Star, Check, Heart, User, Users]
|
||||
const gradients = [
|
||||
'from-blue-500 to-cyan-500',
|
||||
'from-primary-500 to-green-600',
|
||||
'from-orange-500 to-red-500',
|
||||
'from-purple-500 to-pink-500',
|
||||
'from-indigo-500 to-blue-500'
|
||||
]
|
||||
|
||||
return config.value.mitgliedschaft.map((m, index) => ({
|
||||
name: m.typ,
|
||||
description: m.beschreibung || '',
|
||||
price: m.preis.toString(),
|
||||
period: 'Jahr',
|
||||
features: m.features || [],
|
||||
icon: icons[index % icons.length],
|
||||
gradient: gradients[index % gradients.length],
|
||||
popular: index === 0
|
||||
}))
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user