src/components/forms/FormPayment.astro
---
interface Props {
heading?: string;
amount?: string;
description?: string;
submitLabel?: string;
}
const {
heading = "Betalingsgegevens",
amount = "€ 2.500,00",
description = "BLURR Growth pakket — maand 1",
submitLabel = "Betaling bevestigen",
} = Astro.props;
---
<div class="fpm-wrap">
<div class="fpm-order-summary">
<div class="fpm-order-label">Totaal te betalen</div>
<div class="fpm-order-amount">{amount}</div>
<div class="fpm-order-desc">{description}</div>
</div>
<h2 class="fpm-heading">{heading}</h2>
<form class="fpm-form" onsubmit="return false;" novalidate aria-label="Betalingsformulier (demo)">
<div class="fpm-methods" role="group" aria-label="Betaalmethode">
{[
{ id: "ideal", label: "iDEAL", icon: "🏦" },
{ id: "card", label: "Creditcard", icon: "💳" },
{ id: "sepa", label: "SEPA Bankoverschrijving", icon: "🌍" },
].map((m, i) => (
<label class="fpm-method">
<input class="fpm-method-input" type="radio" name="payment_method" value={m.id} checked={i === 0} />
<span class="fpm-method-box">
<span class="fpm-method-icon" aria-hidden="true">{m.icon}</span>
{m.label}
</span>
</label>
))}
</div>
<!-- Card fields (visual only) -->
<div class="fpm-card-fields">
<div class="fpm-field">
<label class="fpm-label" for="fpm-holder">Naam kaarthouder</label>
<input class="fpm-input" type="text" id="fpm-holder" name="card_holder" placeholder="Jan de Vries" autocomplete="cc-name" />
</div>
<div class="fpm-field">
<label class="fpm-label" for="fpm-number">Kaartnummer</label>
<input class="fpm-input fpm-input--card" type="text" id="fpm-number" name="card_number" placeholder="1234 5678 9012 3456" maxlength="19" autocomplete="cc-number" inputmode="numeric" />
</div>
<div class="fpm-row">
<div class="fpm-field">
<label class="fpm-label" for="fpm-expiry">Vervaldatum</label>
<input class="fpm-input" type="text" id="fpm-expiry" name="expiry" placeholder="MM / JJ" maxlength="7" autocomplete="cc-exp" inputmode="numeric" />
</div>
<div class="fpm-field">
<label class="fpm-label" for="fpm-cvv">
CVV
<span class="fpm-tooltip" title="3-cijferige code op de achterkant van je kaart">?</span>
</label>
<input class="fpm-input" type="text" id="fpm-cvv" name="cvv" placeholder="•••" maxlength="4" autocomplete="cc-csc" inputmode="numeric" />
</div>
</div>
</div>
<div class="fpm-security">
<span class="fpm-security-icon" aria-hidden="true">🔒</span>
<span>Betalingen worden verwerkt via een beveiligde SSL-verbinding</span>
</div>
<button class="fpm-submit" type="submit">{submitLabel}</button>
</form>
</div>
<style>
.fpm-wrap { max-width: 500px; padding: 2rem 0; }
.fpm-order-summary {
background: var(--color-primary, #0a0a0a); color: #fff;
padding: 1.5rem; border-radius: 12px; margin-bottom: 2rem; text-align: center;
}
.fpm-order-label { font-size: 0.75rem; opacity: 0.6; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 0.25rem; }
.fpm-order-amount { font-size: 2rem; font-weight: 800; margin-bottom: 0.25rem; }
.fpm-order-desc { font-size: 0.875rem; opacity: 0.7; }
.fpm-heading { font-size: 1.4rem; font-weight: 800; color: var(--color-primary, #0a0a0a); margin: 0 0 1.5rem; }
.fpm-form { display: flex; flex-direction: column; gap: 1.25rem; }
.fpm-methods { display: flex; gap: 0.75rem; flex-wrap: wrap; }
.fpm-method { cursor: pointer; flex: 1; min-width: 120px; }
.fpm-method-input { display: none; }
.fpm-method-box {
display: flex; align-items: center; justify-content: center; gap: 0.5rem;
padding: 0.75rem; background: #f5f5f5; border: 1.5px solid transparent;
border-radius: 8px; font-size: 0.875rem; font-weight: 500; color: #444; transition: all 0.15s;
}
.fpm-method-input:checked + .fpm-method-box { border-color: var(--color-accent, #6366f1); background: #eef2ff; color: var(--color-accent, #6366f1); font-weight: 600; }
.fpm-method-icon { font-size: 1.1rem; }
.fpm-card-fields { display: flex; flex-direction: column; gap: 1rem; background: #f9f9f9; padding: 1.25rem; border-radius: 10px; }
.fpm-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.fpm-field { display: flex; flex-direction: column; gap: 0.35rem; }
.fpm-label { font-size: 0.82rem; font-weight: 600; color: var(--color-primary, #0a0a0a); display: flex; align-items: center; gap: 0.35rem; }
.fpm-tooltip {
display: inline-flex; align-items: center; justify-content: center;
width: 16px; height: 16px; border-radius: 50%; background: #ddd; color: #555;
font-size: 0.65rem; font-weight: 700; cursor: help;
}
.fpm-input {
padding: 0.7rem 0.9rem; border: 1.5px solid #ddd; border-radius: 8px;
font-size: 0.925rem; color: var(--color-primary, #0a0a0a); background: #fff;
transition: border-color 0.2s; font-family: inherit; box-sizing: border-box; width: 100%;
}
.fpm-input:focus { outline: none; border-color: var(--color-accent, #6366f1); box-shadow: 0 0 0 3px rgba(99,102,241,0.12); }
.fpm-security { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8rem; color: #888; }
.fpm-security-icon { font-size: 1rem; }
.fpm-submit {
padding: 0.95rem; background: var(--color-accent, #6366f1); color: #fff;
border: none; border-radius: 8px; font-size: 1rem; font-weight: 600;
cursor: pointer; transition: opacity 0.2s;
}
.fpm-submit:hover { opacity: 0.88; }
</style>
Props
| Prop | Type | Default | Beschrijving |
|---|---|---|---|
headline | string | — | Formuliertitel |
amount | string | — | Bedrag |
* = verplicht