Initial commit: Harheimer TC Website
- 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
This commit is contained in:
238
components/Contact.vue
Normal file
238
components/Contact.vue
Normal file
@@ -0,0 +1,238 @@
|
||||
<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>
|
||||
|
||||
Reference in New Issue
Block a user