diff --git a/frontend/src/components/SeasonSelector.vue b/frontend/src/components/SeasonSelector.vue index e4f76fb1..6faaa2ba 100644 --- a/frontend/src/components/SeasonSelector.vue +++ b/frontend/src/components/SeasonSelector.vue @@ -124,6 +124,42 @@ export default { }); // Methods + const getRunningSeasonId = (seasonEntries) => { + const seasonsList = Array.isArray(seasonEntries) ? seasonEntries : []; + if (!seasonsList.length) return null; + + const now = new Date(); + const currentYear = now.getFullYear(); + // Saisonlogik in der App: Hinrunde Juli-Dez, Rueckrunde Jan-Jun + const startYear = now.getMonth() >= 6 ? currentYear : currentYear - 1; + const endYear = startYear + 1; + const expectedLabel = `${startYear}/${endYear}`; + + const exact = seasonsList.find((entry) => String(entry?.season || '').trim() === expectedLabel); + if (exact?.id != null) { + return exact.id; + } + + // Fallback: numerisch passend, falls Label leicht abweicht + const parsed = seasonsList + .map((entry) => { + const match = String(entry?.season || '').match(/^(\d{4})\/(\d{4})$/); + if (!match) return null; + return { + id: entry.id, + start: Number(match[1]), + end: Number(match[2]) + }; + }) + .filter(Boolean); + const numericMatch = parsed.find((entry) => entry.start === startYear && entry.end === endYear); + if (numericMatch?.id != null) { + return numericMatch.id; + } + + return null; + }; + const loadSeasons = async () => { loading.value = true; error.value = null; @@ -132,12 +168,14 @@ export default { const response = await apiClient.get('/seasons'); seasons.value = response.data; - // Wenn showCurrentSeason true ist und keine Saison ausgewählt, wähle die aktuelle + // Wenn showCurrentSeason true ist und keine Saison ausgewählt, wähle die laufende Saison if (props.showCurrentSeason && !selectedSeasonId.value && seasons.value.length > 0) { - // Die erste Saison ist die neueste (sortiert nach DESC) - selectedSeasonId.value = seasons.value[0].id; + const runningSeasonId = getRunningSeasonId(seasons.value); + const fallbackSeason = seasons.value[0]; + selectedSeasonId.value = runningSeasonId ?? fallbackSeason.id; + const selectedSeason = seasons.value.find((entry) => entry.id == selectedSeasonId.value) || fallbackSeason; emit('update:modelValue', selectedSeasonId.value); - emit('season-change', seasons.value[0]); + emit('season-change', selectedSeason); } } catch (err) { console.error('Fehler beim Laden der Saisons:', err); diff --git a/frontend/src/i18n/locales/de-CH.json b/frontend/src/i18n/locales/de-CH.json index e456d360..af04507e 100644 --- a/frontend/src/i18n/locales/de-CH.json +++ b/frontend/src/i18n/locales/de-CH.json @@ -577,6 +577,7 @@ "scopeAll": "Alle", "scopeActive": "Aktiv", "scopeTest": "Probe", + "scopeActiveTest": "Aktiv + Probe", "scopeNeedsForm": "Formular ungeprüft", "scopeActiveDataIncomplete": "Aktiv + Daten unvollständig", "scopeDataIncomplete": "Daten unvollständig", diff --git a/frontend/src/i18n/locales/de-extended.json b/frontend/src/i18n/locales/de-extended.json index 5897b76e..1355676a 100644 --- a/frontend/src/i18n/locales/de-extended.json +++ b/frontend/src/i18n/locales/de-extended.json @@ -216,6 +216,7 @@ "scopeAll": "Alle", "scopeActive": "Aktiv", "scopeTest": "Probe", + "scopeActiveTest": "Aktiv + Probe", "scopeNeedsForm": "Formular ungeprüft", "scopeInactive": "Inaktiv", "resultsVisible": "Mitglieder sichtbar", diff --git a/frontend/src/i18n/locales/de.json b/frontend/src/i18n/locales/de.json index 273d36ed..19d1f5e6 100644 --- a/frontend/src/i18n/locales/de.json +++ b/frontend/src/i18n/locales/de.json @@ -325,6 +325,7 @@ "scopeAll": "Alle", "scopeActive": "Aktiv", "scopeTest": "Probe", + "scopeActiveTest": "Aktiv + Probe", "scopeNeedsForm": "Formular ungeprüft", "scopeActiveDataIncomplete": "Aktiv + Daten unvollständig", "scopeDataIncomplete": "Daten unvollständig", diff --git a/frontend/src/i18n/locales/en-AU.json b/frontend/src/i18n/locales/en-AU.json index 06128058..ffef64e6 100644 --- a/frontend/src/i18n/locales/en-AU.json +++ b/frontend/src/i18n/locales/en-AU.json @@ -574,6 +574,7 @@ "scopeAll": "All", "scopeActive": "Active", "scopeTest": "Trial", + "scopeActiveTest": "Active + trial", "scopeNeedsForm": "Form unverified", "scopeDataIncomplete": "Data incomplete", "scopeInactive": "Inactive", diff --git a/frontend/src/i18n/locales/en-GB.json b/frontend/src/i18n/locales/en-GB.json index 854f6e26..0ab43dc9 100644 --- a/frontend/src/i18n/locales/en-GB.json +++ b/frontend/src/i18n/locales/en-GB.json @@ -849,6 +849,7 @@ "scopeAll": "All", "scopeActive": "Active", "scopeTest": "Trial", + "scopeActiveTest": "Active + trial", "scopeNeedsForm": "Form unverified", "scopeDataIncomplete": "Data incomplete", "scopeInactive": "Inactive", diff --git a/frontend/src/i18n/locales/en-US.json b/frontend/src/i18n/locales/en-US.json index 812887e2..a4e27c2f 100644 --- a/frontend/src/i18n/locales/en-US.json +++ b/frontend/src/i18n/locales/en-US.json @@ -574,6 +574,7 @@ "scopeAll": "All", "scopeActive": "Active", "scopeTest": "Trial", + "scopeActiveTest": "Active + trial", "scopeNeedsForm": "Form unverified", "scopeDataIncomplete": "Data incomplete", "scopeInactive": "Inactive", diff --git a/frontend/src/i18n/locales/es.json b/frontend/src/i18n/locales/es.json index 48bb64c3..76a304cf 100644 --- a/frontend/src/i18n/locales/es.json +++ b/frontend/src/i18n/locales/es.json @@ -537,6 +537,7 @@ "scopeAll": "Todos", "scopeActive": "Activos", "scopeTest": "Prueba", + "scopeActiveTest": "Activo + prueba", "scopeNeedsForm": "Formulario sin verificar", "scopeDataIncomplete": "Datos incompletos", "scopeInactive": "Inactivos", diff --git a/frontend/src/i18n/locales/fil.json b/frontend/src/i18n/locales/fil.json index 7cb7e0c1..91fe076f 100644 --- a/frontend/src/i18n/locales/fil.json +++ b/frontend/src/i18n/locales/fil.json @@ -537,6 +537,7 @@ "scopeAll": "All", "scopeActive": "Active", "scopeTest": "Trial", + "scopeActiveTest": "Active + trial", "scopeNeedsForm": "Form unverified", "scopeActiveDataIncomplete": "Aktibo + hindi kumpleto ang datos", "scopeDataIncomplete": "Hindi kumpleto ang datos", diff --git a/frontend/src/i18n/locales/fr.json b/frontend/src/i18n/locales/fr.json index bc742a79..5b8c81b4 100644 --- a/frontend/src/i18n/locales/fr.json +++ b/frontend/src/i18n/locales/fr.json @@ -537,6 +537,7 @@ "scopeAll": "Tous", "scopeActive": "Actifs", "scopeTest": "Essai", + "scopeActiveTest": "Actif + essai", "scopeNeedsForm": "Formulaire non vérifié", "scopeDataIncomplete": "Données incomplètes", "scopeInactive": "Inactifs", diff --git a/frontend/src/i18n/locales/it.json b/frontend/src/i18n/locales/it.json index f19c5c70..6f0afa1b 100644 --- a/frontend/src/i18n/locales/it.json +++ b/frontend/src/i18n/locales/it.json @@ -537,6 +537,7 @@ "scopeAll": "Tutti", "scopeActive": "Attivi", "scopeTest": "Prova", + "scopeActiveTest": "Attivo + prova", "scopeNeedsForm": "Modulo non verificato", "scopeDataIncomplete": "Dati incompleti", "scopeInactive": "Inattivi", diff --git a/frontend/src/i18n/locales/ja.json b/frontend/src/i18n/locales/ja.json index 472ba41a..e7eb60e9 100644 --- a/frontend/src/i18n/locales/ja.json +++ b/frontend/src/i18n/locales/ja.json @@ -537,6 +537,7 @@ "scopeAll": "All", "scopeActive": "Active", "scopeTest": "Trial", + "scopeActiveTest": "Active + trial", "scopeNeedsForm": "Form unverified", "scopeActiveDataIncomplete": "アクティブ + データ不完全", "scopeDataIncomplete": "データ不完全", diff --git a/frontend/src/i18n/locales/pl.json b/frontend/src/i18n/locales/pl.json index ad70d1ad..c62d3368 100644 --- a/frontend/src/i18n/locales/pl.json +++ b/frontend/src/i18n/locales/pl.json @@ -537,6 +537,7 @@ "scopeAll": "Wszyscy", "scopeActive": "Aktywni", "scopeTest": "Próba", + "scopeActiveTest": "Aktywni + próba", "scopeNeedsForm": "Formularz niezweryfikowany", "scopeDataIncomplete": "Niepełne dane", "scopeInactive": "Nieaktywni", diff --git a/frontend/src/i18n/locales/th.json b/frontend/src/i18n/locales/th.json index a0ec3164..56d5f42f 100644 --- a/frontend/src/i18n/locales/th.json +++ b/frontend/src/i18n/locales/th.json @@ -537,6 +537,7 @@ "scopeAll": "All", "scopeActive": "Active", "scopeTest": "Trial", + "scopeActiveTest": "Active + trial", "scopeNeedsForm": "Form unverified", "scopeActiveDataIncomplete": "ใช้งานอยู่ + ข้อมูลไม่ครบ", "scopeDataIncomplete": "ข้อมูลไม่ครบ", diff --git a/frontend/src/i18n/locales/tl.json b/frontend/src/i18n/locales/tl.json index 7bcba17d..51a9f6a6 100644 --- a/frontend/src/i18n/locales/tl.json +++ b/frontend/src/i18n/locales/tl.json @@ -537,6 +537,7 @@ "scopeAll": "All", "scopeActive": "Active", "scopeTest": "Trial", + "scopeActiveTest": "Active + trial", "scopeNeedsForm": "Form unverified", "scopeActiveDataIncomplete": "Aktibo + hindi kumpleto ang datos", "scopeDataIncomplete": "Hindi kumpleto ang datos", diff --git a/frontend/src/i18n/locales/zh.json b/frontend/src/i18n/locales/zh.json index 233642b4..242cfda1 100644 --- a/frontend/src/i18n/locales/zh.json +++ b/frontend/src/i18n/locales/zh.json @@ -537,6 +537,7 @@ "scopeAll": "All", "scopeActive": "Active", "scopeTest": "Trial", + "scopeActiveTest": "Active + trial", "scopeNeedsForm": "Form unverified", "scopeActiveDataIncomplete": "活跃 + 数据不完整", "scopeDataIncomplete": "数据不完整", diff --git a/frontend/src/views/MembersView.vue b/frontend/src/views/MembersView.vue index 2f725702..b6de2d10 100644 --- a/frontend/src/views/MembersView.vue +++ b/frontend/src/views/MembersView.vue @@ -689,6 +689,10 @@ export default { return false; } + if (this.selectedMemberScope === 'activeTest' && (!member.active || !member.testMembership)) { + return false; + } + if (this.selectedMemberScope === 'inactive' && member.active) { return false; } @@ -786,6 +790,7 @@ export default { { value: 'all', label: this.$t('members.scopeAll'), count: this.members.length }, { value: 'active', label: this.$t('members.scopeActive'), count: this.members.filter(member => member.active && !member.testMembership).length }, { value: 'test', label: this.$t('members.scopeTest'), count: this.members.filter(member => member.testMembership).length }, + { value: 'activeTest', label: this.$t('members.scopeActiveTest'), count: this.members.filter(member => member.active && member.testMembership).length }, { value: 'notTraining', label: this.$t('members.scopeNotTraining'), count: this.members.filter(member => member.notInTraining).length }, { value: 'needsForm', label: this.$t('members.scopeNeedsForm'), count: this.members.filter(member => !member.memberFormHandedOver).length }, { value: 'activeDataIncomplete', label: this.$t('members.scopeActiveDataIncomplete'), count: this.members.filter(member => member.active && !member.testMembership && this.getMemberDataQualityIssues(member).length > 0).length },