diff --git a/frontend/src/views/social/VocabLessonView.vue b/frontend/src/views/social/VocabLessonView.vue
index af5a8ce..64e290a 100644
--- a/frontend/src/views/social/VocabLessonView.vue
+++ b/frontend/src/views/social/VocabLessonView.vue
@@ -228,6 +228,22 @@
{{ $t('socialnetwork.vocab.courses.exerciseLockTitle') }}
{{ exerciseUnlockHint }}
+
+
+ -
+ {{ $t('socialnetwork.vocab.courses.trainerProgressNewContentLabel') || 'Neue Inhalte:' }}
+ {{ exerciseUnlockProgress.currentNew }} / {{ exerciseUnlockProgress.targetNew }}
+
+ -
+ {{ $t('socialnetwork.vocab.courses.totalAttemptsLabel') || 'Trainer-Versuche gesamt:' }}
+ {{ exerciseUnlockProgress.totalAttempts }} / {{ exerciseUnlockProgress.totalTarget }}
+
+ -
+ {{ $t('socialnetwork.vocab.courses.successRateLabel') || 'Erfolgsrate:' }}
+ {{ exerciseUnlockProgress.successRate }}% / {{ exerciseUnlockProgress.requiredRate }}%
+
+
+
@@ -1237,6 +1253,25 @@ export default {
exerciseUnlockMinSuccessPercent() {
return EXERCISE_UNLOCK_MIN_SUCCESS_PERCENT;
},
+ exerciseUnlockProgress() {
+ const currentNew = Math.max(0, Number(this.vocabTrainerCurrentAttempts) || 0);
+ const targetNew = Math.max(0, Number(this.trainerNewFocusTarget) || 0);
+ const totalAttempts = Math.max(0, Number(this.vocabTrainerTotalAttempts) || 0);
+ const totalTarget = Math.max(0, Number(this.trainerExerciseUnlockAttempts) || 0);
+ const successRate = totalAttempts > 0 ? Math.round((Number(this.vocabTrainerCorrect) || 0) / totalAttempts * 100) : 0;
+ const requiredRate = Math.max(0, Number(this.exerciseUnlockMinSuccessPercent) || 0);
+ return {
+ currentNew,
+ targetNew,
+ totalAttempts,
+ totalTarget,
+ successRate,
+ requiredRate,
+ newContentOk: currentNew >= targetNew,
+ totalAttemptsOk: totalAttempts >= totalTarget,
+ successRateOk: successRate >= requiredRate
+ };
+ },
currentReviewShare() {
if (!this.hasPreviousVocab) {
return 0;
@@ -4598,6 +4633,22 @@ export default {
color: var(--color-text-secondary);
}
+.exercise-unlock-conditions ul {
+ list-style: none;
+ padding: 0;
+ margin: 8px 0 0 0;
+}
+.exercise-unlock-conditions li {
+ display: flex;
+ justify-content: space-between;
+ padding: 4px 0;
+ color: var(--color-text-secondary);
+}
+.exercise-unlock-conditions li.ok {
+ color: var(--color-positive, #2a9d2b);
+ font-weight: 600;
+}
+
.language-assistant-panel {
display: grid;
gap: 14px;