Merge branch 'main' into tournament

This commit is contained in:
Torsten Schulz
2025-03-13 16:24:08 +01:00
10 changed files with 2176 additions and 1374 deletions

View File

@@ -158,6 +158,11 @@
</div>
</div>
<div class="column">
<div>
<button @click="addAccident">Unfall buchen</button>
<div v-if="accidents.length > 0">
</div>
</div>
<h3>Aktivitäten</h3>
<textarea v-model="newActivity"></textarea>
<button @click="addActivity">Aktivität hinzufügen</button>
@@ -176,9 +181,9 @@
:checked="isParticipant(member.id)">
<span class="clickable" @click="selectMember(member)"
:class="{ highlighted: selectedMember && selectedMember.id === member.id }">{{
member.firstName
member ? member.firstName : ''
}} {{
member.lastName }}</span>
member ? member.lastName : '' }}</span>
<span v-if="false" @click="openNotesModal(member)" class="clickable">📝</span>
<span @click="showPic(member)" class="img-icon" v-if="member.hasImage">&#x1F5BC;</span>
<span class="pointer" @click="openTagInfos(member)"></span>
@@ -241,7 +246,27 @@
<img :src="imageUrl" @click="closeImage" />
</div>
</div>
<img v-if="showImage" class="img" :src="imageUrl" @click="closeImage()" />
<div v-if="showAccidentForm" class="accidentForm">
<form @submit.prevent="submitAccident">
<div>
<label for="memberId">Mitglied:</label>
<select id="memberId" v-model="accident.memberId">
<template v-for="member in members" :key="member.id" :value="member.id">
<option v-if="participants.indexOf(member.id) >= 0" :value="member.id">{{ member.firstName + ' ' + member.lastName }}</option>
</template>
</select>
</div>
<div>
<label for="accident">Unfall:</label>
<textarea id="accident" v-model="accident.accident" required ></textarea>
</div>
<button type="button" @click="saveAccident">Eintragen</button>
<button type="button" @click="closeAccidentForm">Schießen</button>
<ul>
<li v-for="accident in accidents" :key="accident.id">{{ accident.firstName + ' ' + accident.lastName + ': ' + accident.accident}}</li>
</ul>
</form>
</div>
</template>
<script>
@@ -307,6 +332,13 @@ export default {
bellSound: new Audio('/sound/bell-123742.mp3'),
thumbSound: new Audio('/sound/thump-105302.mp3'),
timeChecker: null,
showAccidentForm: false,
accident: {
memberId: '',
diaryDateId: '',
accident: '',
},
accidents: [],
};
},
watch: {
@@ -327,6 +359,7 @@ export default {
const lastItem = this.trainingPlan[this.trainingPlan.length - 1];
return lastItem.endTime;
},
filteredPredefinedActivities() {
const input = this.newPlanItem.activity.toLowerCase();
return this.predefinedActivities.filter(activity =>
@@ -343,10 +376,12 @@ export default {
await this.loadPredefinedActivities();
}
},
setCurrentDate() {
const today = new Date().toISOString().split('T')[0];
this.newDate = today;
},
async handleDateChange() {
this.showForm = this.date === 'new';
if (this.date && this.date !== 'new') {
@@ -378,6 +413,7 @@ export default {
this.participants = [];
}
},
initializeSortable() {
const el = this.$refs.sortableList;
Sortable.create(el, {
@@ -385,6 +421,7 @@ export default {
onEnd: this.onDragEnd,
});
},
async createDate() {
try {
const response = await apiClient.post(`/diary/${this.currentClub}`, {
@@ -402,6 +439,7 @@ export default {
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
}
},
async updateTrainingTimes() {
try {
const dateId = this.date.id;
@@ -416,22 +454,27 @@ export default {
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
}
},
async loadMembers() {
const response = await apiClient.get(`/clubmembers/get/${this.currentClub}/false`);
this.members = response.data;
},
async loadParticipants(dateId) {
const response = await apiClient.get(`/participants/${dateId}`);
this.participants = response.data.map(participant => participant.memberId);
},
async loadActivities(dateId) {
const response = await apiClient.get(`/activities/${dateId}`);
this.activities = response.data;
},
async loadTags() {
const response = await apiClient.get('/tags');
this.availableTags = response.data;
},
async loadPredefinedActivities() {
try {
const response = await apiClient.get('/predefined-activities');
@@ -440,6 +483,7 @@ export default {
console.error('Fehler beim Laden der vordefinierten Aktivitäten:', error);
}
},
async loadGroups() {
try {
const response = await apiClient.get(`/group/${this.currentClub}/${this.date.id}`);
@@ -448,9 +492,11 @@ export default {
console.log(error);
}
},
isParticipant(memberId) {
return this.participants.includes(memberId);
},
async toggleParticipant(memberId) {
const isParticipant = this.isParticipant(memberId);
const dateId = this.date.id;
@@ -468,6 +514,7 @@ export default {
this.participants.push(memberId);
}
},
async addActivity() {
const dateId = this.date.id;
if (this.newActivity) {
@@ -481,14 +528,17 @@ export default {
this.selectedActivityTags = [];
}
},
async selectMember(member) {
this.selectedMember = member;
},
async openNotesModal(member) {
this.noteMember = member;
this.loadMemberNotesAndTags(this.date.id, member.id);
this.showNotesModal = true;
},
async loadMemberNotesAndTags(diaryDateId, memberId) {
this.doMemberTagUpdates = false;
try {
@@ -509,6 +559,7 @@ export default {
}
this.doMemberTagUpdates = true;
},
async addMemberNote() {
if (this.newNoteContent && this.selectedMember) {
const response = await apiClient.post(`/diarymember/${this.currentClub}/note`, {
@@ -523,21 +574,25 @@ export default {
alert('Bitte wählen Sie einen Teilnehmer aus und geben Sie einen Notiztext ein.');
}
},
async deleteNote(noteId) {
const response = await apiClient.delete(`/diarymember/${this.currentClub}/note/${noteId}`, {
clubId: this.currentClub
});
this.notes = response.data;
},
closeNotesModal() {
this.showNotesModal = false;
},
async addNewTagFromInput(event) {
const inputValue = event.target.value.trim();
if (inputValue) {
await this.addNewTag(inputValue);
}
},
async addNewTag(newTagName) {
try {
const response = await apiClient.post('/tags', { name: newTagName });
@@ -549,12 +604,14 @@ export default {
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
}
},
async addNewTagForMemberFromInput(event) {
const inputValue = event.target.value.trim();
if (inputValue) {
await this.addNewTagForMember(inputValue);
}
},
async addNewTagForMember(newTagName) {
try {
const response = await apiClient.post('/tags', { name: newTagName });
@@ -567,6 +624,7 @@ export default {
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
}
},
async linkTagToDiaryDate(tag) {
if (!tag || !tag.id) {
console.warn("Ungültiges Tag-Objekt:", tag);
@@ -583,6 +641,7 @@ export default {
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
}
},
async linkTagToMemberAndDate(tag) {
try {
const tagId = tag.id;
@@ -596,6 +655,7 @@ export default {
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
}
},
async updateActivityTags() {
try {
const selectedTags = this.selectedActivityTags;
@@ -613,6 +673,7 @@ export default {
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
}
},
async updateMemberTags() {
if (!this.doMemberTagUpdates || !this.selectedMember) {
return;
@@ -629,6 +690,7 @@ export default {
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
}
},
async removeMemberTag(tagId) {
try {
await apiClient.post(`/diarymember/${this.currentClub}/tag/remove`, {
@@ -642,6 +704,7 @@ export default {
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
}
},
async removeMemberNote(noteContent) {
try {
await apiClient.post(`/diarymember/${this.currentClub}/note/remove`, {
@@ -655,6 +718,7 @@ export default {
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
}
},
async removeActivityTag(tag) {
try {
const tagId = tag.id;
@@ -667,6 +731,7 @@ export default {
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
}
},
async handleActivityTagInput(tags) {
const newTags = tags.filter(tag => !this.previousActivityTags.some(prevTag => prevTag.id === tag.id));
for (const tag of newTags) {
@@ -674,12 +739,14 @@ export default {
}
this.previousActivityTags = [...tags];
},
selectPredefinedActivity(activity) {
this.newPlanItem.activity = activity.name;
this.newPlanItem.durationText = activity.durationText;
this.newPlanItem.duration = activity.duration || '';
this.showDropdown = false;
},
async addPlanItem() {
try {
if (this.addNewItem || this.addNewTimeblock) {
@@ -710,6 +777,7 @@ export default {
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
}
},
async updatePlanItemGroup(planItemId, groupId) {
try {
await apiClient.put(`/diary-date-activities/${this.currentClub}/${planItemId}/group`, {
@@ -720,6 +788,7 @@ export default {
console.error('Fehler beim Aktualisieren der Planungs-Item-Gruppe:', error);
}
},
async removePlanItem(planItemId) {
try {
await apiClient.delete(`/diary-date-activities/${this.currentClub}/${planItemId}`);
@@ -1028,6 +1097,29 @@ export default {
time !== this.trainingStart && time !== this.trainingEnd
);
},
async addAccident() {
this.accidents = [];
this.showAccidentForm = !this.showAccidentForm;
await this.getAccidents();
},
async saveAccident() {
const accident = this.accident;
accident['clubId'] = this.currentClub;
accident['diaryDateId'] = this.date.id;
const response = await apiClient.post('/accident', this.accident);
this.getAccidents();
},
async getAccidents() {
const response = await apiClient.get(`/accident/${this.currentClub}/${this.date.id}`);
this.accidents = response.data;
},
closeAccidentForm() {
this.showAccidentForm = false;
},
},
async mounted() {
await this.init();
@@ -1325,4 +1417,18 @@ img {
.tag-list {
margin: 0 0 1em 1.5em;
}
.accidentForm {
display: block;
position: fixed;
width: 70em;
height: 40em;
top: calc(50% - 20em);
left: calc(50% - 35em);
border: 2px solid #555;
box-shadow: 4px 4px 3px #aaa;
overflow: hidden;
padding: 3px;
background-color: #fff;
}
</style>