Files
preregister/resources/views/components/blocks/form.blade.php
bert.hausmans 9f8052f683 fix(public): do not expose coupon code after preregistration
Codes are still created and stored for Mailwizz; JSON response omits
coupon_code. Thank-you UI explains email delivery instead of showing code.

Made-with: Cursor
2026-04-05 11:22:38 +02:00

181 lines
12 KiB
PHP

@props([
'block',
'page',
])
@php
/** @var \App\Models\PageBlock $block */
/** @var \App\Models\PreregistrationPage $page */
$c = $block->content ?? [];
$fields = data_get($c, 'fields', []);
$showIcons = filter_var(data_get($c, 'show_field_icons', true), FILTER_VALIDATE_BOOLEAN);
$btnColor = (string) data_get($c, 'button_color', '#F47B20');
$btnText = (string) data_get($c, 'button_text_color', '#FFFFFF');
$privacyText = data_get($c, 'privacy_text');
$privacyUrl = data_get($c, 'privacy_url');
@endphp
<div class="w-full space-y-4">
@if (filled(data_get($c, 'title')))
<h2 class="text-center text-xl font-semibold text-white sm:text-2xl">{{ data_get($c, 'title') }}</h2>
@endif
@if (filled(data_get($c, 'description')))
<p class="text-center text-sm leading-relaxed text-white/85 sm:text-[15px]">{{ data_get($c, 'description') }}</p>
@endif
<div x-show="phase === 'active'" x-cloak>
<form x-ref="form" class="space-y-4" @submit.prevent="submitForm()">
<div x-show="formError !== ''" x-cloak class="rounded-xl border border-red-700 bg-red-600 px-4 py-3 text-sm font-medium leading-snug text-white" x-text="formError"></div>
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
@foreach (['first_name', 'last_name'] as $fk)
@php
$fc = is_array($fields[$fk] ?? null) ? $fields[$fk] : [];
$enabled = filter_var($fc['enabled'] ?? true, FILTER_VALIDATE_BOOLEAN);
$req = filter_var($fc['required'] ?? true, FILTER_VALIDATE_BOOLEAN);
@endphp
@if ($enabled)
<div>
<label for="pf-{{ $fk }}" class="sr-only">{{ $fc['label'] ?? $fk }}</label>
<div class="relative">
@if ($showIcons)
<span class="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-white/40" aria-hidden="true">
@if ($fk === 'first_name')
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z" /></svg>
@else
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 002.625.372 9.337 9.337 0 004.121-.952 4.125 4.125 0 00-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 018.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0111.964-3.07M12 6.375a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0z" /></svg>
@endif
</span>
@endif
<input
id="pf-{{ $fk }}"
type="text"
name="{{ $fk }}"
autocomplete="{{ $fk === 'first_name' ? 'given-name' : 'family-name' }}"
@if ($req) required @endif
maxlength="255"
x-model="{{ $fk }}"
class="min-h-[48px] w-full rounded-xl border border-white/35 bg-white/15 py-3 text-[15px] text-white placeholder-white/55 shadow-sm transition duration-200 ease-out focus:border-festival focus:outline-none focus:ring-2 focus:ring-festival/45 {{ $showIcons ? 'pl-11 pr-4' : 'px-4' }}"
placeholder="{{ $fc['placeholder'] ?? $fc['label'] ?? '' }}"
>
</div>
<p x-show="fieldErrors.{{ $fk }}" x-cloak class="mt-2 text-sm text-red-200" x-text="fieldErrors.{{ $fk }} ? fieldErrors.{{ $fk }}[0] : ''"></p>
</div>
@endif
@endforeach
</div>
@php
$emailFc = is_array($fields['email'] ?? null) ? $fields['email'] : [];
$emailOn = filter_var($emailFc['enabled'] ?? true, FILTER_VALIDATE_BOOLEAN);
@endphp
@if ($emailOn)
<div>
<label for="pf-email" class="sr-only">{{ $emailFc['label'] ?? __('Email') }}</label>
<div class="relative">
@if ($showIcons)
<span class="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-white/40" aria-hidden="true">
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" /></svg>
</span>
@endif
<input
id="pf-email"
type="email"
name="email"
autocomplete="email"
required
maxlength="255"
x-model="email"
class="min-h-[48px] w-full rounded-xl border border-white/35 bg-white/15 py-3 text-[15px] text-white placeholder-white/55 shadow-sm transition duration-200 ease-out focus:border-festival focus:outline-none focus:ring-2 focus:ring-festival/45 {{ $showIcons ? 'pl-11 pr-4' : 'px-4' }}"
placeholder="{{ $emailFc['placeholder'] ?? $emailFc['label'] ?? '' }}"
>
</div>
<p x-show="fieldErrors.email" x-cloak class="mt-2 text-sm text-red-200" x-text="fieldErrors.email ? fieldErrors.email[0] : ''"></p>
</div>
@endif
@php
$phoneFc = is_array($fields['phone'] ?? null) ? $fields['phone'] : [];
$phoneOn = filter_var($phoneFc['enabled'] ?? false, FILTER_VALIDATE_BOOLEAN);
$phoneReq = filter_var($phoneFc['required'] ?? false, FILTER_VALIDATE_BOOLEAN);
@endphp
@if ($phoneOn)
<div>
<label for="pf-phone" class="sr-only">{{ $phoneFc['label'] ?? __('Phone') }}</label>
<div class="relative">
@if ($showIcons)
<span class="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-white/40" aria-hidden="true">
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 002.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106c-.44-.11-.902.055-1.173.417l-.97 1.293c-.282.376-.769.608-1.25.608H9.75a2.25 2.25 0 01-2.25-2.25V9.75c0-.481.232-.968.608-1.25l1.293-.97c.362-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 00-1.091-.852H4.5A2.25 2.25 0 002.25 4.5v2.25z" /></svg>
</span>
@endif
<input
id="pf-phone"
type="tel"
name="phone"
autocomplete="tel"
maxlength="20"
@if ($phoneReq) required @endif
x-model="phone"
class="min-h-[48px] w-full rounded-xl border border-white/35 bg-white/15 py-3 text-[15px] text-white placeholder-white/55 shadow-sm transition duration-200 ease-out focus:border-festival focus:outline-none focus:ring-2 focus:ring-festival/45 {{ $showIcons ? 'pl-11 pr-4' : 'px-4' }}"
placeholder="{{ $phoneFc['placeholder'] ?? $phoneFc['label'] ?? '' }}"
>
</div>
<p x-show="fieldErrors.phone" x-cloak class="mt-2 text-sm text-red-200" x-text="fieldErrors.phone ? fieldErrors.phone[0] : ''"></p>
</div>
@endif
@if (filled($privacyText))
<p class="text-center text-xs leading-relaxed text-white/60">
@if (filled($privacyUrl))
<a href="{{ e($privacyUrl) }}" class="underline decoration-white/30 underline-offset-2 hover:text-white" target="_blank" rel="noopener noreferrer">{{ $privacyText }}</a>
@else
{{ $privacyText }}
@endif
</p>
@endif
<button
type="submit"
class="mt-2 min-h-[52px] w-full rounded-xl px-6 py-3.5 text-base font-bold tracking-wide shadow-lg transition duration-200 ease-out hover:scale-[1.02] hover:brightness-110 focus:outline-none focus:ring-2 focus:ring-festival focus:ring-offset-2 focus:ring-offset-black/80 active:scale-[0.99] disabled:cursor-not-allowed disabled:opacity-60 disabled:hover:scale-100 sm:min-h-[56px] sm:text-lg"
style="background-color: {{ e($btnColor) }}; color: {{ e($btnText) }};"
:disabled="submitting"
>
<span x-show="!submitting" x-text="formButtonLabel"></span>
<span x-show="submitting" x-cloak>{{ __('Sending…') }}</span>
</button>
</form>
</div>
<div x-show="phase === 'thanks'" x-cloak class="space-y-6">
<div class="flex justify-center">
<div class="animate-preregister-in flex h-16 w-16 items-center justify-center rounded-full bg-emerald-500/20 text-emerald-300 ring-2 ring-emerald-400/50">
<svg class="h-9 w-9" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" />
</svg>
</div>
</div>
<p class="whitespace-pre-line text-center text-base leading-relaxed text-white/95 sm:text-lg" x-text="thankYouMessage"></p>
<p class="mt-4 text-center text-sm leading-relaxed text-white/65">
{{ __('Je persoonlijke kortingscode wordt niet hier getoond. Je ontvangt die per e-mail wanneer de organisatie de ticketverkoop opent — houd je inbox in de gaten.') }}
</p>
<p
x-show="redirectSecondsLeft !== null && redirectSecondsLeft > 0"
x-cloak
class="text-center text-sm text-white/75"
x-text="(strings.redirectCountdown || '').replace(':seconds', String(redirectSecondsLeft))"
></p>
<div class="rounded-xl border border-white/15 bg-black/30 px-4 py-4 text-center">
<p class="text-sm font-medium text-white/90">{{ __('Deel deze pagina') }}</p>
<button
type="button"
class="mt-3 inline-flex min-h-[44px] w-full items-center justify-center rounded-lg border border-white/25 bg-white/10 px-4 py-2 text-sm font-semibold text-white hover:bg-white/15"
@click="copyPageLink()"
>
{{ __('Link kopiëren') }}
</button>
<p x-show="copyFeedback !== ''" x-cloak class="mt-2 text-xs text-emerald-300" x-text="copyFeedback"></p>
</div>
</div>
</div>