- Vue 3 + Nuxt 3 Framework - Tailwind CSS Styling - Responsive Design mit schwarz-roten Vereinsfarben - Dynamische Galerie mit Lightbox - Event-Management über CSV-Dateien - Mannschaftsübersicht mit dynamischen Seiten - SMTP-Kontaktformular - Google Maps Integration - Mobile-optimierte Navigation mit Submenus - Trainer-Übersicht - Vereinsmeisterschaften, Spielsysteme, TT-Regeln - Impressum mit Datenschutzerklärung
239 lines
8.7 KiB
Vue
239 lines
8.7 KiB
Vue
<template>
|
|
<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">
|
|
Kontakt
|
|
</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">
|
|
Wir freuen uns auf Ihre Nachricht - Kontaktieren Sie uns!
|
|
</p>
|
|
</div>
|
|
|
|
<div class="grid lg:grid-cols-2 gap-12 items-start">
|
|
<!-- Contact Information -->
|
|
<div class="space-y-6">
|
|
<div
|
|
v-for="info in contactInfo"
|
|
:key="info.title"
|
|
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" />
|
|
</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">
|
|
{{ line }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Map & Link -->
|
|
<div class="space-y-4">
|
|
<div class="rounded-2xl overflow-hidden shadow-xl h-64">
|
|
<iframe
|
|
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2554.5!2d8.660947!3d50.187044!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47bd0e5e5e5e5e5e%3A0x5e5e5e5e5e5e5e5e!2sIn%20den%20Schafg%C3%A4rten%2025%2C%2060437%20Frankfurt%20am%20Main!5e0!3m2!1sde!2sde!4v1234567890"
|
|
width="100%"
|
|
height="100%"
|
|
style="border: 0"
|
|
loading="lazy"
|
|
allowfullscreen
|
|
referrerpolicy="no-referrer-when-downgrade"
|
|
title="Sporthalle der Grundschule Harheim"
|
|
/>
|
|
</div>
|
|
<a
|
|
href="https://www.google.com/maps/search/?api=1&query=In+den+Schafgärten+25+60437+Frankfurt"
|
|
target="_blank"
|
|
class="block text-center px-4 py-3 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg transition-colors"
|
|
>
|
|
In Google Maps öffnen
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Contact Form -->
|
|
<div class="bg-gradient-to-br from-primary-50 to-primary-100/50 rounded-2xl p-8 shadow-xl">
|
|
<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">
|
|
<div>
|
|
<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"
|
|
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">
|
|
E-Mail *
|
|
</label>
|
|
<input
|
|
type="email"
|
|
id="email"
|
|
v-model="formData.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">
|
|
Telefon
|
|
</label>
|
|
<input
|
|
type="tel"
|
|
id="phone"
|
|
v-model="formData.phone"
|
|
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">
|
|
Betreff *
|
|
</label>
|
|
<input
|
|
type="text"
|
|
id="subject"
|
|
v-model="formData.subject"
|
|
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">
|
|
Nachricht *
|
|
</label>
|
|
<textarea
|
|
id="message"
|
|
v-model="formData.message"
|
|
required
|
|
rows="5"
|
|
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 resize-none"
|
|
placeholder="Ihre Nachricht..."
|
|
/>
|
|
</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 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">
|
|
{{ submitMessage }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<button
|
|
type="submit"
|
|
: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>
|
|
{{ isSubmitting ? 'Wird gesendet...' : 'E-Mail senden' }}
|
|
</button>
|
|
<p class="text-sm text-gray-600 text-center">
|
|
* Pflichtfelder
|
|
</p>
|
|
</form>
|
|
<p class="mt-4 text-sm text-gray-600 text-center">
|
|
Ihre Nachricht wird direkt an j.dichmann@gmx.de gesendet
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from 'vue'
|
|
import { MapPin, Phone, Mail, Clock, Send, CheckCircle, AlertCircle } from 'lucide-vue-next'
|
|
|
|
const formData = ref({
|
|
name: '',
|
|
email: '',
|
|
phone: '',
|
|
subject: '',
|
|
message: ''
|
|
})
|
|
|
|
const isSubmitting = ref(false)
|
|
const submitStatus = ref(null) // 'success', 'error', null
|
|
const submitMessage = ref('')
|
|
|
|
const sendEmail = async () => {
|
|
isSubmitting.value = true
|
|
submitStatus.value = null
|
|
submitMessage.value = ''
|
|
|
|
try {
|
|
const response = await $fetch('/api/contact', {
|
|
method: 'POST',
|
|
body: formData.value
|
|
})
|
|
|
|
if (response.success) {
|
|
submitStatus.value = 'success'
|
|
submitMessage.value = 'E-Mail wurde erfolgreich gesendet! Wir melden uns bald bei Ihnen.'
|
|
|
|
// Formular zurücksetzen
|
|
formData.value = {
|
|
name: '',
|
|
email: '',
|
|
phone: '',
|
|
subject: '',
|
|
message: ''
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Fehler beim Senden:', error)
|
|
submitStatus.value = 'error'
|
|
submitMessage.value = error.data?.message || 'Fehler beim Senden der E-Mail. Bitte versuchen Sie es später erneut.'
|
|
} finally {
|
|
isSubmitting.value = false
|
|
}
|
|
}
|
|
|
|
const contactInfo = [
|
|
{
|
|
icon: MapPin,
|
|
title: 'Trainingsort',
|
|
content: ['Sporthalle der Grundschule Harheim', 'In den Schafgärten 25', '60437 Frankfurt/Main'],
|
|
color: 'from-red-500 to-pink-500',
|
|
},
|
|
{
|
|
icon: Phone,
|
|
title: 'Telefon',
|
|
content: ['06101-4992227'],
|
|
color: 'from-green-500 to-emerald-500',
|
|
},
|
|
{
|
|
icon: Mail,
|
|
title: 'E-Mail',
|
|
content: ['j.dichmann@gmx.de'],
|
|
color: 'from-blue-500 to-cyan-500',
|
|
},
|
|
{
|
|
icon: Clock,
|
|
title: 'Trainingszeiten',
|
|
content: ['Dienstag: 19:30 - 22:30 Uhr', 'Donnerstag: 19:30 - 22:30 Uhr'],
|
|
color: 'from-purple-500 to-indigo-500',
|
|
},
|
|
]
|
|
</script>
|
|
|