Dominik Milacher 85d080ab05
All checks were successful
Build and deploy updated apps / Build & deploy (push) Successful in 2m12s
Add panoramablick implementation
2025-06-13 23:11:04 +02:00

143 lines
5.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- Contactcentric layout -->
<AppFlatSection>
<!-- Grid: form (fixed maxwidth) | host snapshots -->
<div class="grid gap-12 lg:grid-cols-[minmax(0,480px)_1fr] items-start lg:items-center">
<!-- Contact form -->
<div class="w-full max-w-xl mx-auto lg:mx-0">
<h1 class="text-3xl sm:text-4xl font-bold mb-4">{{ t('contact.title') }}</h1>
<!-- Extended intro -->
<p class="text-neutral-700 mb-4 max-w-prose">
{{ t('contact.description') }}
</p>
<!-- Contact shortcuts -->
<div class="mb-8 space-y-1 text-sm">
<!-- Phone (phone + WhatsApp icons) -->
<div class="flex items-center gap-2">
<!-- Heroicons phone -->
<UIcon name="i-heroicons-phone" class="w-4 h-4 text-primary-600"/>
<!-- WhatsApp icon (any Iconify set you use) -->
<UIcon name="i-uil-whatsapp" class="w-4 h-4 text-primary-600"/>
<a :href="`tel:${t('contact.phone').replace(/\s+/g, '')}`" class="hover:underline">
{{ t('contact.phone') }}
</a>
</div>
<!-- E-mail -->
<div class="flex items-center gap-2">
<UIcon name="i-heroicons-envelope" class="w-4 h-4 text-primary-600"/>
<a :href="`mailto:${t('contact.email')}`" class="hover:underline">
{{ t('contact.email') }}
</a>
</div>
</div>
<p class="text-neutral-700 mb-4 max-w-prose">
{{ t('contact.online-1') }}
<UButton to="/book" variant="outline" trailing-icon="i-heroicons-arrow-right">{{
t('contact.online-2')
}}
</UButton>
{{ t('contact.online-3') }}
</p>
<!-- Form -->
<UForm :state="state" class="space-y-4" @submit="onSubmit">
<UFormField name="name" label="Name" :ui="{ label: 'sr-only' }">
<UInput v-model="state.name" class="w-full" :placeholder="t('contact.form.name')"/>
</UFormField>
<UFormField name="email" label="E-Mail" :ui="{ label: 'sr-only' }">
<UInput v-model="state.email" type="email" class="w-full"
:placeholder="t('contact.form.email')"/>
</UFormField>
<UFormField name="subject" label="Betreff" :ui="{ label: 'sr-only' }">
<UInput v-model="state.subject" class="w-full" :placeholder="t('contact.form.subject')"/>
</UFormField>
<UFormField name="message" label="Nachricht" :ui="{ label: 'sr-only' }">
<UTextarea v-model="state.message" :rows="6" class="w-full"
:placeholder="t('contact.form.message')"/>
</UFormField>
<UButton type="submit" color="primary" size="lg" class="w-full sm:w-auto">
{{ t('contact.form.send') }}
</UButton>
</UForm>
</div>
<!-- Decorative host snapshots -->
<div id="hosts" class="flex flex-col gap-10 lg:self-center">
<AppHero
:src="t('contact.heroes.parents.image')"
:alt="t('contact.heroes.parents.title')"
image-side="left"
:size="50"
:title="t('contact.heroes.parents.title')"
:description="t('contact.heroes.parents.description')"
/>
<AppHero
:src="t('contact.heroes.children.image')"
:alt="t('contact.heroes.children.title')"
image-side="right"
:size="50"
:title="t('contact.heroes.children.title')"
:description="t('contact.heroes.children.description')"
/>
</div>
</div>
</AppFlatSection>
</template>
<script setup lang="ts">
const {t, tm, rt} = useI18n()
import * as v from 'valibot'
import type {FormSubmitEvent} from '@nuxt/ui'
/* ───── validation schema ───── */
const schema = v.object({
name: v.pipe(v.string(), v.minLength(2, 'Bitte Namen eingeben')),
email: v.pipe(v.string(), v.email('Ungültige E-Mail')),
subject: v.pipe(v.string(), v.minLength(3, 'Betreff fehlt')),
message: v.pipe(v.string(), v.minLength(10, 'Nachricht ist zu kurz'))
})
type Schema = v.InferOutput<typeof schema>
/* ───── reactive form state ───── */
const state = reactive<Schema>({
name: '', email: '', subject: '', message: ''
})
const toast = useToast()
/* ───── submit handler ───── */
async function onSubmit(event: FormSubmitEvent<Schema>) {
try {
await $fetch('/contact.php', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: event.data
})
toast.add({
title: 'Nachricht gesendet',
description: 'Vielen Dank wir melden uns bald.',
color: 'green'
})
/* reset fields */
Object.assign(state, {name: '', email: '', subject: '', message: ''})
} catch (err: any) {
toast.add({
title: 'Fehler',
description: err?.data?.message ?? 'Nachricht konnte nicht gesendet werden.',
color: 'red'
})
}
}
</script>