wip
This commit is contained in:
@@ -31,6 +31,10 @@ export default class extends Controller {
|
|||||||
} else {
|
} else {
|
||||||
element = this.element
|
element = this.element
|
||||||
}
|
}
|
||||||
tippy(element, options)
|
this.tooltip = tippy(element, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect() {
|
||||||
|
this.tooltip.destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ h3,
|
|||||||
|
|
||||||
h4,
|
h4,
|
||||||
.headline--4 {
|
.headline--4 {
|
||||||
@apply block md:text-lg font-bold;
|
@apply block font-semibold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.headline--underlined:after {
|
.headline--underlined:after {
|
||||||
|
|||||||
@@ -78,6 +78,13 @@ class BookingDataProcessor
|
|||||||
$bookingData->participants[$participant->index]->communication->mobile = $participant->mobile;
|
$bookingData->participants[$participant->index]->communication->mobile = $participant->mobile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update applicant's data with personal data of first participant
|
||||||
|
if (false !== $firstParticipant = reset($bookingData->participants)) {
|
||||||
|
$bookingData->applicant->height = $firstParticipant->height;
|
||||||
|
$bookingData->applicant->weight = $firstParticipant->weight;
|
||||||
|
$bookingData->applicant->shoeSize = $firstParticipant->shoeSize;
|
||||||
|
}
|
||||||
|
|
||||||
$payload = [
|
$payload = [
|
||||||
'idbuchung' => $bookingData->id,
|
'idbuchung' => $bookingData->id,
|
||||||
'status' => $bookingData->status,
|
'status' => $bookingData->status,
|
||||||
@@ -153,4 +160,4 @@ class BookingDataProcessor
|
|||||||
|
|
||||||
return $payload;
|
return $payload;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ class Service
|
|||||||
public const TOKEN_BOARD = 'VPF';
|
public const TOKEN_BOARD = 'VPF';
|
||||||
public const TOKEN_RENTALS = ['VER', 'VE2', 'VE3', 'VE4', 'VE5', 'VE6', 'VE7', 'VE8'];
|
public const TOKEN_RENTALS = ['VER', 'VE2', 'VE3', 'VE4', 'VE5', 'VE6', 'VE7', 'VE8'];
|
||||||
|
|
||||||
|
public const STATUS_AVAILABLE = 'Frei';
|
||||||
|
public const STATUS_BLOCKED = 'Buchungsstop';
|
||||||
|
public const STATUS_ON_REQUEST = 'Anfrage';
|
||||||
|
|
||||||
#[Groups(['api:single', 'api:list'])]
|
#[Groups(['api:single', 'api:list'])]
|
||||||
public ?int $id = null;
|
public ?int $id = null;
|
||||||
|
|
||||||
@@ -69,4 +73,4 @@ class Service
|
|||||||
|
|
||||||
#[Groups(['api:single', 'api:list'])]
|
#[Groups(['api:single', 'api:list'])]
|
||||||
public ?string $direction = null;
|
public ?string $direction = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,20 +24,13 @@ class ParticipantData
|
|||||||
public ?string $title = null;
|
public ?string $title = null;
|
||||||
public ?string $gender = null;
|
public ?string $gender = null;
|
||||||
public ?string $nationality = null;
|
public ?string $nationality = null;
|
||||||
|
|
||||||
#[Assert\Range(notInRangeMessage: 'Bitte einen Wert im Bereich {{ min }}-{{ max }}cm angeben', min: 150, max: 210)]
|
|
||||||
public ?string $height = null;
|
public ?string $height = null;
|
||||||
|
|
||||||
#[Assert\Range(notInRangeMessage: 'Bitte einen Wert im Bereich {{ min }}-{{ max }} angeben', min: 37, max: 49)]
|
|
||||||
public ?string $shoeSize = null;
|
public ?string $shoeSize = null;
|
||||||
|
|
||||||
#[Assert\Range(notInRangeMessage: 'Bitte einen Wert im Bereich {{ min }}-{{ max }}kg angeben', min: 40, max: 130)]
|
|
||||||
public ?string $weight = null;
|
public ?string $weight = null;
|
||||||
|
|
||||||
#[Assert\NotNull(message: 'Bitte angeben')]
|
#[Assert\NotNull(message: 'Bitte angeben')]
|
||||||
public ?\DateTimeImmutable $dateOfBirth = null;
|
public ?\DateTimeImmutable $dateOfBirth = null;
|
||||||
|
|
||||||
#[Assert\NotBlank(message: 'Bitte angeben')]
|
|
||||||
#[Assert\Email(message: 'Bitte eine gültige E-Mail Adresse angeben', mode: 'strict')]
|
#[Assert\Email(message: 'Bitte eine gültige E-Mail Adresse angeben', mode: 'strict')]
|
||||||
public ?string $email = null;
|
public ?string $email = null;
|
||||||
|
|
||||||
@@ -112,4 +105,4 @@ class ParticipantData
|
|||||||
|
|
||||||
return $instance;
|
return $instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ use Symfony\Component\Form\AbstractType;
|
|||||||
use Symfony\Component\Form\Extension\Core\Type\BirthdayType;
|
use Symfony\Component\Form\Extension\Core\Type\BirthdayType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Form\FormEvent;
|
use Symfony\Component\Form\FormEvent;
|
||||||
@@ -77,6 +76,7 @@ class ParticipantType extends AbstractType
|
|||||||
])
|
])
|
||||||
->add('email', EmailType::class, [
|
->add('email', EmailType::class, [
|
||||||
'label' => 'E-Mail',
|
'label' => 'E-Mail',
|
||||||
|
'required' => false,
|
||||||
'attr' => [
|
'attr' => [
|
||||||
'readonly' => false === $personalDataMutable,
|
'readonly' => false === $personalDataMutable,
|
||||||
]
|
]
|
||||||
@@ -87,17 +87,43 @@ class ParticipantType extends AbstractType
|
|||||||
'readonly' => false === $personalDataMutable,
|
'readonly' => false === $personalDataMutable,
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
->add('height', IntegerType::class, [
|
->add('height', ChoiceType::class, [
|
||||||
'label' => 'Körpergröße [cm]',
|
'label' => 'Körpergröße',
|
||||||
'required' => false,
|
'required' => false,
|
||||||
|
'expanded' => false,
|
||||||
|
'multiple' => false,
|
||||||
|
'placeholder' => 'Keine Angabe',
|
||||||
|
'choices' => [
|
||||||
|
'bis 148cm' => '-148',
|
||||||
|
'149 - 157cm' => '149-157',
|
||||||
|
'158 - 166cm' => '158-166',
|
||||||
|
'167 - 178cm' => '167-178',
|
||||||
|
'179 - 194cm' => '179-197',
|
||||||
|
'195cm oder mehr' => '195cm+',
|
||||||
|
],
|
||||||
])
|
])
|
||||||
->add('shoeSize', IntegerType::class, [
|
->add('shoeSize', ChoiceType::class, [
|
||||||
'label' => 'Schuhgröße',
|
'label' => 'Schuhgröße',
|
||||||
'required' => false,
|
'required' => false,
|
||||||
|
'expanded' => false,
|
||||||
|
'multiple' => false,
|
||||||
|
'placeholder' => 'Keine Angabe',
|
||||||
|
'choices' => array_combine(range(36, 48), range(36, 48)),
|
||||||
])
|
])
|
||||||
->add('weight', IntegerType::class, [
|
->add('weight', ChoiceType::class, [
|
||||||
'label' => 'Gewicht [kg]',
|
'label' => 'Gewicht',
|
||||||
'required' => false,
|
'required' => false,
|
||||||
|
'expanded' => false,
|
||||||
|
'multiple' => false,
|
||||||
|
'placeholder' => 'Keine Angabe',
|
||||||
|
'choices' => [
|
||||||
|
'42 - 48kg' => '42-48',
|
||||||
|
'49 - 57kg' => '49-57',
|
||||||
|
'58 - 66kg' => '58-66',
|
||||||
|
'67 - 78kg' => '67-78',
|
||||||
|
'79 - 94kg' => '79-94',
|
||||||
|
'95kg oder mehr' => '95k+',
|
||||||
|
],
|
||||||
])
|
])
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -130,11 +156,21 @@ class ParticipantType extends AbstractType
|
|||||||
if (true === $service->mandatory) {
|
if (true === $service->mandatory) {
|
||||||
$attributes['checked'] = true;
|
$attributes['checked'] = true;
|
||||||
$attributes['disabled'] = true;
|
$attributes['disabled'] = true;
|
||||||
|
$attributes['class'] = 'text-pink';
|
||||||
|
$attributes['tooltip'] = 'Diese Leistung ist nicht abwählbar';
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable selection of services only available in booking data
|
// disable selection of services only available in booking data
|
||||||
if (Service::SOURCE_BOOKING === $service->source) {
|
if (Service::SOURCE_BOOKING === $service->source) {
|
||||||
$attributes['disabled'] = true;
|
$attributes['disabled'] = true;
|
||||||
|
$attributes['class'] = 'text-pink';
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable selection of services that are unavailable according to their status
|
||||||
|
if (Service::STATUS_BLOCKED === $service->status) {
|
||||||
|
$attributes['checked'] = false;
|
||||||
|
$attributes['disabled'] = true;
|
||||||
|
$attributes['tooltip'] = 'Diese Leistung ist derzeit leider nicht buchbar';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $attributes;
|
return $attributes;
|
||||||
@@ -297,4 +333,4 @@ class ParticipantType extends AbstractType
|
|||||||
'anti_xss' => true,
|
'anti_xss' => true,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,31 +16,6 @@ class PersonalDataType extends AbstractType
|
|||||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||||
{
|
{
|
||||||
$builder
|
$builder
|
||||||
->add('gender', ChoiceType::class, [
|
|
||||||
'label' => 'Gender',
|
|
||||||
'choices' => [
|
|
||||||
'männlich' => 'M',
|
|
||||||
'weiblich' => 'W',
|
|
||||||
'divers' => 'D',
|
|
||||||
],
|
|
||||||
])
|
|
||||||
->add('firstName', TextType::class, [
|
|
||||||
'label' => 'Name',
|
|
||||||
])
|
|
||||||
->add('name', TextType::class, [
|
|
||||||
'label' => 'Nachname',
|
|
||||||
])
|
|
||||||
->add('dateOfBirth', BirthdayType::class, [
|
|
||||||
'label' => 'Geburtsdatum',
|
|
||||||
'html5' => true,
|
|
||||||
'widget' => 'single_text',
|
|
||||||
'input' => 'datetime_immutable',
|
|
||||||
])
|
|
||||||
->add('nationality', CountryType::class, [
|
|
||||||
'label' => 'Nationalität',
|
|
||||||
'property' => 'nationality',
|
|
||||||
'preferred_choices' => ['D', 'A', 'CH'],
|
|
||||||
])
|
|
||||||
->add('street', TextType::class, [
|
->add('street', TextType::class, [
|
||||||
'label' => 'Straße',
|
'label' => 'Straße',
|
||||||
'property_path' => 'address.street',
|
'property_path' => 'address.street',
|
||||||
@@ -78,4 +53,4 @@ class PersonalDataType extends AbstractType
|
|||||||
'anti_xss' => true,
|
'anti_xss' => true,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,10 @@ class AppExtension extends AbstractExtension
|
|||||||
new TwigFilter('file_size', [AppRuntime::class, 'formatBytes']),
|
new TwigFilter('file_size', [AppRuntime::class, 'formatBytes']),
|
||||||
new TwigFilter('file_icon', [AppRuntime::class, 'fileIconFilter'], ['is_safe' => ['html']]),
|
new TwigFilter('file_icon', [AppRuntime::class, 'fileIconFilter'], ['is_safe' => ['html']]),
|
||||||
new TwigFilter('format_money', [AppRuntime::class, 'formatMoney']),
|
new TwigFilter('format_money', [AppRuntime::class, 'formatMoney']),
|
||||||
|
new TwigFilter('map_gender', [AppRuntime::class, 'mapGender']),
|
||||||
new TwigFilter('map_status', [AppRuntime::class, 'mapStatus']),
|
new TwigFilter('map_status', [AppRuntime::class, 'mapStatus']),
|
||||||
|
new TwigFilter('map_country', [AppRuntime::class, 'mapCountry']),
|
||||||
|
new TwigFilter('map_nationality', [AppRuntime::class, 'mapNationality']),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+37
-2
@@ -2,14 +2,17 @@
|
|||||||
|
|
||||||
namespace App\Twig;
|
namespace App\Twig;
|
||||||
|
|
||||||
|
use App\BusProNet\DataProvider\CountryDataProvider;
|
||||||
use Twig\Environment;
|
use Twig\Environment;
|
||||||
use Twig\Extension\RuntimeExtensionInterface;
|
use Twig\Extension\RuntimeExtensionInterface;
|
||||||
use Twig\Extra\Intl\IntlExtension;
|
use Twig\Extra\Intl\IntlExtension;
|
||||||
|
|
||||||
class AppRuntime implements RuntimeExtensionInterface
|
class AppRuntime implements RuntimeExtensionInterface
|
||||||
{
|
{
|
||||||
public function __construct(private readonly IntlExtension $intlExtension)
|
public function __construct(
|
||||||
{
|
private readonly IntlExtension $intlExtension,
|
||||||
|
private readonly CountryDataProvider $countryDataProvider,
|
||||||
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fileIconFilter(Environment $environment, string $mimeType, ?string $classes = 'w-4 h-4'): string
|
public function fileIconFilter(Environment $environment, string $mimeType, ?string $classes = 'w-4 h-4'): string
|
||||||
@@ -50,6 +53,8 @@ class AppRuntime implements RuntimeExtensionInterface
|
|||||||
|
|
||||||
public function mapStatus(string $status): string
|
public function mapStatus(string $status): string
|
||||||
{
|
{
|
||||||
|
$status = strtoupper($status);
|
||||||
|
|
||||||
return match ($status) {
|
return match ($status) {
|
||||||
'F', 'F/S' => 'Festbuchung',
|
'F', 'F/S' => 'Festbuchung',
|
||||||
'S' => 'Stornierung',
|
'S' => 'Stornierung',
|
||||||
@@ -58,4 +63,34 @@ class AppRuntime implements RuntimeExtensionInterface
|
|||||||
default => '',
|
default => '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function mapGender(string $gender): string
|
||||||
|
{
|
||||||
|
$gender = strtoupper($gender);
|
||||||
|
|
||||||
|
return match ($gender) {
|
||||||
|
'M' => 'männlich',
|
||||||
|
'F' => 'weiblich',
|
||||||
|
'D' => 'divers',
|
||||||
|
default => '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mapCountry(?string $country): ?string
|
||||||
|
{
|
||||||
|
if (null === $country) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->countryDataProvider->get($country)?->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mapNationality(?string $nationality): ?string
|
||||||
|
{
|
||||||
|
if (null === $nationality) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->countryDataProvider->get($nationality)?->nationality;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-4
@@ -2,8 +2,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
content: [
|
content: [
|
||||||
'./templates/**/*.twig',
|
'./templates/**/*.twig',
|
||||||
'./src/Twig/*.php',
|
'./src/**/*.php',
|
||||||
'./src/Menu/*.php',
|
|
||||||
],
|
],
|
||||||
safelist: ['rotate-90'],
|
safelist: ['rotate-90'],
|
||||||
theme: {
|
theme: {
|
||||||
@@ -22,8 +21,12 @@ module.exports = {
|
|||||||
'primary-light': '#0080ff',
|
'primary-light': '#0080ff',
|
||||||
'primary-medium': '#165883',
|
'primary-medium': '#165883',
|
||||||
'primary-dark': '#18527b',
|
'primary-dark': '#18527b',
|
||||||
pink: '#fa1a8c',
|
pink: '#960167',
|
||||||
}
|
},
|
||||||
|
backgroundImage: {
|
||||||
|
'badge-gradient': 'linear-gradient(120deg, rgba(150,1,103,1) 0%, rgba(158,3,106,1) 40%, rgba(250,26,140,1) 100%)',
|
||||||
|
'brand-gradient': 'linear-gradient(to top right, #009fff, #165883, #18527b)',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div class="invisible fixed top-0 left-0 inset-0 z-10 bg-white/90 flex items-center justify-center"
|
<div class="invisible fixed top-0 left-0 inset-0 z-10 bg-white/90 flex items-center justify-center"
|
||||||
{{ stimulus_target('loading', 'indicator') }}>
|
{{ stimulus_target('loading', 'indicator') }}>
|
||||||
{% include '_partials/_spinner.html.twig' with { 'class': 'w-8 h-8'} %}
|
{% include '_partials/_spinner.html.twig' with { 'class': 'w-32 h-32 lg:w-48 lg:h-48'} %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+135
-113
@@ -7,7 +7,7 @@
|
|||||||
{% set messages = form.vars.errors|map(error => error.message) %}
|
{% set messages = form.vars.errors|map(error => error.message) %}
|
||||||
{% include '_partials/_alert.html.twig' with { 'level': 'error', 'title': 'Die Buchung konnte nicht aktualisiert werden', 'messages': messages } %}
|
{% include '_partials/_alert.html.twig' with { 'level': 'error', 'title': 'Die Buchung konnte nicht aktualisiert werden', 'messages': messages } %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="flex flex-col space-y-8 pb-4" {{ stimulus_controller('booking', { 'availabilities': availabilities.items }) }} {{ stimulus_controller('iframe') }}>
|
<div class="flex flex-col space-y-8 pb-8" {{ stimulus_controller('booking', { 'availabilities': availabilities.items }) }} {{ stimulus_controller('iframe') }}>
|
||||||
<div class="p-8 border border-gray-300 rounded-md"
|
<div class="p-8 border border-gray-300 rounded-md"
|
||||||
{{ stimulus_controller('toggle', { 'open': true }, { 'closed': 'hidden' }) }}>
|
{{ stimulus_controller('toggle', { 'open': true }, { 'closed': 'hidden' }) }}>
|
||||||
<div role="button" class="flex items-center justify-between" {{ stimulus_action('toggle', 'toggle', 'click') }}>
|
<div role="button" class="flex items-center justify-between" {{ stimulus_action('toggle', 'toggle', 'click') }}>
|
||||||
@@ -35,6 +35,18 @@
|
|||||||
</h3>
|
</h3>
|
||||||
{{ bookingData.bookingDate|date('d.m.Y') }}
|
{{ bookingData.bookingDate|date('d.m.Y') }}
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="text-lg font-semibold">
|
||||||
|
Vorgangsnummer
|
||||||
|
</h3>
|
||||||
|
{{ bookingData.bookingNumber }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="text-lg font-semibold">
|
||||||
|
Rechnungsnummer
|
||||||
|
</h3>
|
||||||
|
{{ bookingData.invoiceNumber }}
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-lg font-semibold">
|
<h3 class="text-lg font-semibold">
|
||||||
Anmelder:in
|
Anmelder:in
|
||||||
@@ -57,15 +69,19 @@
|
|||||||
<h3 class="text-lg font-semibold">
|
<h3 class="text-lg font-semibold">
|
||||||
Inklusivleistungen
|
Inklusivleistungen
|
||||||
</h3>
|
</h3>
|
||||||
<ul class="list-disc pl-4">
|
{% if travelData.includedServices | length == 0 %}
|
||||||
{% for selectionGroup in travelData.includedServices %}
|
-
|
||||||
{% for service in selectionGroup.selections %}
|
{% else %}
|
||||||
<li>
|
<ul class="list-disc pl-4">
|
||||||
{{ service.label }}
|
{% for selectionGroup in travelData.includedServices %}
|
||||||
</li>
|
{% for service in selectionGroup.selections %}
|
||||||
|
<li>
|
||||||
|
{{ service.label }}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
</ul>
|
||||||
</ul>
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-lg font-semibold">
|
<h3 class="text-lg font-semibold">
|
||||||
@@ -93,122 +109,128 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% for child in form.participants %}
|
{% for child in form.participants %}
|
||||||
{% set participant = child.vars.data %}
|
<div>
|
||||||
<div class="{{ html_classes('p-8 border rounded-md', { 'border-gray-300': child.vars.valid, 'border-red-500': not child.vars.valid }) }}" {{ stimulus_controller('toggle', {'open': child.vars.valid == false}, { 'closed': 'hidden' }) }}>
|
{% set participant = child.vars.data %}
|
||||||
<div role="button" class="flex items-center justify-between" {{ stimulus_action('toggle', 'toggle', 'click') }}>
|
<div class="{{ html_classes('p-8 border rounded-md mb-4', { 'border-gray-300': child.vars.valid, 'border-red-500': not child.vars.valid }) }}" {{ stimulus_controller('toggle', {'open': child.vars.valid == false}, { 'closed': 'hidden' }) }}>
|
||||||
<div class="text-2xl font-semibold">Teilnehmer:in {{ participant.index }}: {{ participant.firstName }} {{ participant.lastName }}</div>
|
<div role="button" class="flex items-center justify-between" {{ stimulus_action('toggle', 'toggle', 'click') }}>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6" {{ stimulus_target('toggle', 'icon') }}>
|
<div class="text-2xl font-semibold">Teilnehmer:in {{ participant.index }}: {{ participant.firstName }} {{ participant.lastName }}</div>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6" {{ stimulus_target('toggle', 'icon') }}>
|
||||||
</svg>
|
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
|
||||||
</div>
|
</svg>
|
||||||
<div class="hidden" {{ stimulus_target('toggle', 'toggle') }}>
|
</div>
|
||||||
<div class="flex flex-col space-y-4 pt-4">
|
<div class="hidden" {{ stimulus_target('toggle', 'toggle') }}>
|
||||||
<div class="relative">
|
<div class="flex flex-col space-y-4 pt-4">
|
||||||
<h3 class="text-xl font-semibold">
|
<div class="relative">
|
||||||
Persönliche Daten
|
<h3 class="text-xl font-semibold">
|
||||||
</h3>
|
Persönliche Daten
|
||||||
{% if not child.vars.data.mutable %}
|
</h3>
|
||||||
<div class="pt-4">
|
{% if not child.vars.data.mutable %}
|
||||||
{% include '_partials/_alert.html.twig' with {
|
<div class="pt-4">
|
||||||
'level': 'info',
|
{% include '_partials/_alert.html.twig' with {
|
||||||
'messages': ['Änderungen an den persönlichen Daten sind nur kostenpflichtig über die Kundenbetreuung möglich']
|
'level': 'info',
|
||||||
} %}
|
'messages': ['Änderungen an den persönlichen Daten sind nur über die Kundenbetreuung möglich und kostenpflichtig']
|
||||||
</div>
|
} %}
|
||||||
{% endif %}
|
|
||||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4 pb-4">
|
|
||||||
{{ form_row(child.firstName) }}
|
|
||||||
{{ form_row(child.lastName) }}
|
|
||||||
{{ form_row(child.gender) }}
|
|
||||||
{{ form_row(child.dateOfBirth) }}
|
|
||||||
{{ form_row(child.nationality) }}
|
|
||||||
</fieldset>
|
|
||||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4 pb-4">
|
|
||||||
{{ form_row(child.email) }}
|
|
||||||
{{ form_row(child.mobile) }}
|
|
||||||
</fieldset>
|
|
||||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4">
|
|
||||||
{{ form_row(child.height) }}
|
|
||||||
{{ form_row(child.shoeSize) }}
|
|
||||||
{{ form_row(child.weight) }}
|
|
||||||
</fieldset>
|
|
||||||
{% if not travelData.participantDataMutable %}
|
|
||||||
<div class="absolute top-0 left-0 inset-0 cursor-not-allowed"></div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h3 class="text-xl font-semibold">
|
|
||||||
Unterkunft
|
|
||||||
</h3>
|
|
||||||
{% set room = bookingData.roomForParticipant(participant.index) %}
|
|
||||||
{{ room.label }} ({{ room.individualPrice[participant.index]|format_currency('EUR') }})
|
|
||||||
</div>
|
|
||||||
<div class="relative">
|
|
||||||
<h3 class="text-xl font-semibold">
|
|
||||||
Leistungen
|
|
||||||
</h3>
|
|
||||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4">
|
|
||||||
{% if child.courses is defined %}
|
|
||||||
{{ form_row(child.courses) }}
|
|
||||||
{% endif %}
|
|
||||||
{% if child.skiPass is defined %}
|
|
||||||
{{ form_row(child.skiPass) }}
|
|
||||||
{% endif %}
|
|
||||||
{% if child.additionalServices is defined %}
|
|
||||||
{{ form_row(child.additionalServices) }}
|
|
||||||
{% endif %}
|
|
||||||
{% if child.board is defined %}
|
|
||||||
{{ form_row(child.board) }}
|
|
||||||
{% endif %}
|
|
||||||
{% if child.rentals is defined %}
|
|
||||||
{{ form_row(child.rentals) }}
|
|
||||||
{% endif %}
|
|
||||||
</fieldset>
|
|
||||||
{% if not travelData.additionalServicesMutable %}
|
|
||||||
<div class="absolute inset-0 cursor-not-allowed"></div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="relative">
|
|
||||||
<h3 class="text-xl font-semibold">
|
|
||||||
Hin-/Rückreise
|
|
||||||
</h3>
|
|
||||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4" {{ stimulus_controller('select-toggle', { 'show': ['BUS'], 'visible': participant.transportationServiceTo.subType == 'BUS' }, { 'hidden': 'hidden' }) }}>
|
|
||||||
{{ form_row(child.transportationServiceTo) }}
|
|
||||||
{{ form_row(child.transportationServiceFro) }}
|
|
||||||
{% if child.pickup is defined %}
|
|
||||||
<div {{ stimulus_target('select-toggle', 'container') }}>
|
|
||||||
{{ form_row(child.pickup) }}
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</fieldset>
|
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4 pb-4">
|
||||||
{% if not travelData.transportationServicesMutable %}
|
{{ form_row(child.firstName) }}
|
||||||
<div class="absolute inset-0 cursor-not-allowed"></div>
|
{{ form_row(child.lastName) }}
|
||||||
{% endif %}
|
{{ form_row(child.gender) }}
|
||||||
</div>
|
{{ form_row(child.dateOfBirth) }}
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4">
|
{{ form_row(child.nationality) }}
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4 pb-4">
|
||||||
|
{{ form_row(child.email) }}
|
||||||
|
{{ form_row(child.mobile) }}
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4">
|
||||||
|
{{ form_row(child.height) }}
|
||||||
|
{{ form_row(child.shoeSize) }}
|
||||||
|
{{ form_row(child.weight) }}
|
||||||
|
</fieldset>
|
||||||
|
{% if not travelData.participantDataMutable %}
|
||||||
|
<div class="absolute top-0 left-0 inset-0 cursor-not-allowed"></div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-xl font-semibold">
|
<h3 class="text-xl font-semibold">
|
||||||
Gesamtpreis
|
Unterkunft
|
||||||
</h3>
|
</h3>
|
||||||
<span class="text-2xl font-medium">{{ bookingData.priceForParticipant(participant.index)|format_currency('EUR') }}</span>
|
{% set room = bookingData.roomForParticipant(participant.index) %}
|
||||||
|
{{ room.label }} ({{ room.individualPrice[participant.index]|format_currency('EUR') }})
|
||||||
</div>
|
</div>
|
||||||
{% set surcharges = bookingData.surchargesForParticipant(participant.index) %}
|
<div class="relative">
|
||||||
{% if surcharges|length > 0 %}
|
<h3 class="text-xl font-semibold">
|
||||||
|
Leistungen
|
||||||
|
</h3>
|
||||||
|
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4">
|
||||||
|
{% if child.courses is defined %}
|
||||||
|
{{ form_row(child.courses) }}
|
||||||
|
{% endif %}
|
||||||
|
{% if child.skiPass is defined %}
|
||||||
|
{{ form_row(child.skiPass) }}
|
||||||
|
{% endif %}
|
||||||
|
{% if child.additionalServices is defined %}
|
||||||
|
{{ form_row(child.additionalServices) }}
|
||||||
|
{% endif %}
|
||||||
|
{% if child.board is defined %}
|
||||||
|
{{ form_row(child.board) }}
|
||||||
|
{% endif %}
|
||||||
|
{% if child.rentals is defined %}
|
||||||
|
{{ form_row(child.rentals) }}
|
||||||
|
{% endif %}
|
||||||
|
</fieldset>
|
||||||
|
{% if not travelData.additionalServicesMutable %}
|
||||||
|
<div class="absolute inset-0 cursor-not-allowed"></div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="relative">
|
||||||
|
<h3 class="text-xl font-semibold">
|
||||||
|
Hin-/Rückreise
|
||||||
|
</h3>
|
||||||
|
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4" {{ stimulus_controller('select-toggle', { 'show': ['BUS'], 'visible': participant.transportationServiceTo.subType == 'BUS' }, { 'hidden': 'hidden' }) }}>
|
||||||
|
{{ form_row(child.transportationServiceTo) }}
|
||||||
|
{{ form_row(child.transportationServiceFro) }}
|
||||||
|
{% if child.pickup is defined %}
|
||||||
|
<div {{ stimulus_target('select-toggle', 'container') }}>
|
||||||
|
{{ form_row(child.pickup) }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</fieldset>
|
||||||
|
{% if not travelData.transportationServicesMutable %}
|
||||||
|
<div class="absolute inset-0 cursor-not-allowed"></div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-xl font-semibold">
|
<h3 class="text-xl font-semibold">
|
||||||
Zuschläge
|
Gesamtpreis
|
||||||
</h3>
|
</h3>
|
||||||
<ul>
|
<span class="text-2xl font-medium">{{ bookingData.priceForParticipant(participant.index)|format_currency('EUR') }}</span>
|
||||||
{% for surcharge in surcharges %}
|
|
||||||
<li>
|
|
||||||
{{ surcharge.label }}: {{ surcharge.individualPrice[participant.index]|format_currency('EUR') }}
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% set surcharges = bookingData.surchargesForParticipant(participant.index) %}
|
||||||
|
{% if surcharges|length > 0 %}
|
||||||
|
<div>
|
||||||
|
<h3 class="text-xl font-semibold">
|
||||||
|
Zuschläge
|
||||||
|
</h3>
|
||||||
|
<ul>
|
||||||
|
{% for surcharge in surcharges %}
|
||||||
|
<li>
|
||||||
|
{{ surcharge.label }}: {{ surcharge.individualPrice[participant.index]|format_currency('EUR') }}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<button type="submit"
|
||||||
|
class="button bg-button bg-button--secondary" {{ stimulus_action('loading', 'toggle', null, { 'scroll': true }) }}>
|
||||||
|
Aktualisieren
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
@@ -224,4 +246,4 @@
|
|||||||
</div>
|
</div>
|
||||||
{{ form_rest(form) }}
|
{{ form_rest(form) }}
|
||||||
{{ form_end(form) }}
|
{{ form_end(form) }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
Reise
|
Reise
|
||||||
</th>
|
</th>
|
||||||
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-sm md:text-base">
|
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-sm md:text-base">
|
||||||
Buchungsdatum
|
Reisedatum
|
||||||
</th>
|
</th>
|
||||||
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-sm md:text-base">
|
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-sm md:text-base">
|
||||||
Buchungsnummer
|
Buchungsnummer
|
||||||
@@ -35,15 +35,15 @@
|
|||||||
<tr class="odd:bg-zinc-50 hover:bg-zinc-100 odd:hover:bg-zinc-100">
|
<tr class="odd:bg-zinc-50 hover:bg-zinc-100 odd:hover:bg-zinc-100">
|
||||||
<td class="border-r border-zinc-200 px-2 py-1 md:p-2"
|
<td class="border-r border-zinc-200 px-2 py-1 md:p-2"
|
||||||
data-label="Reise">
|
data-label="Reise">
|
||||||
{% if booking.travelData %}
|
{{ booking.travel }}
|
||||||
{{ booking.travel }}, {{ booking.travelData.dateFrom | date('d.m.Y') }} - {{ booking.travelData.dateTo | date('d.m.Y') }}
|
|
||||||
{% else %}
|
|
||||||
{{ booking.travel }}, {{ booking.travelDate | date('d.m.Y') }}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
</td>
|
||||||
<td class="border-r border-zinc-200 px-2 py-1 md:p-2"
|
<td class="border-r border-zinc-200 px-2 py-1 md:p-2"
|
||||||
data-label="Buchungsdatum">
|
data-label="Buchungsdatum">
|
||||||
{{ booking.bookingDate | date('d.m.Y') }}
|
{% if booking.travelData %}
|
||||||
|
{{ booking.travelData.dateFrom | date('d.m.Y') }} - {{ booking.travelData.dateTo | date('d.m.Y') }}
|
||||||
|
{% else %}
|
||||||
|
{{ booking.travelDate | date('d.m.Y') }}
|
||||||
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="border-r border-zinc-200 px-2 py-1 md:p-2"
|
<td class="border-r border-zinc-200 px-2 py-1 md:p-2"
|
||||||
data-label="Buchungsnummer">
|
data-label="Buchungsnummer">
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
</a>
|
</a>
|
||||||
{% if booking.hasDocuments %}
|
{% if booking.hasDocuments %}
|
||||||
<a href="{{ path('app_booking_documents', { 'id': booking.id }) }}"
|
<a href="{{ path('app_booking_documents', { 'id': booking.id }) }}"
|
||||||
class="button bg-button button--small"
|
class="button bg-button bg-pink button--small"
|
||||||
target="_blank">
|
target="_blank">
|
||||||
Reisedokumente
|
Reisedokumente
|
||||||
</a>
|
</a>
|
||||||
@@ -88,4 +88,4 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -72,7 +72,14 @@
|
|||||||
{%- if attr.disabled is defined and attr.disabled == true -%}
|
{%- if attr.disabled is defined and attr.disabled == true -%}
|
||||||
{%- set attr = attr|merge({'class': attr.class|default('') ~ ' cursor-not-allowed' }) -%}
|
{%- set attr = attr|merge({'class': attr.class|default('') ~ ' cursor-not-allowed' }) -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
<input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
|
{%- set tooltip = null -%}
|
||||||
|
{%- if attr.tooltip is defined -%}
|
||||||
|
{%- set tooltip = attr.tooltip -%}
|
||||||
|
{%- set attr = attr|filter((v, k) => k != 'tooltip') -%}
|
||||||
|
{%- endif -%}
|
||||||
|
<div{% if tooltip is not null %} {{ stimulus_controller('tooltip', { 'content': tooltip }) }}{% endif %}>
|
||||||
|
<input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
|
||||||
|
</div>
|
||||||
{%- endblock checkbox_widget -%}
|
{%- endblock checkbox_widget -%}
|
||||||
|
|
||||||
{%- block radio_widget -%}
|
{%- block radio_widget -%}
|
||||||
@@ -83,7 +90,14 @@
|
|||||||
{%- if attr.disabled is defined and attr.disabled == true -%}
|
{%- if attr.disabled is defined and attr.disabled == true -%}
|
||||||
{%- set attr = attr|merge({'class': attr.class|default('') ~ ' cursor-not-allowed' }) -%}
|
{%- set attr = attr|merge({'class': attr.class|default('') ~ ' cursor-not-allowed' }) -%}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
|
{%- set tooltip = null -%}
|
||||||
|
{%- if attr.tooltip is defined -%}
|
||||||
|
{%- set tooltip = attr.tooltip -%}
|
||||||
|
{%- set attr = attr|filter((v, k) => k != 'tooltip') -%}
|
||||||
|
{%- endif -%}
|
||||||
|
<div{% if tooltip is not null %} {{ stimulus_controller('tooltip', { 'content': tooltip }) }}{% endif %}>
|
||||||
|
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
|
||||||
|
</div>
|
||||||
{%- endblock radio_widget -%}
|
{%- endblock radio_widget -%}
|
||||||
|
|
||||||
{% block checkbox_row %}
|
{% block checkbox_row %}
|
||||||
|
|||||||
@@ -3,17 +3,47 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="grid md:grid-cols-2 gap-x-16 gap-y-4">
|
<div class="grid md:grid-cols-2 gap-x-16 gap-y-4">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="text-2xl font-semibold pb-4">
|
|
||||||
Persönliche Daten
|
|
||||||
</h2>
|
|
||||||
{% include '_partials/_flashes.html.twig' %}
|
{% include '_partials/_flashes.html.twig' %}
|
||||||
{{ form_start(personalDataForm, { 'attr': { 'data-action': 'loading#toggle' } }) }}
|
{{ form_start(personalDataForm, { 'attr': { 'data-action': 'loading#toggle' } }) }}
|
||||||
|
<div class="pb-4">
|
||||||
|
<button type="submit" class="button bg-button">
|
||||||
|
Speichern
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<h2 class="text-2xl font-semibold pb-2">
|
||||||
|
Persönliche Daten
|
||||||
|
</h2>
|
||||||
<div class="grid grid-cols-2 gap-x-8 gap-y-4 pb-4">
|
<div class="grid grid-cols-2 gap-x-8 gap-y-4 pb-4">
|
||||||
{{ form_row(personalDataForm.firstName) }}
|
<div>
|
||||||
{{ form_row(personalDataForm.name) }}
|
<h4>
|
||||||
{{ form_row(personalDataForm.gender) }}
|
Vorname
|
||||||
{{ form_row(personalDataForm.dateOfBirth) }}
|
</h4>
|
||||||
{{ form_row(personalDataForm.nationality) }}
|
{{ personalData.firstName }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>
|
||||||
|
Nachname
|
||||||
|
</h4>
|
||||||
|
{{ personalData.name }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>
|
||||||
|
Gender
|
||||||
|
</h4>
|
||||||
|
{{ personalData.gender|map_gender }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>
|
||||||
|
Geburtsdatum
|
||||||
|
</h4>
|
||||||
|
{{ personalData.dateOfBirth|date('d.m.Y') }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>
|
||||||
|
Nationaliät
|
||||||
|
</h4>
|
||||||
|
{{ personalData.nationality|map_nationality|default('-') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-xl font-semibold pb-2">
|
<h3 class="text-xl font-semibold pb-2">
|
||||||
Anschrift
|
Anschrift
|
||||||
@@ -64,4 +94,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user