IT4C.dev/docs/.vuepress/components/ContactForm.vue
sebastian2357 3d5d2fff0a
refactor(other): new website structure (#227)
* - added new site /new/README.md
- added new components
- added component registration "client.js"
- added approach for tailwind integration (does not work yet)

* Use TypeScript and script setup

* No ts for .textlintrc

* Make Tailwind work

* include heropage contents

partially fixes https://github.com/IT4Change/IT4C.dev/issues/221

* adjust contents of Services

Adjust contents according to
https://github.com/IT4Change/IT4C.dev/issues/222

* added Team & Values texts

According to https://github.com/IT4Change/IT4C.dev/issues/223

* fixed type

* fixed unreferenced styles/main.css

* sample from theme-hope-docu

From
https://theme-hope.vuejs.press/guide/layout/home.html#project-highlights-and-features

* - adapted Hope hero section
- removed remaining Hero Widgets
- added ContentSection
- optimized layout of team section

* - optimized layout/style of ContactForm

* - made TeamMember functional and added some transitions
- added new members as placeholder

* Hero at 100vh; transparent navbar on home page

* Add text and image for Max

* Keep logo text in same row as logo

* - added REST request to mail backend
- added limitations to contact fields

* - added photo and phone number to contact form

* - changed contact person and phone number

* - replaced hero section
- replaced default layout
- replaced footer

* clean up

* - optimized colors

* - clean up AI comments

* move new page from /new to /

* fixed errors with contactForm

* fix projects

* fix merge error

* corrected image for Sebastian

* - improved layout

* - fixed tag colors
- fixed phone number color and hover

---------

Co-authored-by: Sebastian Stein <git@codepassion.de>
Co-authored-by: Maximilian Harz <maxharz@gmail.com>
Co-authored-by: Ulf Gebhardt <ulf.gebhardt@webcraft-media.de>
Co-authored-by: Sebastian Stein <sebastian@codepassion.de>
2025-03-17 01:09:31 +01:00

158 lines
5.2 KiB
Vue

<template>
<p class="text-gray-600 mb-8">Wir freuen uns auf Ihre Nachricht. Als Ansprechpartner steht Ihnen <strong>Ulf Gebhardt</strong> für Ihre Fragen gerne zur Verfügung.</p>
<div class="grid grid-cols-1 md:grid-cols-5 gap-8">
<!-- Left side: Portrait - takes 2/5 of space -->
<div class="flex flex-col items-center md:items-start md:self-start md:col-span-2">
<img
src="/images/portrait/ulf-gebhardt.jpg"
alt="Ulf Gebhardt"
class="rounded-lg shadow-md w-97 h-auto mb-6"
/>
</div>
<!-- Right side: Contact form - takes 3/5 of space -->
<div class="md:col-span-3">
<h3 class="mb-4">Telefon</h3>
<div class="flex-col gap-2 mb-8">
<p class="flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" class="phone-number h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" />
</svg>
<a href="tel:+4915784841600" class="phone-number hover:!underline">+49 15784841600</a>
</p>
</div>
<h3 class="mb-4">Nachricht</h3>
<form class="space-y-4" @submit.prevent="handleSubmit">
<div v-if="submitSuccess" class="p-3 bg-green-100 text-green-700 rounded-md mb-4">
Deine Nachricht wurde erfolgreich gesendet. Vielen Dank!
</div>
<div v-if="submitError" class="p-3 bg-red-100 text-red-700 rounded-md mb-4">
{{ submitError }}
</div>
<div>
<input
type="text"
id="name"
v-model="form.name"
placeholder="Name"
required
minlength="2"
maxlength="35"
class="w-full p-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent"
>
</div>
<div>
<input
type="email"
id="email"
v-model="form.email"
placeholder="E-Mail"
required
class="w-full p-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent"
>
</div>
<div>
<input
type="tel"
id="phone"
v-model="form.phone"
placeholder="Telefon"
minlength="8"
class="w-full p-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent"
>
</div>
<div>
<textarea
id="message"
v-model="form.message"
rows="4"
placeholder="Ihre Nachricht"
required
minlength="5"
class="w-full p-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent"
></textarea>
</div>
<div class="flex justify-end">
<button
type="submit"
:disabled="isSubmitting"
class="bg-green-700 text-white py-2 px-6 rounded-md hover:bg-green-600 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 disabled:bg-green-300 disabled:cursor-not-allowed"
>
<span v-if="isSubmitting">Wird gesendet...</span>
<span v-else>Nachricht senden</span>
</button>
</div>
</form>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
const form = reactive({
name: '',
email: '',
phone: '',
message: ''
})
const isSubmitting = ref(false)
const submitSuccess = ref(false)
const submitError = ref('')
const handleSubmit = async () => {
try {
isSubmitting.value = true
submitError.value = ''
const response = await fetch('/api/mail', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: form.name,
email: form.email,
telephone: form.phone || undefined, // Send undefined if empty to match optional schema
text: form.message
})
})
if(response.status !== 200){
throw new Error('Bei der Kommunikation mit dem Server ist ein Fehler aufgetreten.')
}
const result = await response.json()
if (!response.ok) {
throw new Error(result.error || 'Fehler beim Senden der Nachricht')
}
// Clear form on success
form.name = ''
form.email = ''
form.phone = ''
form.message = ''
submitSuccess.value = true
setTimeout(() => {
submitSuccess.value = false
}, 5000) // Hide success message after 5 seconds
} catch (error) {
submitError.value = error instanceof Error ? error.message : 'Ein unbekannter Fehler ist aufgetreten'
} finally {
isSubmitting.value = false
}
}
</script>
<style>
.phone-number {
color: var(--highlight-color);
}
</style>