@@ -40,7 +125,11 @@
| Name |
- {{props.participant.firstname}} {{props.participant.lastname}}
+ {{ props.participant.firstname }} {{ props.participant.lastname }}
+
+
+
+
|
@@ -48,7 +137,8 @@
| Pfadiname |
- {{props.participant.nickname}}
+ {{ props.participant.nickname }}
+
|
@@ -56,25 +146,35 @@
Anschrift |
- {{props.participant.address_1}}
- {{props.participant.address_2}}
- {{props.participant.postcode}}
- {{props.participant.city}}
+ {{ props.participant.address_1 }}
+ {{ props.participant.address_2 }}
+ {{ props.participant.postcode }}
+ {{ props.participant.city }}
+
+
+
+
+
+
|
+
| Stamm |
- {{props.participant.localgroup}}
+ {{ props.participant.localgroup }}
+
|
+
| Geburtsdatum |
-
- {{props.participant.birthday}}
-
+ {{ props.participant.birthday }}
+
|
@@ -86,35 +186,175 @@
| E-Mail |
- {{props.participant.email_1}}
+ {{ props.participant.email_1 }}
+
|
| Telefon |
- {{props.participant.phone_1}}
+ {{ props.participant.phone_1 }}
+
|
| Ansprechperson |
- {{props.participant.contact_person}}
+ {{ props.participant.contact_person }}
+
|
| Ansprechperson E-Mail |
- {{props.participant.email_2}}
+ {{ props.participant.email_2 }}
+
|
| Ansprechperson Telefon |
- {{props.participant.phone_2}}
+ {{ props.participant.phone_2 }}
+
+ |
+
+
+
+
+
+
+
+
+
+
Medizinische Informationen
+
@@ -122,104 +362,9 @@
-
-
-
Teilnahmedetails
-
-
- | Anreise |
-
- {{props.participant.arrival}}
- |
-
-
- | Abreise |
-
- {{props.participant.departure}}
- |
-
-
- | Teilnahmegruppe |
-
- {{props.participant.participationType}}
- |
-
+
+
-
- | Ernährung |
-
- {{props.participant.eatingHabit}}
- |
-
-
- | eFZ-Status |
-
- {{props.participant.efzStatusReadable}}
- |
-
-
-
- | Beitrag |
-
- {{props.participant.amountPaid.readable}} / {{props.participant.amountExpected.readable}}
- |
-
-
-
-
-
Medizinische Informationen
-
-
- | Allergien |
-
- {{props.participant.allergies}}
- |
-
-
- | Unverträglichkeiten |
-
- {{props.participant.intolerances}}
- |
-
-
-
- | Medikamente |
-
- {{props.participant.medications}}
- |
-
-
-
- | Erweiterte Erste Hilfe |
-
- {{props.participant.extendedFirstAid}}
- |
-
-
-
- | Badeerlaubnis |
-
- {{props.participant.swimmingPermission}}
- |
-
-
- | Letzte Tetanus-Impfung |
-
- {{props.participant.tetanusVaccination}}
- |
-
-
-
- | Anmerkungen |
-
- {{props.participant.notes}}
- |
-
-
-
-
-
-
@@ -231,6 +376,7 @@
.participationData {
display: flex;
margin-bottom: 20px;
+ gap: 20px;
}
.participationData div {
@@ -238,4 +384,19 @@
vertical-align: top;
}
+input[type="text"],
+input[type="email"],
+input[type="date"],
+textarea
+{
+ width: 250px
+}
+
+textarea {
+ height: 100px;
+}
+
+select {
+ width: 262px;
+}
diff --git a/app/Domains/Event/Views/Partials/ParticipantsList.vue b/app/Domains/Event/Views/Partials/ParticipantsList.vue
new file mode 100644
index 0000000..bd07ec5
--- /dev/null
+++ b/app/Domains/Event/Views/Partials/ParticipantsList.vue
@@ -0,0 +1,432 @@
+
+
+
+ {{ event?.name ?? "Veranstaltung" }}
+
+
+
+
+
+ |
+ {{ groupKey }} ({{ participants.length }} Personen)
+ |
+
+
+ | Name |
+ Beitrag |
+ E-Mail-Adresse |
+ Telefon |
+
+
+
+
+
+
+
+
+ Geburtsdatum: {{ participant.birthday }}
+ Alter: {{ participant.age }} Jahre
+
+
+ eFZ-Status:
+ Vorhanden?
+ |
+
+
+ Gezahlt: /
+ Gesamt: {{ participant?.amountExpected.readable }}
+
+
+ Zahlung buchen
+ Teilzahlung buchen
+
+ |
+
+
+ {{ participant?.email_1 ?? "-" }}
+
+ {{ participant.email_2 }}
+
+
+ |
+
+
+ {{ participant?.phone_1 ?? "-" }}
+
+ {{ participant.phone_2 }}
+
+ |
+
+
+
+
+
+ |
+ {{ participant?.localgroup ?? "-" }} |
+ Anreise: {{ participant?.arrival ?? "-" }} |
+ Abreise: {{ participant?.departure ?? "-" }} |
+ Angemeldet am: {{ participant?.registerDate ?? "-" }} |
+ Details |
+ E-Mail senden |
+ Abmelden
+ Wieder anmelden
+ |
+
+
+
+
+ |
+ 0 - 5 Jahre: {{ getAgeCounts(participants)['0-5'] ?? 0 }} |
+ 6-11 Jahre: {{ getAgeCounts(participants)['6-11'] ?? 0 }} |
+ 12-15 Jahre: {{ getAgeCounts(participants)['12-15'] ?? 0 }} |
+ 16 - 17 Jahre: {{ getAgeCounts(participants)['16-17'] ?? 0 }} |
+ 18 - 27 Jahre: {{ getAgeCounts(participants)['18-27'] ?? 0 }} |
+ 27 Jahre und älter: {{ getAgeCounts(participants)['27+'] ?? 0 }}
+ |
+
+ E-Mail an Gruppe senden
+ |
+
+
+
+
+
+
+
+
+
+
+
+ Datum der Abmeldung:
+
+
+
+
+
+
+ Gesamtbetrag der Zahlung:
+ Euro
+
+
+
+
+
+
+
+
+
+
diff --git a/app/Models/EventParticipant.php b/app/Models/EventParticipant.php
index 0803d07..97130d9 100644
--- a/app/Models/EventParticipant.php
+++ b/app/Models/EventParticipant.php
@@ -140,11 +140,18 @@ class EventParticipant extends InstancedModel
return sprintf('%1$s %2$s', $this->firstname, $this->lastname);
}
- public function getFullname() : string {
- return sprintf('%1$1s %2$s %3$s',
+ public function getFullName() : string {
+ if ($this->nickname === null) {
+ return sprintf('%1$s %2$s', $this->firstname, $this->lastname)
+ |>trim(...);
+ }
+
+
+ return sprintf('%1$1s%2$s(%3$s %4$s)',
+ $this->nickname,
+ '
',
$this->firstname,
$this->lastname,
- $this->nickname !== null ? '(' . $this->nickname . ')' : '',
)
|>trim(...);
}
diff --git a/app/Repositories/EventParticipantRepository.php b/app/Repositories/EventParticipantRepository.php
index 29cff4c..8b211f4 100644
--- a/app/Repositories/EventParticipantRepository.php
+++ b/app/Repositories/EventParticipantRepository.php
@@ -4,6 +4,7 @@ namespace App\Repositories;
use App\Enumerations\EatingHabit;
use App\Models\Event;
+use App\Models\EventParticipant;
use Illuminate\Http\Request;
class EventParticipantRepository {
@@ -16,6 +17,41 @@ class EventParticipantRepository {
return $participants;
}
+ public function getByIdentifier(string $identifier, EventRepository $eventRepository, bool $withPermissionCheck = true) : ?EventParticipant {
+ $participant = EventParticipant::where('identifier', $identifier)->first();
+ if ($participant === null) {
+ return null;
+ }
+
+ if ($withPermissionCheck) {
+ $event = $eventRepository->getById($participant->event_id);
+ if ($event === null) {
+ return null;
+ }
+ }
+ return $participant;
+ }
+
+ public function groupByLocalGroup(Event $event, Request $request) : array {
+ $allParticipants = $this->getForList($event, $request);
+ $participants = [];
+ foreach ($allParticipants as $participant) {
+ $participants[$participant['localgroup']][] = $participant;
+ }
+
+ return $participants;
+ }
+
+ public function groupByParticipationType(Event $event, Request $request) : array {
+ $allParticipants = $this->getForList($event, $request);
+ $participants = [];
+ foreach ($allParticipants as $participant) {
+ $participants[$participant['participationType']][] = $participant;
+ }
+
+ return $participants;
+ }
+
public function getParticipantsWithIntolerances(Event $event, Request $request) : array {
$participants = [];
foreach ($event->participants()->whereNotNull('intolerances')->whereNot('intolerances' , '=', '')->get() as $participant) {
diff --git a/app/Resources/EventParticipantResource.php b/app/Resources/EventParticipantResource.php
index a62eb14..0725348 100644
--- a/app/Resources/EventParticipantResource.php
+++ b/app/Resources/EventParticipantResource.php
@@ -2,6 +2,8 @@
namespace App\Resources;
+use App\Enumerations\EatingHabit;
+use App\Enumerations\EfzStatus;
use App\Enumerations\ParticipationType;
use App\Models\EventParticipant;
use App\ValueObjects\Age;
@@ -18,7 +20,7 @@ class EventParticipantResource extends JsonResource
{
$event = $this->resource->event;
- $amountLeft = $this->resource->amount;
+ $amountLeft = clone $this->resource->amount;
if ($this->resource->amount_paid !== null) {
$amountLeft->subtractAmount($this->resource->amount_paid);
}
@@ -32,14 +34,20 @@ class EventParticipantResource extends JsonResource
$presenceDaysSupport = $presenceDaysSupport - 1;
}
+
+
+
return array_merge(
$this->resource->toArray(),
[
+ 'birthdayDate' => $this->resource->birthday->format('Y-m-d'),
+ 'registerDate' => $this->resource->created_at->format('d.m.Y'),
+ 'fullname' => $this->resource->getFullName(),
'age' => new Age($this->resource->birthday)->getAge(),
'localgroup' => $this->resource->localGroup()->first()->name,
'swimmingPermission' => $this->resource->swimmingPermission()->first()->short,
'extendedFirstAid' => $this->resource->firstAidPermission()->first()->name,
- 'tetanusVaccination' => $this->resource->tetanus_vaccination?->format('d.m.Y'),
+ 'tetanusVaccination' => $this->resource->tetanus_vaccination?->format('d.m.Y') ?? 'Unbekannt',
'presenceDays' => ['real' => $presenceDays, 'support' => $presenceDaysSupport],
'participationType' => ParticipationType::where(['slug' => $this->resource->participation_type])->first()->name,
'needs_payment' => $this->resource->amount->getAmount() > 0 && $event->pay_direct,
@@ -49,14 +57,21 @@ class EventParticipantResource extends JsonResource
'amount_left_string' => $amountLeft->toString(),
'amount_left_value' => $amountLeft->getAmount(),
'email_1' => $this->resource->email_1,
- 'amountPaid' => ['value' => $this->resource->amount_paid, 'readable' => $this->resource->amount_paid?->toString() ?? '0,00 Euro'],
- 'amountExpected' => ['value' => $this->resource->amount, 'readable' => $this->resource->amount?->toString() ?? '0,00 Euro'],
+ 'amountPaid' => ['value' => $this->resource->amount_paid, 'readable' => $this->resource->amount_paid?->toString() ?? '0,00 Euro', 'short' => $this->resource->amount_paid?->getFormattedAmount() ?? '0,00'],
+ 'amountExpected' => ['value' => $this->resource->amount, 'readable' => $this->resource->amount?->toString() ?? '0,00 Euro', 'short' => $this->resource->amount?->getFormattedAmount() ?? '0,00'],
'alcoholicsAllowed' => new Age($this->resource->birthday)->getAge() >= $event->alcoholics_age,
'localGroupPostcode' => $this->resource->localGroup()->first()->postcode,
'localGroupCity' => $this->resource->localGroup()->first()->city,
'state' => config('postCode.map.' . $this->resource->postcode),
'localGroupState' => config('postCode.map.' . $this->resource->localGroup()->first()->postcode),
'birthday' => $this->resource->birthday->format('d.m.Y'),
+ 'eatingHabit' => EatingHabit::where('slug', $this->resource->eating_habit)->first()->name,
+ 'efzStatusReadable' => match($this->resource->efz_status) {
+ EfzStatus::EFZ_STATUS_CHECKED_VALID => 'Gültig',
+ EfzStatus::EFZ_STATUS_CHECKED_INVALID => 'Ungültig',
+ EfzStatus::EFZ_STATUS_NOT_CHECKED => 'Nicht geprüft',
+ EfzStatus::EFZ_STATUS_NOT_REQUIRED => 'Nicht erforderlich',
+ },
]
);
}
diff --git a/app/Resources/LocalGroupResource.php b/app/Resources/LocalGroupResource.php
index 7ac11eb..6404281 100644
--- a/app/Resources/LocalGroupResource.php
+++ b/app/Resources/LocalGroupResource.php
@@ -17,6 +17,7 @@ class LocalGroupResource extends JsonResource {
'email' => $this->resource->email,
'city' => $this->resource->city,
'postalcode' => $this->resource->postcode,
+ 'slug' => $this->resource->slug,
];
}
}
diff --git a/app/Views/Components/Modal.vue b/app/Views/Components/Modal.vue
index e4ef2fe..5911f9b 100644
--- a/app/Views/Components/Modal.vue
+++ b/app/Views/Components/Modal.vue
@@ -112,7 +112,7 @@ onUnmounted(() => {
background: white;
border-radius: 12px;
- max-width: 600px;
+ max-width: 1200px;
width: 90%;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
outline: none;
diff --git a/public/css/app.css b/public/css/app.css
index fbc9c61..cd9ab77 100644
--- a/public/css/app.css
+++ b/public/css/app.css
@@ -29,7 +29,7 @@ h1, h2, h3, h4, h5, h6 {
.main {
margin: 0 auto;
- box-shadow: 20px 54px 15px rgba(0, 0, 0, 0.1);
+ box-shadow: 20px 20px 15px rgba(0, 0, 0, 0.1);
border-radius: 0 10px 0 0;
flex: 1;
display: flex;
diff --git a/public/css/elements.css b/public/css/elements.css
index c44327b..a95134e 100644
--- a/public/css/elements.css
+++ b/public/css/elements.css
@@ -15,6 +15,7 @@ input[type="email"],
input[type="password"],
input[type="date"],
input[type="number"],
+textarea,
select {
width: 100%;
font-size: 13pt;
@@ -34,6 +35,7 @@ input[type="email"]:focus,
input[type="password"]:focus,
input[type="date"]:focus,
input[type="number"]:focus,
+textarea:focus,
select:focus {
outline: none;
border-color: #1d4899;
@@ -46,6 +48,7 @@ table {
}
input[type="button"],
+.button,
input[type="submit"] {
cursor: pointer;
background-color: #ffffff;
@@ -55,6 +58,7 @@ input[type="submit"] {
}
input[type="button"]:hover,
+.button:hover,
input[type="submit"]:hover,
.deny-button:hover,
.accept-button:hover,