Files
mareike/app/Domains/Event/Views/Partials/ParticipantData.vue
T

469 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
import {computed, onMounted, reactive, watch} from "vue";
import AmountInput from "../../../../Views/Components/AmountInput.vue";
import DialableTelephoneNumber from "../../../../Views/Components/DialableTelephoneNumber.vue";
const staticProps = defineProps({
editMode: Boolean,
participant: Object,
event: Object,
});
const props = reactive({
participant: staticProps.participant,
});
onMounted(async () => {
const response = await fetch('/api/v1/event/participant/' + staticProps.participant.identifier + '/');
const data = await response.json();
Object.assign(props, data);
});
const emit = defineEmits([
'closeParticipantDetails',
'markCocExisting',
'paymentComplete',
'cancelParticipation',
'editParticipant',
'saveParticipant',
]);
const form = reactive({
firstname: '',
lastname: '',
nickname: '',
address_1: '',
address_2: '',
postcode: '',
city: '',
localgroup: '',
birthday: '',
email_1: '',
phone_1: '',
contact_person: '',
email_2: '',
phone_2: '',
arrival: '',
departure: '',
participationType: '',
eatingHabit: '',
paymentMethod: '',
allergies: '',
intolerances: '',
medications: '',
extendedFirstAid: '',
swimmingPermission: '',
tetanusVaccination: '',
notes: '',
amountPaid: '',
amountExpected: '',
cocStatus: '',
participationOptions: {},
});
// Teilnahmeoptionen des Events (Definition mit Titel/Frage/Optionen).
const participationQuestions = computed(() => staticProps.event?.participationOptions ?? []);
// Gewählte Antwort (Options-Label) eines Teilnehmers zu einer Frage für die Ansicht „Titel: Antwort".
function answerLabelFor(questionKey) {
const answer = (props.participant?.participationOptions ?? []).find(o => o.questionKey === questionKey);
return answer?.valueLabel ?? '—';
}
watch(
() => props.participant,
(participant) => {
form.firstname = participant?.firstname ?? '';
form.lastname = participant?.lastname ?? '';
form.nickname = participant?.nickname ?? '';
form.address_1 = participant?.address_1 ?? '';
form.address_2 = participant?.address_2 ?? '';
form.postcode = participant?.postcode ?? '';
form.city = participant?.city ?? '';
form.localgroup = participant?.local_group ?? '';
form.birthday = participant?.birthdayDate ?? '';
form.email_1 = participant?.email_1 ?? '';
form.phone_1 = participant?.phone_1 ?? '';
form.contact_person = participant?.contact_person ?? '';
form.email_2 = participant?.email_2 ?? '';
form.phone_2 = participant?.phone_2 ?? '';
form.arrival = participant?.arrivalDate ?? '';
form.departure = participant?.departureDate ?? '';
form.participationType = participant?.participation_type ?? '';
form.eatingHabit = participant?.eating_habit ?? '';
form.paymentMethod = participant?.payment_method ?? '';
form.allergies = participant?.allergies ?? '';
form.intolerances = participant?.intolerances ?? '';
form.medications = participant?.medications ?? '';
form.extendedFirstAid = participant?.first_aid_permission ?? '';
form.swimmingPermission = participant?.swimming_permission ?? '';
form.tetanusVaccination = participant?.tetanusVaccinationEdit ?? '';
form.notes = participant?.notes ?? '';
form.amountPaid = participant?.amountPaid.short ?? '';
form.amountExpected = participant?.amountExpected.short ?? '';
form.cocStatus = participant?.efz_status ?? '';
form.participationOptions = Object.fromEntries(
(participant?.participationOptions ?? []).map(o => [o.questionKey, o.value])
);
},
{ immediate: true }
);
function markCocExisting(participant) {
emit('markCocExisting', participant);
close();
}
function paymentComplete(participant) {
emit('paymentComplete', participant);
close();
}
function close() {
emit('closeParticipantDetails');
}
function cancelParticipation(participant) {
emit('cancelParticipation', participant);
close();
}
function enableEditMode() {
emit('editParticipant');
}
function saveParticipant() {
emit('saveParticipant', { ...form });
close();
}
</script>
<template>
<div>
<h2>Anmeldedetails</h2>
<div class="participationData">
<div>
<h3>Persönliche Daten</h3>
<table>
<tr>
<th>Name</th>
<td>
<span v-if="!staticProps.editMode">
{{ props.participant.firstname }} {{ props.participant.lastname }}
</span>
<span v-else>
<input v-model="form.firstname" type="text" placeholder="Vorname" />
<input v-model="form.lastname" type="text" placeholder="Nachname" />
</span>
</td>
</tr>
<tr>
<th>Pfadiname</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.nickname }}</span>
<input v-else v-model="form.nickname" type="text" />
</td>
</tr>
<tr>
<th>Anschrift</th>
<td>
<span v-if="!staticProps.editMode">
{{ props.participant.address_1 }}<br />
{{ props.participant.address_2 }}<br />
{{ props.participant.postcode }}
{{ props.participant.city }}
</span>
<span v-else>
<input v-model="form.address_1" type="text" placeholder="Adresse 1" />
<input v-model="form.address_2" type="text" placeholder="Adresse 2" />
<input v-model="form.postcode" type="text" placeholder="PLZ" />
<input v-model="form.city" type="text" placeholder="Ort" />
</span>
</td>
</tr>
<tr>
<th>Stamm</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.localgroup }}</span>
<select v-else v-model="form.localgroup">
<option v-for="group in staticProps.event.contributingLocalGroups" :key="group.id" :value="group.slug">{{ group.name }}</option>
</select>
</td>
</tr>
<tr>
<th>Geburtsdatum</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.birthday }}</span>
<input v-else v-model="form.birthday" type="date" />
</td>
</tr>
</table>
</div>
<div>
<h3>Kontaktdaten</h3>
<table>
<tr>
<th>E-Mail</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.email_1 }}</span>
<input v-else v-model="form.email_1" type="email" />
</td>
</tr>
<tr>
<th>Telefon</th>
<td>
<DialableTelephoneNumber v-if="!staticProps.editMode" :number="props.participant.phone_1" />
<input v-else v-model="form.phone_1" type="text" />
</td>
</tr>
<tr>
<th>Ansprechperson</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.contact_person }}</span>
<input v-else v-model="form.contact_person" type="text" />
</td>
</tr>
<tr>
<th>Ansprechperson E-Mail</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.email_2 }}</span>
<input v-else v-model="form.email_2" type="email" />
</td>
</tr>
<tr>
<th>Ansprechperson Telefon</th>
<td>
<DialableTelephoneNumber v-if="!staticProps.editMode" :number="props.participant.phone_2" />
<input v-else v-model="form.phone_2" type="text" />
</td>
</tr>
</table>
</div>
</div>
<div class="participationData">
<div>
<h3>Teilnahmedetails</h3>
<table>
<tr>
<th>Anreise</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.arrival }}</span>
<input v-else v-model="form.arrival" type="date" />
</td>
</tr>
<tr>
<th>Abreise</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.departure }}</span>
<input v-else v-model="form.departure" type="date" />
</td>
</tr>
<tr>
<th>Teilnahmegruppe</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.participationType }}</span>
<select v-else v-model="form.participationType">
<option
v-for="participationType in staticProps.event.participationTypes"
:value="participationType.type.slug"
>
{{ participationType.type.name }}
</option>
</select>
</td>
</tr>
<tr>
<th>Ernährung</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.eatingHabit }}</span>
<select v-else v-model="form.eatingHabit">
<option
v-for="eatingHabit in staticProps.event.eatingHabits"
:value="eatingHabit.slug"
>
{{ eatingHabit.name }}
</option>
</select>
</td>
</tr>
<tr>
<th>Zahlungsmethode</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.paymentMethod }}</span>
<select v-else v-model="form.paymentMethod">
<option
v-for="paymentMethod in staticProps.event.paymentMethods"
:value="paymentMethod.slug"
>
{{ paymentMethod.name }}
</option>
</select>
</td>
</tr>
<tr>
<th>eFZ-Status</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.efzStatusReadable }}</span>
<select v-else v-model="form.cocStatus">
<option value="not_checked">Nicht geprüft</option>
<option value="not_required">Nicht erforderlich</option>
<option value="checked_valid">Geprüft und Vorhanden</option>
<option value="checked_invalid">Nicht vorhanden</option>
</select>
</td>
</tr>
<tr>
<th>Beitrag</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.amountPaid.readable }} / {{ props.participant.amountExpected.readable }}</span>
<span v-else>
<AmountInput v-model="form.amountPaid" style="width:74px" /> Euro
/
<AmountInput v-model="form.amountExpected" style="width: 74px" /> Euro
</span>
</td>
</tr>
</table>
</div>
<div>
<h3>Medizinische Informationen</h3>
<table>
<tr>
<th>Allergien</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.allergies }}</span>
<input type="text" v-else v-model="form.allergies" />
</td>
</tr>
<tr>
<th>Unverträglichkeiten</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.intolerances }}</span>
<input type="text" v-else v-model="form.intolerances" />
</td>
</tr>
<tr>
<th>Medikamente</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.medications }}</span>
<input type="text" v-else v-model="form.medications" />
</td>
</tr>
<tr>
<th>Erweiterte Erste Hilfe</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.extendedFirstAid }}</span>
<select v-else v-model="form.extendedFirstAid">
<option value="FIRST_AID_PERMISSION_ALLOWED">Erlaubt</option>
<option value="FIRST_AID_PERMISSION_DENIED">Verweigert</option>
</select>
</td>
</tr>
<tr>
<th>Badeerlaubnis</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.swimmingPermission }}</span>
<select v-else v-model="form.swimmingPermission">
<option value="SWIMMING_PERMISSION_ALLOWED">Vorhanden, kann schwimmen</option>
<option value="SWIMMING_PERMISSION_LIMITED">Vorhanden, kann nicht schwimmen</option>
<option value="SWIMMING_PERMISSION_DENIED">Verweigert</option>
</select>
</td>
</tr>
<tr>
<th>Letzte Tetanus-Impfung</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.tetanusVaccination }}</span>
<input v-else v-model="form.tetanusVaccination" type="date" />
</td>
</tr>
<tr>
<th>Anmerkungen</th>
<td>
<span v-if="!staticProps.editMode">{{ props.participant.notes }}</span>
<textarea v-else v-model="form.notes"></textarea>
</td>
</tr>
</table>
</div>
</div>
<div class="participationData" v-if="participationQuestions.length > 0">
<div>
<h3>Teilnahmeoptionen</h3>
<table>
<tr v-for="question in participationQuestions" :key="question.key">
<th>{{ question.title || question.label }}</th>
<td>
<span v-if="!staticProps.editMode">{{ answerLabelFor(question.key) }}</span>
<select v-else v-model="form.participationOptions[question.key]">
<option value=""> keine </option>
<option v-for="option in question.options" :key="option.value" :value="option.value">
{{ option.label }}
</option>
</select>
</td>
</tr>
</table>
</div>
<div></div>
</div>
</div>
<button v-if="!staticProps.editMode" class="button" @click="enableEditMode">Bearbeiten</button>
<button v-else class="button" @click="saveParticipant">Speichern</button>
<button v-if="!props.participant.unregistered" class="button" @click="paymentComplete(props.participant)">Zahlung vollständig</button>
<button v-if="!props.participant.unregistered" class="button" @click="markCocExisting(props.participant)">eFZ liegt vor</button>
<button v-if="!props.participant.unregistered" class="button" @click="cancelParticipation(props.participant)">Abmelden</button>
<button class="button" @click="close">Schließen</button>
</template>
<style scoped>
.participationData {
display: flex;
margin-bottom: 20px;
gap: 20px;
}
.participationData table tr th {
width: 200px;
}
.participationData div {
flex: 1;
vertical-align: top;
}
input[type="text"],
input[type="email"],
input[type="date"],
textarea
{
width: 250px
}
textarea {
height: 100px;
}
select {
width: 262px;
}
</style>