diff --git a/backend/services/falukantService.js b/backend/services/falukantService.js index f90eaeb..b22069b 100644 --- a/backend/services/falukantService.js +++ b/backend/services/falukantService.js @@ -4409,7 +4409,6 @@ class FalukantService extends BaseService { const characterId = character.id; const ageDays = character.birthdate ? calcAge(character.birthdate) : 0; const canApplyByAge = ageDays >= FalukantService.MIN_AGE_POLITICS_DAYS; - console.log('[getOpenPolitics] characterId=', characterId, 'birthdate=', character.birthdate, 'ageDays=', ageDays, 'MIN=', FalukantService.MIN_AGE_POLITICS_DAYS, 'canApplyByAge=', canApplyByAge); const rows = await sequelize.query( FalukantService.RECURSIVE_REGION_SEARCH, { @@ -4485,7 +4484,6 @@ class FalukantService extends BaseService { }; }) .filter(election => !election.alreadyApplied); // Nur Positionen ohne bestehende Bewerbung - console.log('[getOpenPolitics] returning', result.length, 'entries, canApplyByAge on first:', result[0]?.canApplyByAge); return result; } @@ -4502,9 +4500,7 @@ class FalukantService extends BaseService { // 2) Mindestalter 16 (Spieljahre = 16 Tage Realzeit) const ageDays = character.birthdate ? calcAge(character.birthdate) : 0; - console.log('[applyForElections] characterId=', character.id, 'birthdate=', character.birthdate, 'ageDays=', ageDays, 'MIN=', FalukantService.MIN_AGE_POLITICS_DAYS); if (ageDays < FalukantService.MIN_AGE_POLITICS_DAYS) { - console.log('[applyForElections] rejected: too_young'); throw new Error('too_young'); } diff --git a/frontend/src/i18n/locales/de/falukant.json b/frontend/src/i18n/locales/de/falukant.json index 4ae1639..db0eda4 100644 --- a/frontend/src/i18n/locales/de/falukant.json +++ b/frontend/src/i18n/locales/de/falukant.json @@ -1029,9 +1029,11 @@ "region": "Region", "date": "Datum", "candidacy": "Kandidatur", + "candidacyWithAge": "Kandidatur (ab 16 Jahren)", "none": "Keine offenen Positionen.", "apply": "Für ausgewählte Positionen kandidieren", - "minAgeHint": "Kandidatur erst ab 16 Jahren möglich." + "minAgeHint": "Kandidatur erst ab 16 Jahren möglich.", + "ageRequirement": "Für alle politischen Ämter gilt: Kandidatur erst ab 16 Jahren." }, "too_young": "Dein Charakter ist noch zu jung. Eine Bewerbung ist erst ab 16 Jahren möglich.", "upcoming": { diff --git a/frontend/src/i18n/locales/en/falukant.json b/frontend/src/i18n/locales/en/falukant.json index cde5ff4..14a6d19 100644 --- a/frontend/src/i18n/locales/en/falukant.json +++ b/frontend/src/i18n/locales/en/falukant.json @@ -363,9 +363,11 @@ "region": "Region", "date": "Date", "candidacy": "Candidacy", + "candidacyWithAge": "Candidacy (from age 16)", "none": "No open positions.", "apply": "Apply for selected positions", - "minAgeHint": "Candidacy is only possible from age 16." + "minAgeHint": "Candidacy is only possible from age 16.", + "ageRequirement": "All political offices require candidates to be at least 16 years old." }, "too_young": "Your character is too young. Applications are only possible from age 16.", "upcoming": { diff --git a/frontend/src/views/falukant/EducationView.vue b/frontend/src/views/falukant/EducationView.vue index 03814b3..83e26b6 100644 --- a/frontend/src/views/falukant/EducationView.vue +++ b/frontend/src/views/falukant/EducationView.vue @@ -18,14 +18,14 @@ {{ $t(`falukant.product.${product.labelTr}`) }} - {{ product.knowledges[0].knowledge }} % + {{ product.knowledges?.[0]?.knowledge ?? 0 }} % @@ -171,11 +171,23 @@ export default { activeChild: null, } }, + watch: { + activeTab: { + async handler(tab) { + if (tab === 'director' && this.directors.length === 0) { + await this.loadDirectors(); + } + if (tab === 'children' && this.children.length === 0) { + await this.loadChildren(); + } + } + } + }, async mounted() { await this.loadProducts(); await this.loadEducations(); - await this.loadDirectors(); await this.loadChildren(); + if (this.activeTab === 'director') await this.loadDirectors(); }, methods: { // Basis-Funktion: lineare Interpolation @@ -193,7 +205,8 @@ export default { return this.computeCost(knowledge, 'one'); }, getSelfAllCost() { - const avg = this.products.reduce((sum, p) => sum + (p.knowledges[0].knowledge||0), 0) / this.products.length; + if (!this.products?.length) return 0; + const avg = this.products.reduce((sum, p) => sum + (p.knowledges?.[0]?.knowledge || 0), 0) / this.products.length; return this.computeCost(avg, 'all'); }, @@ -209,12 +222,14 @@ export default { }, getChildrenAllCost(childId) { const child = this.children.find(c => c.id === childId); - const avg = (child.knowledge || []).reduce((s,k) => s + k.knowledge, 0) / (child.knowledge?.length||1); + if (!child || !Array.isArray(child.knowledge)) return 0; + const avg = child.knowledge.reduce((s, k) => s + (k.knowledge || 0), 0) / (child.knowledge.length || 1); return this.computeCost(avg, 'all'); }, childNotInLearning() { const child = this.children.find(c => c.id === this.activeChild); - return !this.childrenRunningEducations.some(e => e.learningCharacter.id === child.id); + if (!child) return true; + return !this.childrenRunningEducations.some(e => e.learningCharacter?.id === child.id); }, // DIRECTOR diff --git a/frontend/src/views/falukant/PoliticsView.vue b/frontend/src/views/falukant/PoliticsView.vue index 1f8b6bb..e767a6d 100644 --- a/frontend/src/views/falukant/PoliticsView.vue +++ b/frontend/src/views/falukant/PoliticsView.vue @@ -57,6 +57,7 @@
+

{{ $t('falukant.politics.open.ageRequirement') }}

{{ $t('loading') }}
@@ -65,7 +66,7 @@ - + @@ -247,10 +248,6 @@ export default { try { const { data } = await apiClient.get('/api/falukant/politics/open'); this.openPolitics = Array.isArray(data) ? data : []; - // Debug: Alters-Flag prüfen - if (this.openPolitics.length > 0) { - console.log('[PoliticsView] loadOpenPolitics: count=', this.openPolitics.length, 'first.canApplyByAge=', this.openPolitics[0].canApplyByAge, 'first.id=', this.openPolitics[0].id); - } // Bereits beworbene Positionen vorselektieren, damit die Checkbox // sichtbar markiert bleibt. this.selectedApplications = this.openPolitics @@ -435,6 +432,13 @@ h2 { overflow: hidden; } +.politics-age-requirement { + flex: 0 0 auto; + margin: 0 0 10px 0; + font-size: 0.95em; + color: #555; +} + .table-scroll { flex: 1; overflow-y: auto;
{{ $t('falukant.politics.open.office') }} {{ $t('falukant.politics.open.region') }} {{ $t('falukant.politics.open.date') }}{{ $t('falukant.politics.open.candidacy') }}{{ $t('falukant.politics.open.candidacyWithAge') }}