feat(bisaya-course): expand 'Haus & Familie' lesson with new vocabulary and exercises
All checks were successful
Deploy to production / deploy (push) Successful in 2m52s

- Added comprehensive learning goals, core patterns, grammar focus, speaking prompts, and practical tasks for the 'Haus & Familie' lesson, enhancing the curriculum for better language acquisition.
- Updated exercise content to include multiple-choice questions and gap-fill tasks related to household vocabulary, improving user engagement and learning outcomes.
- Enhanced localization for the lesson description and vocabulary, ensuring clarity and consistency across the learning platform.
This commit is contained in:
Torsten Schulz (local)
2026-04-09 17:19:02 +02:00
parent f5a5639e97
commit 204b7aed04
10 changed files with 354 additions and 54 deletions

View File

@@ -924,6 +924,28 @@
</div>
</div>
</div>
<!-- Kapitel-Prüfung: Mindestziel am Ende nicht erreicht -->
<div v-if="showChapterExamFailedDialog" class="dialog-overlay" @click.self="closeChapterExamFailedDialog">
<div class="dialog" style="width: 440px; height: auto;">
<div class="dialog-header">
<span class="dialog-title">{{ $t('socialnetwork.vocab.courses.exerciseExamFailedTitle') }}</span>
<span class="dialog-close" @click="closeChapterExamFailedDialog"></span>
</div>
<div class="dialog-body">
<p>{{ $t('socialnetwork.vocab.courses.exerciseExamFailedBody', {
score: chapterExamFailedScore,
target: exerciseTargetScore,
count: exerciseRetryUnlockAttempts
}) }}</p>
</div>
<div class="dialog-footer">
<button type="button" class="dialog-button dialog-button--primary" @click="closeChapterExamFailedDialog">
{{ $t('socialnetwork.vocab.courses.exerciseExamFailedOk') }}
</button>
</div>
</div>
</div>
</template>
<script>
@@ -1008,6 +1030,8 @@ export default {
exerciseReinforcementPrepMode: false,
exerciseReinforcementCorrectAnswer: '',
exerciseReinforcementMessage: '',
showChapterExamFailedDialog: false,
chapterExamFailedScore: 0,
/** Index in scrambledChapterExamExercises bei Ein-Frage-Ansicht */
exerciseSequentialIndex: 0,
/** Aus vorherigen Lektionen (MC-Optionen nach Fragentyp Ziel-/Muttersprache) */
@@ -1151,7 +1175,7 @@ export default {
if (!list.length) return false;
const ex = list[this.exerciseSequentialIndex];
if (!ex) return false;
return Boolean(this.exerciseResults[ex.id]?.correct) && this.exerciseSequentialIndex < list.length - 1;
return Boolean(this.exerciseResults[ex.id]) && this.exerciseSequentialIndex < list.length - 1;
},
exerciseRetryUnlockAttempts() {
return Math.min(8, Math.max(2, Math.ceil(this.trainerNewFocusTarget * 0.25)));
@@ -1938,6 +1962,66 @@ export default {
this.exerciseReinforcementCorrectAnswer = '';
this.exerciseReinforcementMessage = '';
},
closeChapterExamFailedDialog() {
this.showChapterExamFailedDialog = false;
},
clearChapterExamAttemptState() {
const all = this.effectiveExercises;
if (!all.length) return;
const results = { ...this.exerciseResults };
const answers = { ...this.exerciseAnswers };
all.forEach((e) => {
delete results[e.id];
delete answers[e.id];
});
this.exerciseResults = results;
this.exerciseAnswers = answers;
this.exerciseSequentialIndex = 0;
this.buildMcRandomizedOptions();
},
handleChapterExamFailed(score) {
this.exerciseRetryPending = true;
this.exerciseRetryPendingSinceAttempts = this.vocabTrainerTotalAttempts;
this.clearChapterExamAttemptState();
this.chapterExamFailedScore = score;
this.showChapterExamFailedDialog = true;
this.activeTab = 'learn';
this.$nextTick(() => {
const scrollEl = document.querySelector('.app-content__scroll.contentscroll');
if (scrollEl) scrollEl.scrollTop = 0;
else window.scrollTo(0, 0);
});
this.persistLessonState();
},
finalizeChapterExamIfComplete() {
const allExercises = this.effectiveExercises;
if (!this.lesson || !allExercises.length) return;
const allAnswered = allExercises.every((exercise) => Boolean(this.exerciseResults[exercise.id]));
if (!allAnswered) return;
const correctExercises = allExercises.filter((exercise) => this.exerciseResults[exercise.id]?.correct).length;
const score = Math.round((correctExercises / allExercises.length) * 100);
const target = this.exerciseTargetScore;
if (score >= target && !this.exerciseNeedsReinforcement) {
void this.checkLessonCompletion();
return;
}
this.handleChapterExamFailed(score);
},
afterChapterExamAnswerSubmitted(exerciseId) {
this.$nextTick(() => {
if (this.sequentialPanelActive) {
const list = this.scrambledChapterExamExercises;
const idx = list.findIndex((e) => e.id === exerciseId);
if (idx >= 0 && idx < list.length - 1 && this.exerciseResults[exerciseId]) {
this.exerciseSequentialIndex = idx + 1;
}
}
this.persistLessonState();
this.finalizeChapterExamIfComplete();
});
},
advancePrepPass() {
if (this.lessonPrepStage >= 2 || this.prepItems.length === 0) {
return;
@@ -2630,28 +2714,15 @@ export default {
this.exerciseReinforcementPrepMode = true;
this.exerciseReinforcementCorrectAnswer = correctText;
this.exerciseReinforcementMessage = this.$t('socialnetwork.vocab.courses.exercisePrepReinforcementHint');
} else {
this.exerciseReinforcementPrepMode = false;
this.exerciseReinforcementCorrectAnswer = correctText;
this.exerciseReinforcementMessage = this.$t('socialnetwork.vocab.courses.exerciseReinforcementHint', {
count: this.exerciseRetryUnlockAttempts
});
this.showExerciseReinforcementDialog = true;
return;
}
this.showExerciseReinforcementDialog = true;
// Kapitel-Prüfung: Lösung inline anzeigen, ohne Sofort-Dialog; nach letzter Frage ggf. Übung + Neustart
this.afterChapterExamAnswerSubmitted(exerciseId);
return;
}
// Nächste Frage im Einzel-Panel / Abschluss prüfen
this.$nextTick(() => {
if (this.sequentialPanelActive) {
const list = this.scrambledChapterExamExercises;
const idx = list.findIndex((e) => e.id === exerciseId);
if (idx >= 0 && idx < list.length - 1) {
this.exerciseSequentialIndex = idx + 1;
}
}
this.checkLessonCompletion();
});
this.afterChapterExamAnswerSubmitted(exerciseId);
} catch (e) {
console.error('Fehler beim Prüfen der Antwort:', e);
this.showErrorDialog = true;