feat: refactor to cards
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
{% extends 'layout.html.twig' %}
|
||||
|
||||
{% block title %}Booking Error{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="max-w-lg mx-auto">
|
||||
<div class="bg-red-50 border border-red-200 rounded-lg p-6">
|
||||
<div class="flex">
|
||||
<div class="flex-shrink-0">
|
||||
<svg class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<h3 class="text-sm font-medium text-red-800">
|
||||
Booking Error
|
||||
</h3>
|
||||
<div class="mt-2 text-sm text-red-700">
|
||||
{% for flash_message in app.flashes('error') %}
|
||||
<p>{{ flash_message }}</p>
|
||||
{% else %}
|
||||
<p>Es ist ein Fehler beim Starten des Buchungsvorgangs aufgetreten.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<div class="flex space-x-2">
|
||||
<a href="https://www.ep-reisen.de" class="button bg-button bg-button--secondary">
|
||||
Zur Startseite
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,78 @@
|
||||
{% extends 'layout.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
{% include '_partials/_flashes.html.twig' %}
|
||||
<h1>Neue Buchung</h1>
|
||||
{% if bookingCreateDto.bookingStatus == 'A' %}
|
||||
<div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">
|
||||
<div class="flex items-start">
|
||||
<svg class="w-5 h-5 text-blue-600 mt-0.5 mr-3" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
<div>
|
||||
<h3 class="text-blue-900 font-semibold">Buchung auf Anfrage</h3>
|
||||
<p class="text-blue-800 text-sm mt-1">Diese Reise kann nur auf Anfrage gebucht werden. Deine Buchung wird nach Eingang geprüft und du erhältst eine Bestätigung.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="grid grid-cols-3 gap-8">
|
||||
<div id="form-wrapper" class="col-span-2">
|
||||
<h2 class="pb-4">
|
||||
Unterkunft
|
||||
</h2>
|
||||
{{ form_start(form) }}
|
||||
{% do form.roomSelections.setRendered %}
|
||||
{# This block contains the room selection form fields #}
|
||||
{% block room_selection_form %}
|
||||
<div id="room-selection-form"{% if htmx_oob_swap is defined and htmx_oob_swap %} hx-swap-oob="true"{% endif %}>
|
||||
{{ form_errors(form) }}
|
||||
{% if groupedRooms.by_room is not empty %}
|
||||
<h3>
|
||||
Zimmer
|
||||
</h3>
|
||||
{% for roomId, room in groupedRooms.by_room %}
|
||||
{{ form_row(form.roomSelections[roomId], {
|
||||
'attr': {
|
||||
'hx-post': path('app_booking_create_step_1_refresh'),
|
||||
'hx-swap': 'none',
|
||||
'hx-trigger': 'change'
|
||||
}
|
||||
}) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if groupedRooms.by_pax is not empty %}
|
||||
<h3>
|
||||
Betten
|
||||
</h3>
|
||||
{% for roomId, room in groupedRooms.by_pax %}
|
||||
{{ form_row(form.roomSelections[roomId], {
|
||||
'attr': {
|
||||
'hx-post': path('app_booking_create_step_1_refresh'),
|
||||
'hx-swap': 'none',
|
||||
'hx-trigger': 'change'
|
||||
}
|
||||
}) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
<div class="flex justify-end pt-4">
|
||||
<button type="submit" class="button bg-button bg-button--secondary" {{ stimulus_action('loading', 'toggle') }}>Weiter</button>
|
||||
</div>
|
||||
{{ form_rest(form) }}
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
{% block booking_summary %}
|
||||
<div id="booking-summary"{% if htmx_oob_swap is defined and htmx_oob_swap %} hx-swap-oob="true"{% endif %}>
|
||||
{% include 'booking/_summary.html.twig' with {
|
||||
'bookingCreateDto': bookingCreateDto,
|
||||
'participantCount': participantCount,
|
||||
'pricingData': pricingData,
|
||||
'groupedSelectedRooms': groupedSelectedRooms,
|
||||
'assignmentCounts': []
|
||||
} %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,76 @@
|
||||
{% extends 'layout.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
{% include '_partials/_flashes.html.twig' %}
|
||||
<div {{ stimulus_controller('toast') }}></div>
|
||||
<h1>Neue Buchung</h1>
|
||||
|
||||
<div class="grid grid-cols-3 gap-8">
|
||||
{# Main content area - cards grid #}
|
||||
{% block participant_cards %}
|
||||
<div id="main-content" class="col-span-2">
|
||||
{{ form_start(form, {
|
||||
'attr': {
|
||||
'hx-post': path('app_booking_create_step_2'),
|
||||
'hx-target': '#main-content',
|
||||
'hx-swap': 'innerHTML'
|
||||
}
|
||||
}) }}
|
||||
|
||||
<h2>Teilnehmer</h2>
|
||||
|
||||
{# Display form-level validation errors #}
|
||||
{% if form.vars.submitted and not form.vars.valid %}
|
||||
<div class="mb-4 p-4 bg-red-50 border border-red-200 rounded-lg">
|
||||
<div class="flex items-start">
|
||||
<svg class="w-5 h-5 text-red-600 mr-2 mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
<div>
|
||||
<p class="font-semibold text-red-800 mb-1">Bitte überprüfe die Teilnehmerdaten</p>
|
||||
<p class="text-sm text-red-700">Einige Teilnehmer haben noch unvollständige oder fehlerhafte Angaben. Bitte bearbeite die markierten Teilnehmer.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div id="participant-cards-grid" class="space-y-4">
|
||||
{% for cardData in cardsData %}
|
||||
{% set hasErrors = loop.index0 in participantErrors|default([]) %}
|
||||
{% include 'booking/_participant_card.html.twig' with {
|
||||
'cardData': cardData,
|
||||
'index': loop.index0,
|
||||
'mode': 'create',
|
||||
'hasErrors': hasErrors
|
||||
} %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between mt-8">
|
||||
<a href="{{ path('app_booking_create_step_1') }}" class="button bg-button bg-button--secondary">
|
||||
Zurück
|
||||
</a>
|
||||
<button type="submit" class="button bg-button bg-button--secondary">
|
||||
Weiter
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{{ form_rest(form) }}
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{# Sidebar summary #}
|
||||
{% block booking_summary %}
|
||||
<div id="booking-summary"{% if htmx_oob_swap|default(false) %} hx-swap-oob="true"{% endif %}>
|
||||
{% include 'booking/_summary.html.twig' with {
|
||||
'bookingCreateDto': bookingDto,
|
||||
'participantCount': summaryData.participantsCount,
|
||||
'groupedSelectedRooms': summaryData.groupedSelectedRooms,
|
||||
'assignmentCounts': summaryData.assignmentCounts,
|
||||
'pricingData': pricingData
|
||||
} %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,89 @@
|
||||
{% extends 'layout.html.twig' %}
|
||||
|
||||
{# Local form theme override for consistent fieldset rendering #}
|
||||
{% use 'forms.html.twig' %}
|
||||
|
||||
{% block form_row %}
|
||||
{%- if form.vars.expanded is defined and form.vars.expanded -%}
|
||||
{# Expanded forms get fieldset wrapper #}
|
||||
<fieldset class="mb-1">
|
||||
<legend class="font-semibold mb-1">
|
||||
{{- form.vars.label -}}
|
||||
</legend>
|
||||
{{- form_widget(form, {
|
||||
'attr': attr|default({})
|
||||
}) -}}
|
||||
{{- form_errors(form) -}}
|
||||
{{- form_help(form) -}}
|
||||
</fieldset>
|
||||
{%- else -%}
|
||||
{{- parent() -}}
|
||||
{%- endif -%}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% include '_partials/_flashes.html.twig' %}
|
||||
|
||||
<h1>Neue Buchung</h1>
|
||||
|
||||
<div class="grid grid-cols-3 gap-8">
|
||||
<div id="form-wrapper" class="col-span-2">
|
||||
<h2 class="mb-6">Zahlungsart</h2>
|
||||
|
||||
{{ form_start(form, {
|
||||
'attr': {
|
||||
'novalidate': 'novalidate',
|
||||
'hx-post': path('app_booking_create_step_3'),
|
||||
'hx-target': '#form-wrapper',
|
||||
'hx-select': '#form-wrapper',
|
||||
'hx-swap': 'outerHTML'
|
||||
}
|
||||
}) }}
|
||||
|
||||
{# Payment method selection with HTMX #}
|
||||
<div id="form-payment"
|
||||
hx-post="{{ path('app_booking_create_step_3_refresh') }}"
|
||||
hx-trigger="change from:input[type='radio']"
|
||||
hx-target="#form-payment"
|
||||
hx-select="#form-payment"
|
||||
hx-swap="outerHTML">
|
||||
{{ form_row(form.paymentMethod) }}
|
||||
|
||||
{# Bank account section - conditionally rendered #}
|
||||
{% if form.bankAccount is defined %}
|
||||
<div class="border border-gray-300 rounded-lg p-4 bg-gray-50 mt-4">
|
||||
<h3 class="font-semibold text-lg mb-4">Bankverbindung</h3>
|
||||
|
||||
<div class="space-y-4">
|
||||
{{ form_row(form.bankAccount.iban) }}
|
||||
{{ form_row(form.bankAccount.accountHolder) }}
|
||||
{{ form_row(form.bankAccount.bankName) }}
|
||||
|
||||
<div class="mt-6 p-4 bg-blue-50 border border-blue-200 rounded">
|
||||
{{ form_row(form.bankAccount.sepaMandateAccepted, {
|
||||
'label_attr': {'class': 'text-sm'}
|
||||
}) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between pt-6">
|
||||
<a href="{{ path('app_booking_create_step_2') }}" class="button bg-button bg-button--secondary">Zurück</a>
|
||||
<button type="submit" class="button bg-button bg-button--secondary" {{ stimulus_action('loading', 'toggle') }}>Weiter</button>
|
||||
</div>
|
||||
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
|
||||
<div id="booking-summary">
|
||||
{% include 'booking/_summary.html.twig' with {
|
||||
'bookingCreateDto': bookingCreateDto,
|
||||
'participantCount': participantsCount,
|
||||
'groupedSelectedRooms': groupedSelectedRooms,
|
||||
'assignmentCounts': assignmentCounts
|
||||
} %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,316 @@
|
||||
{% extends 'layout.html.twig' %}
|
||||
|
||||
{% block title %}Buchung bestätigen{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% include '_partials/_flashes.html.twig' %}
|
||||
|
||||
<h1>Neue Buchung</h1>
|
||||
|
||||
{% if bookingCreateDto.bookingStatus == 'A' %}
|
||||
<div class="bg-amber-50 border border-amber-200 rounded-lg p-4 mb-6">
|
||||
<div class="flex items-start">
|
||||
<svg class="w-5 h-5 text-amber-600 mt-0.5 mr-3 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
<div>
|
||||
<h3 class="text-amber-900 font-semibold">Achtung: Buchung auf Anfrage</h3>
|
||||
<p class="text-amber-800 text-sm mt-1">Diese Buchung erfolgt auf Anfrage. Nach der Absendung wird deine Anfrage geprüft. Du erhältst anschließend eine verbindliche Buchungsbestätigung oder eine Absage per E-Mail.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div id="form-wrapper">
|
||||
<h2 class="mb-6">Buchung bestätigen</h2>
|
||||
|
||||
{# Travel Summary #}
|
||||
<div class="mb-8 p-6 bg-gray-50 rounded-lg border border-gray-200">
|
||||
<h3 class="text-xl font-semibold mb-4">Reise</h3>
|
||||
<dl class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<dt class="font-semibold text-gray-700">Reiseziel</dt>
|
||||
<dd>{{ bookingCreateDto.travel.label }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="font-semibold text-gray-700">Zeitraum</dt>
|
||||
<dd>{{ bookingCreateDto.travel.dateFrom|date('d.m.Y') }} - {{ bookingCreateDto.travel.dateTo|date('d.m.Y') }}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
{# Rooms Summary #}
|
||||
<div class="mb-8 p-6 bg-gray-50 rounded-lg border border-gray-200">
|
||||
<h3 class="text-xl font-semibold mb-4">Zimmer / Unterkünfte</h3>
|
||||
{% if pricingData.rooms is not empty %}
|
||||
<ul class="space-y-2">
|
||||
{% for roomPricing in pricingData.rooms %}
|
||||
<li class="flex justify-between">
|
||||
<span>{{ roomPricing.quantity }}x {{ roomPricing.label }}</span>
|
||||
<span class="font-semibold">{{ roomPricing.totalPrice|number_format(2, ',', '.') }} €</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{# Participants Summary #}
|
||||
<div class="mb-8 p-6 bg-gray-50 rounded-lg border border-gray-200">
|
||||
<h3 class="text-xl font-semibold mb-4">Teilnehmer ({{ participantsCount }})</h3>
|
||||
{% for participant in bookingCreateDto.participants %}
|
||||
<div class="mb-6 pb-6 {% if not loop.last %}border-b border-gray-300{% endif %}">
|
||||
<h4 class="font-semibold text-lg mb-3">
|
||||
{{ participant.firstName }} {{ participant.lastName }}
|
||||
{% if loop.first %}<span class="text-sm text-gray-600">(Anmelder)</span>{% endif %}
|
||||
</h4>
|
||||
|
||||
<dl class="grid grid-cols-2 gap-4 text-sm">
|
||||
{# Personal Data #}
|
||||
{% if participant.dateOfBirth %}
|
||||
<div>
|
||||
<dt class="text-gray-600 font-semibold">Geburtsdatum</dt>
|
||||
<dd>{{ participant.dateOfBirth|date('d.m.Y') }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if participant.gender %}
|
||||
<div>
|
||||
<dt class="text-gray-600 font-semibold">Geschlecht</dt>
|
||||
<dd>{{ participant.gender == 'M' ? 'Männlich' : 'Weiblich' }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if participant.email %}
|
||||
<div>
|
||||
<dt class="text-gray-600 font-semibold">E-Mail</dt>
|
||||
<dd>{{ participant.email }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if participant.mobile %}
|
||||
<div>
|
||||
<dt class="text-gray-600 font-semibold">Telefon</dt>
|
||||
<dd>{{ participant.mobile }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if participant.nationality %}
|
||||
<div>
|
||||
<dt class="text-gray-600 font-semibold">Nationalität</dt>
|
||||
<dd>{{ participant.nationality }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Address #}
|
||||
{% if participant.address and (participant.address.street or participant.address.city) %}
|
||||
<div class="col-span-2">
|
||||
<dt class="text-gray-600 font-semibold">Adresse</dt>
|
||||
<dd>
|
||||
{% if participant.address.street %}{{ participant.address.street }}<br>{% endif %}
|
||||
{% if participant.address.postCode or participant.address.city %}
|
||||
{{ participant.address.postCode }} {{ participant.address.city }}<br>
|
||||
{% endif %}
|
||||
{% if participant.address.country %}{{ participant.address.country }}{% endif %}
|
||||
</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Room Assignment #}
|
||||
{% set assignedRoom = bookingCreateDto.travel.getRoomById(participant.assignedRoomId) %}
|
||||
{% if assignedRoom %}
|
||||
<div>
|
||||
<dt class="text-gray-600 font-semibold">Zimmer</dt>
|
||||
<dd>{{ assignedRoom.label }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Room Remarks #}
|
||||
{% if participant.remarksRoom %}
|
||||
<div>
|
||||
<dt class="text-gray-600 font-semibold">Zimmerwunsch</dt>
|
||||
<dd>{{ participant.remarksRoom }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Transportation Services #}
|
||||
{% if participant.transportationOutbound %}
|
||||
<div>
|
||||
<dt class="text-gray-600 font-semibold">Anreise</dt>
|
||||
<dd>{{ participant.transportationOutbound.label }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if participant.transportationInbound %}
|
||||
<div>
|
||||
<dt class="text-gray-600 font-semibold">Abreise</dt>
|
||||
<dd>{{ participant.transportationInbound.label }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Pickup Location #}
|
||||
{% if participant.pickup %}
|
||||
<div>
|
||||
<dt class="text-gray-600 font-semibold">Zu- und Ausstieg</dt>
|
||||
<dd>{{ participant.pickup.label }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Parking & License Plate #}
|
||||
{% if participant.parking %}
|
||||
<div>
|
||||
<dt class="text-gray-600 font-semibold">Parkplatz</dt>
|
||||
<dd>Ja</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if participant.licensePlate %}
|
||||
<div>
|
||||
<dt class="text-gray-600 font-semibold">Kennzeichen</dt>
|
||||
<dd>{{ participant.licensePlate }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Board Services #}
|
||||
{% if participant.board is not empty %}
|
||||
<div class="col-span-2">
|
||||
<dt class="text-gray-600 font-semibold mb-1">Verpflegung</dt>
|
||||
<dd>
|
||||
<ul class="list-disc list-inside">
|
||||
{% for boardItem in participant.board %}
|
||||
<li>{{ boardItem.label }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Ski Pass #}
|
||||
{% if participant.skiPass %}
|
||||
<div class="col-span-2">
|
||||
<dt class="text-gray-600 font-semibold">Skipass</dt>
|
||||
<dd>{{ participant.skiPass.label }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Rentals #}
|
||||
{% if participant.rentals is not empty %}
|
||||
<div class="col-span-2">
|
||||
<dt class="text-gray-600 font-semibold mb-1">Ausrüstung</dt>
|
||||
<dd>
|
||||
<ul class="list-disc list-inside">
|
||||
{% for rental in participant.rentals %}
|
||||
<li>{{ rental.label }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Rental Insurance #}
|
||||
{% if participant.rentalInsuranceSelected and participant.rentalInsurance %}
|
||||
<div class="col-span-2">
|
||||
<dt class="text-gray-600 font-semibold">Leihmaterial-Versicherung</dt>
|
||||
<dd>{{ participant.rentalInsurance.label }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Body Dimensions (if rentals selected) #}
|
||||
{% if participant.rentals is not empty %}
|
||||
{% if participant.height or participant.weight or participant.shoeSize %}
|
||||
<div class="col-span-2">
|
||||
<dt class="text-gray-600 font-semibold mb-1">Körpermaße</dt>
|
||||
<dd>
|
||||
{% if participant.height %}Größe: {{ participant.height }} cm{% endif %}
|
||||
{% if participant.weight %}{% if participant.height %}, {% endif %}Gewicht: {{ participant.weight }} kg{% endif %}
|
||||
{% if participant.shoeSize %}{% if participant.height or participant.weight %}, {% endif %}Schuhgröße: {{ participant.shoeSize }}{% endif %}
|
||||
</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{# Courses #}
|
||||
{% if participant.courses is not empty %}
|
||||
<div class="col-span-2">
|
||||
<dt class="text-gray-600 font-semibold mb-1">Kurse</dt>
|
||||
<dd>
|
||||
<ul class="list-disc list-inside">
|
||||
{% for course in participant.courses %}
|
||||
<li>{{ course.label }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Additional Services #}
|
||||
{% if participant.additionalServices is not empty %}
|
||||
<div class="col-span-2">
|
||||
<dt class="text-gray-600 font-semibold mb-1">Zusatzleistungen</dt>
|
||||
<dd>
|
||||
<ul class="list-disc list-inside">
|
||||
{% for service in participant.additionalServices %}
|
||||
<li>{{ service.label }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Insurance #}
|
||||
{% if participant.insurance %}
|
||||
<div class="col-span-2">
|
||||
<dt class="text-gray-600 font-semibold">Reiseversicherung</dt>
|
||||
<dd>{{ participant.insurance.label }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
</dl>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{# Payment Summary #}
|
||||
<div class="mb-8 p-6 bg-gray-50 rounded-lg border border-gray-200">
|
||||
<h3 class="text-xl font-semibold mb-4">Zahlungsart</h3>
|
||||
<dl class="space-y-2">
|
||||
<div>
|
||||
<dt class="font-semibold text-gray-700">Gewählte Zahlungsart</dt>
|
||||
<dd>
|
||||
{% if bookingCreateDto.paymentMethod == constant('App\\BusProNet\\Constants::PAYMENT_METHOD_DEBIT') %}
|
||||
Lastschrift (Einzugsermächtigungsverfahren)
|
||||
{% else %}
|
||||
Überweisung
|
||||
{% endif %}
|
||||
</dd>
|
||||
</div>
|
||||
{% if bookingCreateDto.paymentMethod == constant('App\\BusProNet\\Constants::PAYMENT_METHOD_DEBIT') and bookingCreateDto.bankAccount %}
|
||||
<div>
|
||||
<dt class="font-semibold text-gray-700">IBAN</dt>
|
||||
<dd class="font-mono">{{ bookingCreateDto.bankAccount.iban }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="font-semibold text-gray-700">Kontoinhaber</dt>
|
||||
<dd>{{ bookingCreateDto.bankAccount.accountHolder }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
{# Confirmation Form #}
|
||||
{{ form_start(form, {
|
||||
'attr': {
|
||||
'novalidate': 'novalidate',
|
||||
'hx-post': path('app_booking_create_step_4'),
|
||||
'hx-target': '#form-wrapper',
|
||||
'hx-select': '#form-wrapper',
|
||||
'hx-swap': 'outerHTML'
|
||||
}
|
||||
}) }}
|
||||
|
||||
<div class="mb-8 p-6 bg-blue-50 border border-blue-200 rounded-lg">
|
||||
{{ form_row(form.confirmationAccepted, {
|
||||
'label_attr': {'class': 'text-base font-semibold'}
|
||||
}) }}
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between pt-6">
|
||||
<a href="{{ path('app_booking_create_step_3') }}" class="button bg-button bg-button--secondary">Zurück</a>
|
||||
<button type="submit" class="button bg-button bg-button--primary" {{ stimulus_action('loading', 'toggle') }}>Verbindlich buchen</button>
|
||||
</div>
|
||||
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,23 @@
|
||||
{% extends 'layout.html.twig' %}
|
||||
|
||||
{% block title %}Buchung erfolgreich{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-2xl mx-auto text-center py-12">
|
||||
<h1 class="text-3xl font-bold mb-4">Buchung erfolgreich abgeschlossen</h1>
|
||||
|
||||
<p class="text-xl mb-8">
|
||||
Deine Buchungsnummer lautet <strong class="font-mono">{{ bookingNumber }}</strong>
|
||||
</p>
|
||||
|
||||
<div class="bg-blue-50 border border-blue-200 rounded-lg p-6 mb-8">
|
||||
<p class="text-gray-700">
|
||||
Du erhältst in Kürze eine Bestätigungs-E-Mail mit allen Details zu Deiner Buchung.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<a href="https://www.ep-reisen.de" class="button bg-button bg-button--primary">
|
||||
Zurück zur Startseite
|
||||
</a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user