ContactsSection
apps/www/src/components/ContactsSection.astro · 173 lines · group Contact
Used by
- skattedosan.se /en/contacts/ × 2
- skattedosan.se /contacts/ × 2history: commit 1396f74 (2026-08-18)
Live sites: skattedosan.se.
Samples 2
Contact us
- Phone number
- +46 73 302 92 51
- ask@codeexpert.se
MDX of this sample
<ContactsSection
title="Contact us"
alertTitle="Thank you!"
alertText="We`ve received your message. Someone from our team will contact you soon."
/>Contact us
- Phone number
- +46 73 302 92 51
- ask@codeexpert.se
MDX of this sample
<ContactsSection
title="Contact us"
alertTitle="Thank you!"
alertText="We`ve received your message. Someone from our team will contact you soon."
/>Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| title | string | yes | ||
| string | yes | |||
| phone | string | |||
| firstNameLabel | string | 'First name' | ||
| emailLabel | string | 'Email' | ||
| phoneLabel | string | 'Phone number' | ||
| messageLabel | string | 'Message' | ||
| submitButton | string | 'Submit' | ||
| subjectMail | string | 'Request from Contacts' | ||
| alertTitle | string | 'Thank you!' | ||
| alertText | string | 'We`ve received your message. Someone from our team will contact you soon' |
Source apps/www/src/components/ContactsSection.astro @ gitt.one
---
import Envelope from 'astro-heroicons/solid/Envelope.astro';
import Phone from 'astro-heroicons/solid/Phone.astro';
import pagesConfig from '../../pages.config.js';
interface Props {
title: string;
email: string;
phone?: string;
firstNameLabel?: string;
emailLabel?: string;
phoneLabel?: string;
messageLabel?: string;
submitButton?: string;
subjectMail?: string;
alertTitle?: string;
alertText?: string;
}
const {
title,
email,
phone,
firstNameLabel = 'First name',
emailLabel = 'Email',
phoneLabel = 'Phone number',
messageLabel = 'Message',
submitButton = 'Submit',
subjectMail = 'Request from Contacts',
alertTitle = 'Thank you!',
alertText = 'We`ve received your message. Someone from our team will contact you soon',
} = Astro.props;
const contactPhone = phone || pagesConfig.defaultPhone;
const contactEmail = email || pagesConfig.defaultEmail;
const turnstileSiteKey = pagesConfig.turnstileSiteKey;
const CAPTCHA_MESSAGE =
'The captcha check has not finished yet. Please wait a moment and try again.';
const inputClass =
'w-full rounded-md border border-gray-200 px-5 py-3 shadow-md focus:outline-none focus:ring-2 focus:ring-primary-500';
---
<section class="bg-white">
<div class="relative my-16 bg-white sm:my-20">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div
data-form-success
class="mb-6 hidden rounded-md bg-green-50 p-4"
role="status"
>
<h3 class="text-sm font-medium text-green-800">{alertTitle}</h3>
<div class="mt-2 text-sm text-green-700">
<p>{alertText}</p>
</div>
</div>
<div class="relative bg-white shadow-xl">
<div class="grid grid-cols-1 lg:grid-cols-3">
<div
class="relative overflow-hidden bg-gradient-to-b from-primary-500 to-primary-alt-600 px-6 py-10 sm:px-10 xl:p-12"
>
{Boolean(title) && <h3 class="text-lg font-medium text-white">{title}</h3>}
<dl class="mt-8 space-y-6">
<dt><span class="sr-only">{phoneLabel}</span></dt>
<dd class="flex text-base text-white">
<Phone class="h-6 w-6 flex-shrink-0 text-white" aria-hidden="true" />
<a class="ml-3" href={`tel:${contactPhone}`}>{contactPhone}</a>
</dd>
<dt><span class="sr-only">{emailLabel}</span></dt>
<dd class="flex text-base text-white">
<Envelope class="h-6 w-6 flex-shrink-0 text-white" aria-hidden="true" />
<a class="ml-3" href={`mailto:${contactEmail}`}>{contactEmail}</a>
</dd>
</dl>
</div>
<div class="px-6 py-10 sm:px-10 lg:col-span-2 xl:p-12">
<form
data-contact-form
data-api={pagesConfig.contactFormReceiverURL}
data-site-host={new URL(pagesConfig.siteUrl).host}
data-captcha-message={CAPTCHA_MESSAGE}
method="POST"
class="mt-6"
novalidate={false}
>
<div
data-form-fields
class="grid grid-cols-1 gap-y-6 sm:grid-cols-2 sm:gap-x-8"
>
<div class="sm:col-span-2">
<label for="name" class="block text-sm font-medium text-gray-900">
{firstNameLabel} <span aria-hidden="true">*</span>
</label>
<input type="text" id="name" name="name" required class:list={['mt-1', inputClass]} />
</div>
<div class="col-span-1 sm:col-span-2 lg:col-span-1">
<label for="phone" class="block text-sm font-medium text-gray-900">
{phoneLabel} <span aria-hidden="true">*</span>
</label>
<input type="tel" id="phone" name="phone" required class:list={['mt-1', inputClass]} />
</div>
<div class="col-span-1 sm:col-span-2 lg:col-span-1">
<label for="email" class="block text-sm font-medium text-gray-900">
{emailLabel} <span aria-hidden="true">*</span>
</label>
<input type="email" id="email" name="email" required class:list={['mt-1', inputClass]} />
</div>
<div class="sm:col-span-2">
<label for="message" class="block text-sm font-medium text-gray-900">
{messageLabel} <span aria-hidden="true">*</span>
</label>
<textarea id="message" name="message" rows="4" required class:list={['mt-1', inputClass]}
></textarea>
</div>
<!-- Honeypot: real users never see or fill this field. -->
<input
type="text"
name="website"
tabindex="-1"
autocomplete="off"
aria-hidden="true"
class="hidden"
/>
<input type="hidden" name="subject" value={subjectMail} />
<div class="sm:col-span-2 sm:flex sm:items-center sm:justify-end sm:gap-x-4">
{
Boolean(turnstileSiteKey) && (
<div class="cf-turnstile" data-sitekey={turnstileSiteKey} />
)
}
<p data-form-preview-note class="hidden text-sm text-gray-500">
Preview environment — the contact form works only on the
production site.
</p>
<p data-form-error class="hidden text-sm text-red-500">
Something went wrong. Please try again later.
</p>
<button
type="submit"
class="inline-flex min-h-full items-center justify-center rounded-md bg-primary-500 px-4 py-3 font-medium text-white shadow hover:bg-primary-600 focus:outline-none focus:ring-1 focus:ring-primary-700 disabled:bg-gray-200"
>
{submitButton}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
{
Boolean(turnstileSiteKey) && (
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer is:inline />
)
}
<script>
import { initContactForms } from '../lib/contact-form';
initContactForms();
</script>Source links point to engine-astro@e857a859. Samples are cut from the sites' own content by scripts/gallery-extract.mjs; nothing is merged or removed yet.