Zoeken...  ⌘K GitHub

FormBooking Forms

Afspraakformulier met datum- en tijdselectie.

/form-booking
src/components/forms/FormBooking.astro
---
interface Props {
  heading?: string;
  subtext?: string;
  submitLabel?: string;
  timeSlots?: string[];
}

const {
  heading = "Plan een afspraak",
  subtext = "Kies een datum en tijdstip dat jou uitkomt. We bevestigen je afspraak binnen 1 uur via e-mail.",
  submitLabel = "Afspraak bevestigen",
  timeSlots = ["09:00", "09:30", "10:00", "10:30", "11:00", "13:00", "13:30", "14:00", "14:30", "15:00", "15:30"],
} = Astro.props;
---

<div class="fbk-wrap">
  <div class="fbk-header">
    <div class="fbk-icon" aria-hidden="true">📅</div>
    {heading && <h2 class="fbk-heading">{heading}</h2>}
    {subtext && <p class="fbk-subtext">{subtext}</p>}
  </div>
  <form class="fbk-form" onsubmit="return false;" novalidate>
    <div class="fbk-row">
      <div class="fbk-field">
        <label class="fbk-label" for="fbk-name">Naam *</label>
        <input class="fbk-input" type="text" id="fbk-name" name="name" placeholder="Jouw naam" required autocomplete="name" />
      </div>
      <div class="fbk-field">
        <label class="fbk-label" for="fbk-email">E-mailadres *</label>
        <input class="fbk-input" type="email" id="fbk-email" name="email" placeholder="jij@bedrijf.nl" required autocomplete="email" />
      </div>
    </div>
    <div class="fbk-row">
      <div class="fbk-field">
        <label class="fbk-label" for="fbk-phone">Telefoonnummer</label>
        <input class="fbk-input" type="tel" id="fbk-phone" name="phone" placeholder="+31 6 00 00 00 00" autocomplete="tel" />
      </div>
      <div class="fbk-field">
        <label class="fbk-label" for="fbk-type">Type afspraak *</label>
        <select class="fbk-select" id="fbk-type" name="meeting_type" required>
          <option value="">Selecteer type</option>
          <option>Kennismakingsgesprek (30 min)</option>
          <option>Strategiesessie (60 min)</option>
          <option>Campagne evaluatie (45 min)</option>
          <option>Onboarding gesprek (90 min)</option>
        </select>
      </div>
    </div>
    <div class="fbk-field">
      <label class="fbk-label" for="fbk-date">Gewenste datum *</label>
      <input class="fbk-input" type="date" id="fbk-date" name="date" required />
    </div>
    <div class="fbk-field">
      <label class="fbk-label">Voorkeurstijdstip *</label>
      <div class="fbk-slots">
        {timeSlots.map(slot => (
          <label class="fbk-slot">
            <input class="fbk-slot-input" type="radio" name="time_slot" value={slot} required />
            <span class="fbk-slot-label">{slot}</span>
          </label>
        ))}
      </div>
    </div>
    <div class="fbk-field">
      <label class="fbk-label" for="fbk-format">Vergaderformaat</label>
      <div class="fbk-format-group">
        {["Videocall (Teams/Zoom)", "Telefonisch", "Op locatie Amsterdam"].map(f => (
          <label class="fbk-format-item">
            <input class="fbk-format-radio" type="radio" name="format" value={f} />
            {f}
          </label>
        ))}
      </div>
    </div>
    <div class="fbk-field">
      <label class="fbk-label" for="fbk-notes">Wat wil je bespreken? (optioneel)</label>
      <textarea class="fbk-textarea" id="fbk-notes" name="notes" rows="3" placeholder="Bijv. we overwegen te starten met Google Ads voor ons e-commerce platform..."></textarea>
    </div>
    <button class="fbk-submit" type="submit">{submitLabel}</button>
  </form>
</div>

<style>
  .fbk-wrap { max-width: 620px; padding: 2rem 0; }
  .fbk-header { margin-bottom: 2rem; }
  .fbk-icon { font-size: 2rem; margin-bottom: 0.75rem; }
  .fbk-heading { font-size: 1.75rem; font-weight: 800; color: var(--color-primary, #0a0a0a); margin: 0 0 0.5rem; }
  .fbk-subtext { font-size: 0.95rem; color: #666; margin: 0; }
  .fbk-form { display: flex; flex-direction: column; gap: 1.25rem; }
  .fbk-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; }
  @media (max-width: 520px) { .fbk-row { grid-template-columns: 1fr; } }
  .fbk-field { display: flex; flex-direction: column; gap: 0.4rem; }
  .fbk-label { font-size: 0.85rem; font-weight: 600; color: var(--color-primary, #0a0a0a); }
  .fbk-input, .fbk-select, .fbk-textarea {
    padding: 0.7rem 0.9rem; border: 1.5px solid #ddd; border-radius: 8px;
    font-size: 0.95rem; color: var(--color-primary, #0a0a0a); background: #fff;
    transition: border-color 0.2s; font-family: inherit; box-sizing: border-box; width: 100%;
  }
  .fbk-input:focus, .fbk-select:focus, .fbk-textarea:focus { outline: none; border-color: var(--color-accent, #6366f1); box-shadow: 0 0 0 3px rgba(99,102,241,0.12); }
  .fbk-textarea { resize: vertical; min-height: 90px; }
  .fbk-slots { display: flex; flex-wrap: wrap; gap: 0.4rem; }
  .fbk-slot { cursor: pointer; }
  .fbk-slot-input { display: none; }
  .fbk-slot-label {
    display: block; padding: 0.45rem 0.9rem; background: #f5f5f5; border-radius: 6px;
    font-size: 0.85rem; font-weight: 500; color: #555; border: 1.5px solid transparent; transition: all 0.15s;
  }
  .fbk-slot-input:checked + .fbk-slot-label { background: #eef2ff; color: var(--color-accent, #6366f1); border-color: var(--color-accent, #6366f1); font-weight: 600; }
  .fbk-format-group { display: flex; flex-direction: column; gap: 0.5rem; }
  .fbk-format-item { display: flex; align-items: center; gap: 0.5rem; font-size: 0.9rem; color: #333; cursor: pointer; padding: 0.55rem 1rem; background: #f9f9f9; border-radius: 8px; border: 1.5px solid transparent; }
  .fbk-format-item:has(input:checked) { border-color: var(--color-accent, #6366f1); background: #eef2ff; color: var(--color-accent, #6366f1); }
  .fbk-format-radio { accent-color: var(--color-accent, #6366f1); }
  .fbk-submit {
    padding: 0.9rem 2rem; background: var(--color-accent, #6366f1); color: #fff;
    border: none; border-radius: 8px; font-size: 1rem; font-weight: 600;
    cursor: pointer; transition: opacity 0.2s; align-self: flex-start;
  }
  .fbk-submit:hover { opacity: 0.88; }
</style>

Props

Prop Type Default Beschrijving
headline string Formuliertitel

* = verplicht