From 4cfc82c7aa78bf3890ce1e76b9bcbe2b21f76666 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Wed, 15 Apr 2026 13:17:32 +0200 Subject: [PATCH] feat(ScheduleView): enhance player selection logic and eligibility checks - Introduced new methods to determine the lineup half for matches and fetch eligible member IDs based on the selected team. - Improved player selection dialog to filter visible members based on active status and eligibility, ensuring a more accurate representation of available players. - Added logic to handle preselected player IDs, enhancing the user experience during team selection. --- frontend/src/views/ScheduleView.vue | 60 ++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/frontend/src/views/ScheduleView.vue b/frontend/src/views/ScheduleView.vue index cc54f104..ca17dc33 100644 --- a/frontend/src/views/ScheduleView.vue +++ b/frontend/src/views/ScheduleView.vue @@ -640,15 +640,25 @@ export default { const readyIds = normalizePlayersList(match.playersReady); const plannedIds = normalizePlayersList(match.playersPlanned); const playedIds = normalizePlayersList(match.playersPlayed); + const preselectedIds = Array.from(new Set([...readyIds, ...plannedIds, ...playedIds])); // Fetch members for the current club const response = await apiClient.get(`/clubmembers/get/${this.currentClub}/true`); - const allMembers = response.data; - - const activeMembers = allMembers.filter(m => m.active); - - this.playerSelectionDialog.members = activeMembers.map(m => ({ + + const lineupHalf = this.getLineupHalfForMatch(match); + const eligibleMemberIds = await this.getEligibleMemberIdsForSelectedTeam(lineupHalf); + const activeMembers = allMembers.filter(member => member.active); + const allowedIds = new Set( + [...eligibleMemberIds, ...preselectedIds] + .map((id) => Number(id)) + .filter((id) => Number.isFinite(id)) + ); + const visibleMembers = allowedIds.size > 0 + ? activeMembers.filter((member) => allowedIds.has(Number(member.id))) + : activeMembers; + + this.playerSelectionDialog.members = visibleMembers.map(m => ({ ...m, isReady: readyIds.includes(m.id) || false, isPlanned: plannedIds.includes(m.id) || false, @@ -663,6 +673,46 @@ export default { this.playerSelectionDialog.loading = false; } }, + getLineupHalfForMatch(match) { + const matchDate = new Date(match?.date); + if (Number.isNaN(matchDate.getTime())) { + return 'first_half'; + } + // Rueckrunde: Januar bis Juni + return matchDate.getMonth() <= 5 ? 'second_half' : 'first_half'; + }, + async getEligibleMemberIdsForSelectedTeam(lineupHalf) { + if (!this.selectedTeam?.id) { + return []; + } + + const selectedIndex = this.teams.findIndex(team => Number(team.id) === Number(this.selectedTeam.id)); + if (selectedIndex < 0) { + return []; + } + + // Niedrigere Mannschaften = ausgewaehltes Team + alle dahinter in der sortierten Teamliste + const candidateTeams = this.teams.slice(selectedIndex); + const lineupResponses = await Promise.all(candidateTeams.map(async (team) => { + try { + const response = await apiClient.get(`/club-teams/${team.id}/lineup`, { + params: { half: lineupHalf } + }); + return Array.isArray(response.data) ? response.data : []; + } catch (error) { + return []; + } + })); + + const ids = new Set(); + lineupResponses.flat().forEach((assignment) => { + const memberId = Number(assignment?.memberId); + if (Number.isFinite(memberId)) { + ids.add(memberId); + } + }); + return Array.from(ids); + }, closePlayerSelectionDialog() { this.playerSelectionDialog.isOpen = false;