diff --git a/frontend/src/apiClient.js b/frontend/src/apiClient.js index ba5551b..e284cf1 100644 --- a/frontend/src/apiClient.js +++ b/frontend/src/apiClient.js @@ -19,4 +19,16 @@ apiClient.interceptors.request.use(config => { return config; }); +// Response-Interceptor für automatische Logout-Behandlung bei 401 +apiClient.interceptors.response.use( + response => response, + error => { + if (error.response && error.response.status === 401) { + // Automatisch ausloggen und zur Login-Seite weiterleiten + store.dispatch('logout'); + } + return Promise.reject(error); + } +); + export default apiClient; diff --git a/frontend/src/store.js b/frontend/src/store.js index e71fabc..6f6c53b 100644 --- a/frontend/src/store.js +++ b/frontend/src/store.js @@ -55,7 +55,7 @@ const store = createStore({ commit('clearToken'); commit('clearUsername'); router.push('/login'); // Leitet den Benutzer zur Login-Seite um - window.location.reload(); // Optional, um den Zustand vollständig zurückzusetzen + // window.location.reload() entfernt, um Endlos-Neuladeschleife zu verhindern }, setCurrentClub({ commit }, club) { diff --git a/frontend/src/views/ScheduleView.vue b/frontend/src/views/ScheduleView.vue index e15b12d..ae039d6 100644 --- a/frontend/src/views/ScheduleView.vue +++ b/frontend/src/views/ScheduleView.vue @@ -107,11 +107,70 @@ export default { alert('Fehler beim Importieren der CSV-Datei'); } }, + // Sortierfunktion für Ligen + sortLeagues(leagues) { + // Ligen-Priorität + const leagueOrder = [ + '1. Bundesliga', + '2. Bundesliga', + '3. Bundesliga', + 'Regionalliga', + 'Oberliga', + 'Verbandsliga (Hessen)', + 'Bezirksoberliga', + 'Bezirksliga', + 'Bezirksklasse', + 'Kreisliga', + '1. Kreisklasse', + '2. Kreisklasse', + '3. Kreisklasse', + ]; + + // Hilfsfunktionen + function getLeagueIndex(name) { + for (let i = 0; i < leagueOrder.length; i++) { + if (name.includes(leagueOrder[i])) return i; + } + return leagueOrder.length; + } + function parseYouth(name) { + // Gibt {type: 'J'|'M'|'Jugend'|null, age: Zahl|null} zurück + const m = name.match(/([JM])(\d{1,2})/i); + if (m) return { type: m[1].toUpperCase(), age: parseInt(m[2]) }; + if (/jugend/i.test(name)) return { type: 'Jugend', age: null }; + return { type: null, age: null }; + } + + // Sortierlogik + return leagues.slice().sort((a, b) => { + const ya = parseYouth(a.name); + const yb = parseYouth(b.name); + // Erwachsene zuerst + if (!ya.type && yb.type) return -1; + if (ya.type && !yb.type) return 1; + if (!ya.type && !yb.type) { + // Beide Erwachsene: nach Liga + return getLeagueIndex(a.name) - getLeagueIndex(b.name); + } + // Beide Jugend: erst nach Alter aufsteigend (älteste unten), dann J vor M vor "Jugend", dann Liga + // "Jugend" ohne Zahl ist die jüngste Jugendklasse + if (ya.age !== yb.age) { + if (ya.age === null) return -1; + if (yb.age === null) return 1; + return ya.age - yb.age; + } + // Reihenfolge: J < M < Jugend + const typeOrder = { 'J': 0, 'M': 1, 'Jugend': 2 }; + if (ya.type !== yb.type) return (typeOrder[ya.type] || 2) - (typeOrder[yb.type] || 2); + return getLeagueIndex(a.name) - getLeagueIndex(b.name); + }); + }, + async loadLeagues() { try { const clubId = this.currentClub; const response = await apiClient.get(`/matches/leagues/current/${clubId}`); - this.leagues = response.data; + this.leagues = this.sortLeagues(response.data); } catch (error) { alert('Fehler beim Laden der Ligen'); }