From 6b24ac00718e3548266ad1fa5e8c96760d85754a Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Fri, 19 Dec 2025 10:14:41 +0100 Subject: [PATCH] Implement toggle functionality for Mannschaftsspieler status in Mitgliederbereich. Add button for editing status and update local state upon toggling. Enhance API response handling to include isMannschaftsspieler attribute for user data retrieval. --- pages/mitgliederbereich/mitglieder.vue | 74 ++++++++++-- server/api/members.get.js | 6 +- .../members/toggle-mannschaftsspieler.post.js | 105 ++++++++++++++++++ 3 files changed, 174 insertions(+), 11 deletions(-) create mode 100644 server/api/members/toggle-mannschaftsspieler.post.js diff --git a/pages/mitgliederbereich/mitglieder.vue b/pages/mitgliederbereich/mitglieder.vue index 935394b..a192c07 100644 --- a/pages/mitgliederbereich/mitglieder.vue +++ b/pages/mitgliederbereich/mitglieder.vue @@ -81,13 +81,30 @@ Nur für Vorstand - - Ja + {{ member.isMannschaftsspieler ? 'Ja' : 'Nein' }} + + + {{ member.isMannschaftsspieler ? 'Ja' : 'Nein' }} - -
@@ -163,11 +180,29 @@ > Aus Login-System - - Mannschaftsspieler + Mannschaftsspieler: {{ member.isMannschaftsspieler ? 'Ja' : 'Nein' }} + + + Mannschaftsspieler: {{ member.isMannschaftsspieler ? 'Ja' : 'Nein' }}
@@ -618,6 +653,27 @@ const saveMember = async () => { } } +const toggleMannschaftsspieler = async (member) => { + try { + const response = await $fetch('/api/members/toggle-mannschaftsspieler', { + method: 'POST', + body: { memberId: member.id } + }) + + // Update local state immediately + member.isMannschaftsspieler = response.isMannschaftsspieler + + // Reload to ensure consistency + await loadMembers() + } catch (error) { + console.error('Fehler beim Umschalten des Mannschaftsspieler-Status:', error) + const errorMsg = error.data?.message || error.message || 'Fehler beim Umschalten des Status.' + if (window.showErrorModal) { + window.showErrorModal('Fehler', errorMsg) + } + } +} + const confirmDelete = async (member) => { window.showConfirmModal('Mitglied löschen', `Möchten Sie "${member.name}" wirklich löschen?`, async () => { try { diff --git a/server/api/members.get.js b/server/api/members.get.js index 409584a..7d78a44 100644 --- a/server/api/members.get.js +++ b/server/api/members.get.js @@ -83,7 +83,8 @@ export default defineEventHandler(async (event) => { loginEmail: user.email, loginRoles: roles, loginRole: roles[0] || 'mitglied', // Rückwärtskompatibilität - lastLogin: user.lastLogin + lastLogin: user.lastLogin, + isMannschaftsspieler: user.isMannschaftsspieler === true || mergedMembers[matchedManualIndex].isMannschaftsspieler === true } } else { // Add as new member (from login system) @@ -102,7 +103,8 @@ export default defineEventHandler(async (event) => { loginEmail: user.email, loginRoles: roles, loginRole: roles[0] || 'mitglied', // Rückwärtskompatibilität - lastLogin: user.lastLogin + lastLogin: user.lastLogin, + isMannschaftsspieler: user.isMannschaftsspieler === true }) } } diff --git a/server/api/members/toggle-mannschaftsspieler.post.js b/server/api/members/toggle-mannschaftsspieler.post.js new file mode 100644 index 0000000..adb91e9 --- /dev/null +++ b/server/api/members/toggle-mannschaftsspieler.post.js @@ -0,0 +1,105 @@ +import { verifyToken, getUserById, hasAnyRole, readUsers, writeUsers } from '../../utils/auth.js' +import { readMembers, writeMembers, getMemberById } from '../../utils/members.js' + +export default defineEventHandler(async (event) => { + try { + // Support both Cookie and Authorization Header + let token = getCookie(event, 'auth_token') + + if (!token) { + const authHeader = getHeader(event, 'authorization') + if (authHeader && authHeader.startsWith('Bearer ')) { + token = authHeader.substring(7) + } + } + + if (!token) { + throw createError({ + statusCode: 401, + message: 'Nicht authentifiziert.' + }) + } + + const decoded = verifyToken(token) + + if (!decoded) { + throw createError({ + statusCode: 401, + message: 'Ungültiges Token.' + }) + } + + const user = await getUserById(decoded.id) + + if (!user) { + throw createError({ + statusCode: 401, + message: 'Benutzer nicht gefunden.' + }) + } + + // Only admin and vorstand can toggle this flag + if (!hasAnyRole(user, 'admin', 'vorstand')) { + throw createError({ + statusCode: 403, + message: 'Keine Berechtigung.' + }) + } + + const body = await readBody(event) + const { memberId } = body + + if (!memberId) { + throw createError({ + statusCode: 400, + message: 'Mitglieds-ID ist erforderlich.' + }) + } + + // Prüfe ob es ein Login-System-Mitglied ist (user.id === memberId) + const users = await readUsers() + const loginUser = users.find(u => u.id === memberId) + + if (loginUser) { + // Login-System-Mitglied: Flag in users.json speichern + loginUser.isMannschaftsspieler = !loginUser.isMannschaftsspieler + await writeUsers(users) + + return { + success: true, + message: 'Mannschaftsspieler-Status aktualisiert.', + isMannschaftsspieler: loginUser.isMannschaftsspieler + } + } else { + // Manuelles Mitglied: Flag in members.json speichern + const members = await readMembers() + const member = members.find(m => m.id === memberId) + + if (!member) { + throw createError({ + statusCode: 404, + message: 'Mitglied nicht gefunden.' + }) + } + + member.isMannschaftsspieler = !member.isMannschaftsspieler + await writeMembers(members) + + return { + success: true, + message: 'Mannschaftsspieler-Status aktualisiert.', + isMannschaftsspieler: member.isMannschaftsspieler + } + } + } catch (error) { + console.error('Fehler beim Umschalten des Mannschaftsspieler-Status:', error) + if (error.statusCode) { + throw error + } + throw createError({ + statusCode: error.statusCode || 500, + message: error.message || 'Fehler beim Umschalten des Mannschaftsspieler-Status.' + }) + } +}) +