diff --git a/frontend/src/views/social/VocabLessonView.vue b/frontend/src/views/social/VocabLessonView.vue index b57002c..33745c9 100644 --- a/frontend/src/views/social/VocabLessonView.vue +++ b/frontend/src/views/social/VocabLessonView.vue @@ -1296,12 +1296,32 @@ export default { .filter(Boolean); }, prepItems() { - return this.lessonVocab - .map((item) => ({ - target: String(item?.reference || '').trim(), - gloss: String(item?.learning || '').trim() - })) - .filter((item) => item.target); + // Vorbereitung nur mit echten Paaren (Zielsprache + Übersetzung), + // damit weder leere Gloss-Zeilen noch übergroße Listen entstehen. + const out = []; + const seen = new Set(); + const pushUnique = (target, gloss) => { + const t = String(target || '').trim(); + const g = String(gloss || '').trim(); + if (!t || !g) return; + const key = `${this.normalizeLessonVocabTerm(t)}|${this.normalizeLessonVocabTerm(g)}`; + if (seen.has(key)) return; + seen.add(key); + out.push({ target: t, gloss: g }); + }; + + // 1) Didaktisch gepflegte Kernmuster zuerst (höchste Qualität) + this.normalizedCorePatterns.forEach((p) => { + pushUnique(p?.target, p?.gloss); + }); + + // 2) Ergänzung aus extrahierten Übungsvokabeln, aber nur saubere Paare + this.lessonVocab.forEach((item) => { + pushUnique(item?.reference, item?.learning); + }); + + // Begrenzen, damit die Vorbereitungsrunde kompakt bleibt + return out.slice(0, 30); }, currentPrepItem() { return this.prepItems[this.lessonPrepIndex] || null;