Fügt die Funktionalität zum schnellen Hinzufügen von Mitgliedern in DiaryView.vue hinzu. Implementiert einen Dialog zur Eingabe von Mitgliedsdaten, einschließlich Vorname, Nachname, Geburtsdatum und Geschlecht. Aktualisiert die Logik zur Validierung neuer Mitglieder und zur Integration in die Mitgliederliste.

This commit is contained in:
Torsten Schulz (local)
2025-09-21 19:25:30 +02:00
parent d90acf43e1
commit 09ffd1db3d

View File

@@ -263,6 +263,9 @@
<span class="pointer" @click="openTagInfos(member)"></span>
</li>
</ul>
<div class="add-participant">
<button @click="openQuickAddDialog" class="quick-add-btn">+ Schnell hinzufügen</button>
</div>
</div>
</div>
</div>
@@ -343,6 +346,48 @@
</ul>
</form>
</div>
<!-- Schnell hinzufügen Dialog -->
<div v-if="showQuickAddDialog" class="modal-overlay" @click.self="closeQuickAddDialog">
<div class="modal">
<div class="modal-header">
<h3>Neues Mitglied hinzufügen</h3>
</div>
<div class="modal-body">
<div class="form-row">
<div class="form-group">
<label for="firstName">Vorname:</label>
<input type="text" id="firstName" v-model="newMember.firstName" required />
</div>
<div class="form-group">
<label for="lastName">Nachname:</label>
<input type="text" id="lastName" v-model="newMember.lastName" required />
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="birthDate">Geburtsdatum:</label>
<input type="date" id="birthDate" v-model="newMember.birthDate" />
</div>
<div class="form-group">
<label for="gender">Geschlecht:</label>
<select id="gender" v-model="newMember.gender">
<option value="">Bitte wählen</option>
<option value="male">Männlich</option>
<option value="female">Weiblich</option>
<option value="diverse">Divers</option>
</select>
</div>
</div>
<div class="form-row">
<button class="btn-secondary" @click="closeQuickAddDialog">Abbrechen</button>
<button class="btn-primary" @click="createAndAddMember" :disabled="!isNewMemberValid">
Erstellen & Hinzufügen
</button>
</div>
</div>
</div>
</div>
</div>
</template>
@@ -433,6 +478,14 @@ export default {
// Aktivitäts-Teilnehmer
activityMembersOpenId: null,
activityMembersMap: {}, // key: activityId, value: Set(participantIds)
// Schnell hinzufügen Dialog
showQuickAddDialog: false,
newMember: {
firstName: '',
lastName: '',
birthDate: '',
gender: ''
}
};
},
watch: {
@@ -465,6 +518,12 @@ export default {
const presentSet = new Set(this.participants);
return this.members.filter(m => presentSet.has(m.id));
},
isNewMemberValid() {
return this.newMember.firstName.trim() !== '' &&
this.newMember.lastName.trim() !== '' &&
(this.newMember.gender === 'male' || this.newMember.gender === 'female' || this.newMember.gender === 'diverse');
},
},
methods: {
async init() {
@@ -1458,6 +1517,80 @@ export default {
alert('Fehler beim Aktualisieren der Aktivitäts-Teilnehmer');
}
},
// Schnell hinzufügen Dialog Methoden
openQuickAddDialog() {
this.showQuickAddDialog = true;
this.newMember = {
firstName: '',
lastName: '',
birthDate: '',
gender: ''
};
},
closeQuickAddDialog() {
this.showQuickAddDialog = false;
this.newMember = {
firstName: '',
lastName: '',
birthDate: '',
gender: ''
};
},
async createAndAddMember() {
if (!this.isNewMemberValid) return;
try {
// Erstelle neues Mitglied
const memberData = {
firstName: this.newMember.firstName.trim(),
lastName: this.newMember.lastName.trim(),
birthDate: this.newMember.birthDate || null,
gender: this.newMember.gender
};
const response = await apiClient.post(`/clubmembers/set/${this.currentClub}`, {
id: null, // null für neues Mitglied
firstname: memberData.firstName,
lastname: memberData.lastName,
street: '',
city: '',
birthdate: memberData.birthDate,
phone: '',
email: '',
active: true,
testMembership: false,
picsInInternetAllowed: false,
gender: memberData.gender
});
if (response.data.result === 'success') {
// Lade die aktualisierte Mitgliederliste
const membersResponse = await apiClient.get(`/clubmembers/get/${this.currentClub}/false`);
this.members = membersResponse.data;
// Finde das neu erstellte Mitglied (das letzte in der Liste)
const newMember = this.members[this.members.length - 1];
// Füge das neue Mitglied als Teilnehmer hinzu
await this.toggleParticipant(newMember.id);
// Schließe den Dialog
this.closeQuickAddDialog();
// Zeige Erfolgsmeldung
alert(`Mitglied "${newMember.firstName} ${newMember.lastName}" wurde erfolgreich erstellt und hinzugefügt!`);
} else {
throw new Error('Fehler beim Erstellen des Mitglieds');
}
} catch (error) {
console.error('Fehler beim Erstellen des Mitglieds:', error);
alert('Fehler beim Erstellen des Mitglieds: ' + (error.response?.data?.error || error.message));
}
},
},
async mounted() {
await this.init();
@@ -1856,4 +1989,158 @@ img {
.image-icon:hover {
opacity: 1;
}
/* Schnell hinzufügen Button */
.add-participant {
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px solid #dee2e6;
}
.quick-add-btn {
background-color: #17a2b8;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 4px;
cursor: pointer;
font-size: 0.9em;
transition: background-color 0.2s ease;
white-space: nowrap;
}
.quick-add-btn:hover {
background-color: #138496;
}
.quick-add-btn:active {
background-color: #117a8b;
}
/* Modal Dialog Styles */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal {
background: white;
border-radius: 8px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
max-width: 500px;
width: 90%;
max-height: 90vh;
overflow-y: auto;
display: flex;
flex-direction: column;
}
.modal-header {
padding: 1rem 1.5rem;
border-bottom: 1px solid #dee2e6;
}
.modal-header h3 {
margin: 0;
color: #495057;
}
.modal-body {
padding: 1.5rem;
flex: 1;
display: flex;
flex-direction: column;
}
.modal-body .form-row {
display: flex !important;
gap: 1rem;
margin-bottom: 1rem;
flex-wrap: nowrap;
}
.modal-body .form-row .form-group {
flex: 1;
margin-bottom: 0;
min-width: 0;
}
.modal-body .form-row:last-child {
justify-content: flex-end;
gap: 0.5rem;
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px solid #dee2e6;
flex-wrap: nowrap;
}
.form-group {
margin-bottom: 1rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
color: #495057;
}
.form-group input,
.form-group select {
width: 100%;
padding: 0.5rem;
border: 1px solid #ced4da;
border-radius: 4px;
font-size: 1rem;
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: #80bdff;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}
.modal .btn-secondary {
background-color: #6c757d !important;
color: white !important;
border: none !important;
padding: 0.5rem 1rem !important;
border-radius: 4px !important;
cursor: pointer !important;
font-size: 0.9rem !important;
}
.modal .btn-secondary:hover {
background-color: #5a6268 !important;
}
.modal .btn-primary {
background-color: #007bff !important;
color: white !important;
border: none !important;
padding: 0.5rem 1rem !important;
border-radius: 4px !important;
cursor: pointer !important;
font-size: 0.9rem !important;
}
.modal .btn-primary:hover {
background-color: #0056b3 !important;
}
.modal .btn-primary:disabled {
background-color: #6c757d !important;
cursor: not-allowed !important;
opacity: 0.6 !important;
}
</style>