Signup for events implemented

This commit is contained in:
2026-03-22 00:06:03 +01:00
parent b8341890d3
commit 405591d6dd
13 changed files with 428 additions and 24 deletions

View File

@@ -7,8 +7,6 @@ use App\Providers\InertiaProvider;
use App\Scopes\CommonController;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Js;
class DashboardController extends CommonController {
public function __invoke(Request $request) {

View File

@@ -6,17 +6,16 @@ use App\Domains\Event\Actions\CertificateOfConductionCheck\CertificateOfConducti
use App\Domains\Event\Actions\CertificateOfConductionCheck\CertificateOfConductionCheckRequest;
use App\Domains\Event\Actions\SignUp\SignUpCommand;
use App\Domains\Event\Actions\SignUp\SignUpRequest;
use App\Mail\EventSignUpSuccessfull;
use App\Models\Tenant;
use App\Models\User;
use App\Providers\DoubleCheckEventRegistrationProvider;
use App\Providers\InertiaProvider;
use App\Resources\EventResource;
use App\Resources\UserResource;
use App\Scopes\CommonController;
use App\ValueObjects\Amount;
use http\Env\Response;
use DateTime;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Mail;
class SignupController extends CommonController {
public function __invoke(int $eventId, Request $request) {
@@ -76,11 +75,17 @@ class SignupController extends CommonController {
$departure = \DateTime::createFromFormat('Y-m-d', $registrationData['departure']);
$tetanusVaccination = $registrationData['tetanusVaccination'] ? \DateTime::createFromFormat('Y-m-d', $registrationData['tetanusVaccination']) : null;
// Steps:
// 1. Check, if bereits angemeldet
$doubleCheckEventRegistrationProvider = new DoubleCheckEventRegistrationProvider(
$event,
$registrationData['vorname'],
$registrationData['nachname'],
$registrationData['email_1'],
DateTime::createFromFormat('Y-m-d', $registrationData['geburtsdatum']));
if ($doubleCheckEventRegistrationProvider->isRegistered()) {
return response()->json(['status' => 'exists']);
}
//
$amount = $eventResource->calculateAmount(
$registrationData['participationType'],
$registrationData['beitrag'],
@@ -138,9 +143,15 @@ class SignupController extends CommonController {
$signupResponse->participant->efz_status = $certificateOfConductionCheckResponse->status;
$signupResponse->participant->save();
// 6. E-Mail senden & Bestätigung senden
Mail::to($signupResponse->participant->email_1)->send(new EventSignUpSuccessfull(
participant: $signupResponse->participant,
));
if ($signupResponse->participant->email_2 !== null) {
Mail::to($signupResponse->participant->email_2)->send(new EventSignUpSuccessfull(
participant: $signupResponse->participant,
));
}
return response()->json(
[

View File

@@ -18,8 +18,6 @@ const props = defineProps({
localGroups: Array,
})
console.log(props.participantData);
const emit = defineEmits(['registrationDone'])
const {
@@ -48,7 +46,7 @@ const steps = [
:participant="submitResult?.participant"
:event="event"
/>
<SubmitAlreadyExists v-else-if="submitResult?.type === 'exists'" :data="submitResult.data" />
<SubmitAlreadyExists v-else-if="submitResult?.status === 'exists'" :event="event" />
<template v-else>
<!-- Fortschrittsleiste (ab Step 2) -->

View File

@@ -1,12 +1,18 @@
<script setup>
defineProps({ data: Object })
const props = defineProps({
event: Object
})
</script>
<template>
<div style="padding: 20px 0;">
<h3>{{ data.nicename }}</h3>
<p>{{ data.text_1 }}</p>
<p>{{ data.text_2 }}</p>
<a :href="data.email_link" style="color: #2563eb;">{{ data.email_text }}</a>
<h3>Registrierung nicht möglich</h3>
<p>
Leider konnte deine Anmeldung nicht ausgeführt werden, da du bereits für die Veranstaltung {{props.event.name}} angemeldet bist.
</p>
<p>
Falls du bereits angemeldet warst und abgemeldet wurdest, oder andere Fragen hast, kontaktiere die Veranstaltungsleitung:
<a href="mailto:{{props.event.email}}">{{props.event.email}}</a>
</p>
</div>
</template>

View File

@@ -16,7 +16,7 @@ console.log(props.participant)
<table class="form-table" style="margin-bottom: 20px;">
<tr><td>Anreise:</td><td>{{ props.participant.arrival }}</td></tr>
<tr><td>Abreise:</td><td>{{ props.participant.departure }}</td></tr>
<tr><td>Teilnahmegruppe:</td><td>{{ props.participant.participation_group }}</td></tr>
<tr><td>Teilnahmegruppe:</td><td>{{ props.participant.participationType }}</td></tr>
</table>
<div v-if="props.participant.efz_status === 'NOT_CHECKED'" style="font-weight: bold; color: #b45309; margin-bottom: 20px;">

View File

@@ -14,6 +14,35 @@ function formatDate(dateString) {
if (!dateString) return ''
return format(parseISO(dateString), 'dd.MM.yyyy')
}
function participationGroup() {
if (props.formData.participationType === 'team') {
return 'Kernteam';
}
if (props.formData.participationType === 'participant') {
return 'Teilnehmende';
}
if (props.formData.participationType === 'volunteer') {
return 'Unterstützende';
}
return 'Sonstige';
}
function eatingHabit() {
if (props.formData.eatingHabit === 'EATING_HABIT_VEGAN') {
return 'Vegan';
}
if (props.formData.eatingHabit === 'EATING_HABIT_VEGETARIAN') {
return 'Vegetarisch';
}
return 'Omnivor';
}
</script>
<template>
@@ -23,6 +52,65 @@ function formatDate(dateString) {
<div v-if="summaryLoading" style="color: #6b7280; padding: 20px 0;">Wird geladen</div>
<div v-else>
<table class="form-table" style="margin-bottom: 20px;">
<tr>
<td>Dein Name:</td>
<td>{{props.formData.vorname}} {{props.formData.vorname}}</td>
</tr>
<tr>
<td>Deine E-Mail:</td>
<td>{{props.formData.email_1}}</td>
</tr>
<tr v-if="props.formData.ansprechpartner !== ''">
<td>Name deiner Kontaktperson:</td>
<td>{{props.formData.ansprechpartner}}</td>
</tr>
<tr v-if="props.formData.email_2 !== ''">
<td>E-Mail-Adresse deiner Kontaktperson:</td>
<td>{{props.formData.email_2}}</td>
</tr>
<tr v-if="props.formData.telefon_2 !== ''">
<td>Telefonnummer deiner Kontaktperson:</td>
<td>{{props.formData.telefon_2}}</td>
</tr>
<tr>
<td>Teilnahmegruppe:</td>
<td>{{ participationGroup() }}</td>
</tr>
<tr>
<td>Foto-Erlaubnis:</td>
<td>
<strong>Social Media:</strong> {{props.formData.foto.socialmedia ? 'Ja' : 'Nein'}},
<strong>Printmedien:</strong> {{props.formData.foto.print ? 'Ja' : 'Nein'}},
<strong>Webseite:</strong> {{props.formData.foto.webseite ? 'Ja' : 'Nein'}},
<strong>Partnerorganisationen:</strong> {{props.formData.foto.partner ? 'Ja' : 'Nein'}},
<strong>Interne Zwecke:</strong> {{props.formData.foto.intern ? 'Ja' : 'Nein'}}
</td>
</tr>
<tr>
<td>Allergien:</td>
<td>{{props.formData.allergien}}</td>
</tr>
<tr>
<td>Lebensmittelunverträglichkeiten:</td>
<td>{{props.formData.intolerances}}</td>
</tr>
<tr>
<td>Ernährungsweise:</td>
<td>{{eatingHabit()}}</td>
</tr>
<tr><td>Veranstaltung:</td><td><strong>{{ event.name }}</strong></td></tr>
<tr><td>Anreise:</td><td>{{ formatDate(formData.arrival) }}</td></tr>
<tr><td>Abreise:</td><td>{{ formatDate(formData.departure) }}</td></tr>