ContactSection

apps/www/src/components/ContactSection.astro · 185 lines · group Contact

moblos-family contact section (codeexpert.se style): gray info panel on the left, placeholder-labelled inputs on the right. The gradient-panel variant lives in ContactsSection.astro (skattedosan family).

Used by

Live sites: pages.gitt.one, codeexpert.se, posexpert.se.

Samples 4

codeexpert.se/

Contact with us

Please, leave your contacts or write/call us directly

Phone number
+46733029251
MDX of this sample
<ContactSection
  title="Contact with us"
  description="Please, leave your contacts or write/call us directly"
  email="ask@codeexpert.se"
  phone="+46733029251"
  firstNameLabel="Full 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"
/>
pages.gitt.one/

Contact with us

Please, leave your contacts or write/call us directly

Phone number
+46733029251
MDX of this sample
<ContactSection
  title="Contact with us"
  description="Please, leave your contacts or write/call us directly"
  email="ask@codeexpert.se"
  phone="+46733029251"
  firstNameLabel="Your name"
  emailLabel="Email"
  phoneLabel="Phone number"
  messageLabel="Message"
  submitButton="Submit"
  subjectMail="Request from pages.gitt.one"
  alertTitle="Thank you!"
  alertText="We've received your message. Someone from our team will contact you soon"
/>
posexpert.se/

Contact with us

Get in touch with us to discuss our POS development solutions

Phone number
+46733029251
MDX of this sample
<ContactSection
  title="Contact with us"
  description="Get in touch with us to discuss our POS development solutions"
  email="ask@posexpert.se"
  phone="+46733029251"
  firstNameLabel="Your 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"
/>
posexpert.se/history: commit d82a01f (2026-08-20)

Contact with us

Get in touch with us to discuss our POS development solutions

Phone number
+46733029251
MDX of this sample
<ContactSection
  title="Contact with us"
  description="Get in touch with us to discuss our POS development solutions"
  email="ask@posexpert.se"
  phone="+46733029251"
  firstNameLabel="Your 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"
/>

Props

NameTypeRequiredDefaultDescription
titlestringyes
descriptionstring''
emailstring
phonestring
firstNameLabelstring'Full name'
emailLabelstring'Email'
phoneLabelstring'Phone'
messageLabelstring'Message'
submitButtonstring'Submit'
subjectMailstring'Request from Contacts'
alertTitlestring'Thank you!'
alertTextstring'We`ve received your message. Someone from our team will contact you soon'

Source apps/www/src/components/ContactSection.astro @ gitt.one

---
// moblos-family contact section (codeexpert.se style): gray info panel on the
// left, placeholder-labelled inputs on the right. The gradient-panel variant
// lives in ContactsSection.astro (skattedosan family).
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;
  description?: string;
  email?: string;
  phone?: string;
  firstNameLabel?: string;
  emailLabel?: string;
  phoneLabel?: string;
  messageLabel?: string;
  submitButton?: string;
  subjectMail?: string;
  alertTitle?: string;
  alertText?: string;
}

const {
  title,
  description = '',
  email,
  phone,
  firstNameLabel = 'Full name',
  emailLabel = 'Email',
  phoneLabel = 'Phone',
  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 =
  'block w-full rounded-md border border-stone-300 px-4 py-3 placeholder-stone-500 shadow-sm focus:outline-none focus:ring-2 focus:ring-primary-500';
---

<div class="relative bg-white" id="contacts">
  <div class="absolute inset-0">
    <div class="absolute inset-y-0 left-0 w-1/2 bg-stone-50"></div>
  </div>
  <div class="relative mx-auto max-w-7xl lg:grid lg:grid-cols-5">
    <div class="bg-stone-50 px-4 py-12 sm:px-6 lg:col-span-2 lg:px-8 xl:pr-12">
      <div class="mx-auto max-w-lg">
        <h2 class="text-3xl font-extrabold tracking-tight text-stone-900 sm:text-4xl">
          {title}
        </h2>
        {description && <p class="mt-3 text-lg leading-6 text-stone-500">{description}</p>}
        <dl class="mt-8 text-base text-stone-500">
          {
            Boolean(contactPhone) && (
              <div class="mt-6">
                <dt class="sr-only">Phone number</dt>
                <dd class="flex">
                  <Phone class="h-6 w-6 flex-shrink-0 text-stone-400" aria-hidden="true" />
                  <a class="ml-3" href={`tel:${contactPhone.replace(/[^+\d]/g, '')}`}>
                    {contactPhone}
                  </a>
                </dd>
              </div>
            )
          }
          <div class="mt-3">
            <dt class="sr-only">Email</dt>
            <dd class="flex">
              <Envelope class="h-6 w-6 flex-shrink-0 text-stone-400" aria-hidden="true" />
              <a class="ml-3" href={`mailto:${contactEmail}`}>{contactEmail}</a>
            </dd>
          </div>
        </dl>
      </div>
    </div>
    <div class="bg-white px-4 py-12 sm:px-6 lg:col-span-3 lg:px-8 xl:pl-12">
      <div class="mx-auto max-w-lg lg:max-w-none">
        <form
          method="post"
          data-contact-form
          data-api={pagesConfig.contactFormReceiverURL}
          data-site-host={new URL(pagesConfig.siteUrl).host}
          data-captcha-message={CAPTCHA_MESSAGE}
          class="grid grid-cols-1 gap-y-6"
        >
          <div data-form-fields class="grid grid-cols-1 gap-y-6">
            <div>
              <label for="contact-name" class="sr-only">{firstNameLabel}</label>
              <input
                type="text"
                name="name"
                id="contact-name"
                autocomplete="name"
                class={inputClass}
                placeholder={firstNameLabel}
                required
              />
            </div>
            <div>
              <label for="contact-email" class="sr-only">{emailLabel}</label>
              <input
                type="email"
                name="email"
                id="contact-email"
                autocomplete="email"
                class={inputClass}
                placeholder={emailLabel}
                required
              />
            </div>
            <div>
              <label for="contact-phone" class="sr-only">{phoneLabel}</label>
              <input
                type="tel"
                name="phone"
                id="contact-phone"
                autocomplete="tel"
                class={inputClass}
                placeholder={phoneLabel}
                required
              />
            </div>
            <div>
              <label for="contact-message" class="sr-only">{messageLabel}</label>
              <textarea
                name="message"
                id="contact-message"
                rows="4"
                class={inputClass}
                placeholder={messageLabel}
                required></textarea>
            </div>
            <input name="website" class="hidden" tabindex="-1" autocomplete="off" />
            <input type="hidden" name="subject" value={subjectMail} />
            {
              Boolean(turnstileSiteKey) && (
                <div class="cf-turnstile" data-sitekey={turnstileSiteKey} />
              )
            }
            <div>
              <button
                type="submit"
                class="inline-flex justify-center rounded-md border border-transparent bg-primary-700 px-6 py-3 text-base font-medium text-white shadow-sm hover:bg-primary-800 disabled:opacity-50"
              >
                {submitButton}
              </button>
            </div>
            <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-red-600">
              Something went wrong. Please try again or write us directly.
            </p>
          </div>
          <div data-form-success class="hidden">
            <h3 class="text-2xl font-bold text-stone-900">{alertTitle}</h3>
            <p class="mt-2 text-stone-500">{alertText}</p>
          </div>
        </form>
      </div>
    </div>
  </div>
</div>

{
  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.