Enhance VocabLessonView with new vocabulary trainer features and improved statistics
- Added functionality for tracking total attempts and success rates in the vocabulary trainer, enhancing user feedback on performance. - Introduced multiple choice and typing modes for vocabulary practice, allowing users to switch between different learning styles. - Updated translations in both English and German to include new vocabulary terms and exercise instructions, ensuring consistency across languages. - Improved UI layout for displaying vocabulary statistics and answer options, enhancing overall user experience.
This commit is contained in:
@@ -64,9 +64,23 @@
|
||||
</div>
|
||||
<div v-else class="vocab-trainer-active">
|
||||
<div class="vocab-trainer-stats">
|
||||
<span>{{ $t('socialnetwork.vocab.courses.correct') }}: {{ vocabTrainerCorrect }}</span>
|
||||
<span>{{ $t('socialnetwork.vocab.courses.wrong') }}: {{ vocabTrainerWrong }}</span>
|
||||
<button @click="stopVocabTrainer" class="btn-stop-trainer">{{ $t('socialnetwork.vocab.courses.stopTrainer') }}</button>
|
||||
<div class="stats-row">
|
||||
<span>{{ $t('socialnetwork.vocab.courses.correct') }}: {{ vocabTrainerCorrect }}</span>
|
||||
<span>{{ $t('socialnetwork.vocab.courses.wrong') }}: {{ vocabTrainerWrong }}</span>
|
||||
<span>{{ $t('socialnetwork.vocab.courses.totalAttempts') }}: {{ vocabTrainerTotalAttempts }}</span>
|
||||
<span v-if="vocabTrainerTotalAttempts > 0" class="success-rate">
|
||||
{{ $t('socialnetwork.vocab.courses.successRate') }}: {{ Math.round((vocabTrainerCorrect / vocabTrainerTotalAttempts) * 100) }}%
|
||||
</span>
|
||||
</div>
|
||||
<div class="stats-row">
|
||||
<span class="mode-badge" :class="{ 'mode-active': vocabTrainerMode === 'multiple_choice', 'mode-completed': vocabTrainerMode === 'typing' }">
|
||||
{{ $t('socialnetwork.vocab.courses.modeMultipleChoice') }}
|
||||
</span>
|
||||
<span class="mode-badge" :class="{ 'mode-active': vocabTrainerMode === 'typing' }">
|
||||
{{ $t('socialnetwork.vocab.courses.modeTyping') }}
|
||||
</span>
|
||||
<button @click="stopVocabTrainer" class="btn-stop-trainer">{{ $t('socialnetwork.vocab.courses.stopTrainer') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="currentVocabQuestion" class="vocab-question">
|
||||
<div class="vocab-prompt">
|
||||
@@ -79,7 +93,25 @@
|
||||
{{ $t('socialnetwork.vocab.courses.wrong') }}. {{ $t('socialnetwork.vocab.courses.correctAnswer') }}: {{ currentVocabQuestion.answer }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="vocab-answer-area">
|
||||
<!-- Multiple Choice Modus -->
|
||||
<div v-else-if="vocabTrainerMode === 'multiple_choice'" class="vocab-answer-area multiple-choice">
|
||||
<div class="choice-buttons">
|
||||
<button
|
||||
v-for="(option, index) in vocabTrainerChoiceOptions"
|
||||
:key="index"
|
||||
@click="selectVocabChoice(option)"
|
||||
class="choice-button"
|
||||
:class="{ selected: vocabTrainerSelectedChoice === option }"
|
||||
>
|
||||
{{ option }}
|
||||
</button>
|
||||
</div>
|
||||
<button @click="checkVocabAnswer" :disabled="!vocabTrainerSelectedChoice" class="btn-check">
|
||||
{{ $t('socialnetwork.vocab.courses.checkAnswer') }}
|
||||
</button>
|
||||
</div>
|
||||
<!-- Texteingabe Modus -->
|
||||
<div v-else class="vocab-answer-area typing">
|
||||
<input
|
||||
v-model="vocabTrainerAnswer"
|
||||
@keydown.enter.prevent="checkVocabAnswer"
|
||||
@@ -87,11 +119,12 @@
|
||||
class="vocab-input"
|
||||
ref="vocabInput"
|
||||
/>
|
||||
<button @click="checkVocabAnswer" :disabled="!vocabTrainerAnswer.trim()">
|
||||
<button @click="checkVocabAnswer" :disabled="!vocabTrainerAnswer.trim()" class="btn-check">
|
||||
{{ $t('socialnetwork.vocab.courses.checkAnswer') }}
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="vocabTrainerAnswered" class="vocab-next">
|
||||
<!-- "Weiter"-Button nur im Multiple Choice Modus oder bei falscher Antwort im Typing Modus -->
|
||||
<div v-if="vocabTrainerAnswered && (vocabTrainerMode === 'multiple_choice' || !vocabTrainerLastCorrect)" class="vocab-next">
|
||||
<button @click="nextVocabQuestion">{{ $t('socialnetwork.vocab.courses.next') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -252,10 +285,15 @@ export default {
|
||||
// Vokabeltrainer
|
||||
vocabTrainerActive: false,
|
||||
vocabTrainerPool: [],
|
||||
vocabTrainerMode: 'multiple_choice', // 'multiple_choice' oder 'typing'
|
||||
vocabTrainerCorrect: 0,
|
||||
vocabTrainerWrong: 0,
|
||||
vocabTrainerTotalAttempts: 0,
|
||||
vocabTrainerStats: {}, // { [vocabKey]: { attempts: 0, correct: 0, wrong: 0 } }
|
||||
vocabTrainerChoiceOptions: [],
|
||||
currentVocabQuestion: null,
|
||||
vocabTrainerAnswer: '',
|
||||
vocabTrainerSelectedChoice: null,
|
||||
vocabTrainerAnswered: false,
|
||||
vocabTrainerLastCorrect: false,
|
||||
vocabTrainerDirection: 'L2R' // L2R: learning->reference, R2L: reference->learning
|
||||
@@ -299,17 +337,22 @@ export default {
|
||||
// Extrahiere wichtige Begriffe aus den Übungen
|
||||
try {
|
||||
if (!this.lesson || !this.lesson.grammarExercises || !Array.isArray(this.lesson.grammarExercises)) {
|
||||
console.log('[importantVocab] Keine Übungen vorhanden');
|
||||
return [];
|
||||
}
|
||||
|
||||
const vocabMap = new Map();
|
||||
|
||||
this.lesson.grammarExercises.forEach(exercise => {
|
||||
this.lesson.grammarExercises.forEach((exercise, idx) => {
|
||||
try {
|
||||
console.log(`[importantVocab] Verarbeite Übung ${idx + 1}:`, exercise.title);
|
||||
// Extrahiere aus questionData
|
||||
const qData = this.getQuestionData(exercise);
|
||||
const aData = this.getAnswerData(exercise);
|
||||
|
||||
console.log(`[importantVocab] qData:`, qData);
|
||||
console.log(`[importantVocab] aData:`, aData);
|
||||
|
||||
if (qData && aData) {
|
||||
// Für Multiple Choice: Extrahiere Optionen und richtige Antwort
|
||||
if (this.getExerciseType(exercise) === 'multiple_choice') {
|
||||
@@ -317,22 +360,28 @@ export default {
|
||||
const correctIndex = aData.correctAnswer !== undefined ? aData.correctAnswer : (aData.correct || 0);
|
||||
const correctAnswer = options[correctIndex] || '';
|
||||
|
||||
console.log(`[importantVocab] Multiple Choice - options:`, options, `correctIndex:`, correctIndex, `correctAnswer:`, correctAnswer);
|
||||
|
||||
if (correctAnswer) {
|
||||
// Versuche die Frage zu analysieren (z.B. "Wie sagt man 'X' auf Bisaya?" oder "Was bedeutet 'X'?")
|
||||
const question = qData.question || qData.text || '';
|
||||
console.log(`[importantVocab] Frage:`, question);
|
||||
|
||||
// Pattern 1: "Wie sagt man 'X' auf Bisaya?" -> X ist Deutsch, correctAnswer ist Bisaya
|
||||
let match = question.match(/['"]([^'"]+)['"]/);
|
||||
if (match) {
|
||||
const germanWord = match[1];
|
||||
console.log(`[importantVocab] Pattern 1 gefunden - Bisaya:`, correctAnswer, `Deutsch:`, germanWord);
|
||||
vocabMap.set(correctAnswer, { learning: correctAnswer, reference: germanWord });
|
||||
} else {
|
||||
// Pattern 2: "Was bedeutet 'X'?" -> X ist Bisaya, correctAnswer ist Deutsch
|
||||
match = question.match(/Was bedeutet ['"]([^'"]+)['"]/);
|
||||
if (match) {
|
||||
const bisayaWord = match[1];
|
||||
console.log(`[importantVocab] Pattern 2 gefunden - Bisaya:`, bisayaWord, `Deutsch:`, correctAnswer);
|
||||
vocabMap.set(bisayaWord, { learning: bisayaWord, reference: correctAnswer });
|
||||
} else {
|
||||
console.log(`[importantVocab] Kein Pattern gefunden, Fallback`);
|
||||
// Fallback: Verwende die richtige Antwort als Lernwort
|
||||
vocabMap.set(correctAnswer, { learning: correctAnswer, reference: correctAnswer });
|
||||
}
|
||||
@@ -343,6 +392,7 @@ export default {
|
||||
// Für Gap Fill: Extrahiere richtige Antworten
|
||||
if (this.getExerciseType(exercise) === 'gap_fill') {
|
||||
const answers = aData.answers || (aData.correct ? (Array.isArray(aData.correct) ? aData.correct : [aData.correct]) : []);
|
||||
console.log(`[importantVocab] Gap Fill - answers:`, answers);
|
||||
if (answers.length > 0) {
|
||||
// Versuche aus dem Text Kontext zu extrahieren
|
||||
const text = qData.text || '';
|
||||
@@ -361,7 +411,9 @@ export default {
|
||||
}
|
||||
});
|
||||
|
||||
return Array.from(vocabMap.values());
|
||||
const result = Array.from(vocabMap.values());
|
||||
console.log(`[importantVocab] Ergebnis:`, result);
|
||||
return result;
|
||||
} catch (e) {
|
||||
console.error('Fehler in importantVocab computed property:', e);
|
||||
return [];
|
||||
@@ -522,11 +574,72 @@ export default {
|
||||
|
||||
const res = await apiClient.post(`/api/vocab/grammar-exercises/${exerciseId}/check`, { answer });
|
||||
this.exerciseResults[exerciseId] = res.data;
|
||||
|
||||
// Prüfe ob alle Übungen bestanden sind
|
||||
await this.checkLessonCompletion();
|
||||
} catch (e) {
|
||||
console.error('Fehler beim Prüfen der Antwort:', e);
|
||||
alert(e.response?.data?.error || 'Fehler beim Prüfen der Antwort');
|
||||
}
|
||||
},
|
||||
async checkLessonCompletion() {
|
||||
// Prüfe ob alle Übungen korrekt beantwortet wurden
|
||||
if (!this.lesson || !this.lesson.grammarExercises) return;
|
||||
|
||||
const allExercises = this.lesson.grammarExercises;
|
||||
const allCompleted = allExercises.every(exercise => {
|
||||
const result = this.exerciseResults[exercise.id];
|
||||
return result && result.correct;
|
||||
});
|
||||
|
||||
if (allCompleted) {
|
||||
// Berechne Gesamt-Score
|
||||
const totalExercises = allExercises.length;
|
||||
const correctExercises = allExercises.filter(ex => this.exerciseResults[ex.id]?.correct).length;
|
||||
const score = Math.round((correctExercises / totalExercises) * 100);
|
||||
|
||||
// Aktualisiere Fortschritt
|
||||
try {
|
||||
await apiClient.put(`/api/vocab/lessons/${this.lessonId}/progress`, {
|
||||
completed: true,
|
||||
score: score,
|
||||
timeSpentMinutes: 0 // TODO: Zeit tracken
|
||||
});
|
||||
|
||||
// Weiterleitung zur nächsten Lektion
|
||||
await this.navigateToNextLesson();
|
||||
} catch (e) {
|
||||
console.error('Fehler beim Aktualisieren des Fortschritts:', e);
|
||||
}
|
||||
}
|
||||
},
|
||||
async navigateToNextLesson() {
|
||||
try {
|
||||
// Lade Kurs mit allen Lektionen
|
||||
const courseRes = await apiClient.get(`/api/vocab/courses/${this.courseId}`);
|
||||
const course = courseRes.data;
|
||||
|
||||
if (!course.lessons || course.lessons.length === 0) return;
|
||||
|
||||
// Finde aktuelle Lektion
|
||||
const currentLessonIndex = course.lessons.findIndex(l => l.id === parseInt(this.lessonId));
|
||||
|
||||
if (currentLessonIndex >= 0 && currentLessonIndex < course.lessons.length - 1) {
|
||||
// Nächste Lektion gefunden
|
||||
const nextLesson = course.lessons[currentLessonIndex + 1];
|
||||
|
||||
// Zeige Erfolgs-Meldung und leite weiter
|
||||
if (confirm(this.$t('socialnetwork.vocab.courses.lessonCompleted') + '\n' + this.$t('socialnetwork.vocab.courses.goToNextLesson'))) {
|
||||
this.$router.push(`/socialnetwork/vocab/courses/${this.courseId}/lessons/${nextLesson.id}`);
|
||||
}
|
||||
} else {
|
||||
// Letzte Lektion - zeige Abschluss-Meldung
|
||||
alert(this.$t('socialnetwork.vocab.courses.allLessonsCompleted'));
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Fehler beim Laden der nächsten Lektion:', e);
|
||||
}
|
||||
},
|
||||
back() {
|
||||
this.$router.push(`/socialnetwork/vocab/courses/${this.courseId}`);
|
||||
},
|
||||
@@ -535,52 +648,149 @@ export default {
|
||||
if (!this.importantVocab || this.importantVocab.length === 0) return;
|
||||
this.vocabTrainerActive = true;
|
||||
this.vocabTrainerPool = [...this.importantVocab];
|
||||
this.vocabTrainerMode = 'multiple_choice';
|
||||
this.vocabTrainerCorrect = 0;
|
||||
this.vocabTrainerWrong = 0;
|
||||
this.vocabTrainerTotalAttempts = 0;
|
||||
this.vocabTrainerStats = {};
|
||||
this.nextVocabQuestion();
|
||||
this.$nextTick(() => {
|
||||
this.$refs.vocabInput?.focus?.();
|
||||
});
|
||||
},
|
||||
stopVocabTrainer() {
|
||||
this.vocabTrainerActive = false;
|
||||
this.currentVocabQuestion = null;
|
||||
this.vocabTrainerAnswer = '';
|
||||
this.vocabTrainerSelectedChoice = null;
|
||||
this.vocabTrainerAnswered = false;
|
||||
},
|
||||
getVocabKey(vocab) {
|
||||
return `${vocab.learning}|${vocab.reference}`;
|
||||
},
|
||||
getVocabStats(vocab) {
|
||||
const key = this.getVocabKey(vocab);
|
||||
if (!this.vocabTrainerStats[key]) {
|
||||
this.vocabTrainerStats[key] = { attempts: 0, correct: 0, wrong: 0 };
|
||||
}
|
||||
return this.vocabTrainerStats[key];
|
||||
},
|
||||
checkVocabModeSwitch() {
|
||||
// Wechsle zu Texteingabe wenn 80% erreicht und mindestens 20 Versuche
|
||||
if (this.vocabTrainerMode === 'multiple_choice' && this.vocabTrainerTotalAttempts >= 20) {
|
||||
const successRate = (this.vocabTrainerCorrect / this.vocabTrainerTotalAttempts) * 100;
|
||||
if (successRate >= 80) {
|
||||
this.vocabTrainerMode = 'typing';
|
||||
// Reset Stats für Texteingabe-Modus
|
||||
this.vocabTrainerCorrect = 0;
|
||||
this.vocabTrainerWrong = 0;
|
||||
this.vocabTrainerTotalAttempts = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
buildChoiceOptions(correctAnswer, allVocabs) {
|
||||
const options = new Set([correctAnswer]);
|
||||
// Füge 3 Distraktoren hinzu
|
||||
while (options.size < 4 && allVocabs.length > 1) {
|
||||
const randomVocab = allVocabs[Math.floor(Math.random() * allVocabs.length)];
|
||||
const distractor = this.vocabTrainerDirection === 'L2R' ? randomVocab.reference : randomVocab.learning;
|
||||
if (distractor !== correctAnswer) {
|
||||
options.add(distractor);
|
||||
}
|
||||
}
|
||||
// Shuffle
|
||||
const arr = Array.from(options);
|
||||
for (let i = arr.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[arr[i], arr[j]] = [arr[j], arr[i]];
|
||||
}
|
||||
return arr;
|
||||
},
|
||||
nextVocabQuestion() {
|
||||
if (!this.vocabTrainerPool || this.vocabTrainerPool.length === 0) {
|
||||
this.currentVocabQuestion = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Prüfe ob Modus-Wechsel nötig ist
|
||||
this.checkVocabModeSwitch();
|
||||
|
||||
// Wähle zufällige Vokabel
|
||||
const randomIndex = Math.floor(Math.random() * this.vocabTrainerPool.length);
|
||||
const vocab = this.vocabTrainerPool[randomIndex];
|
||||
this.vocabTrainerDirection = Math.random() < 0.5 ? 'L2R' : 'R2L';
|
||||
this.currentVocabQuestion = {
|
||||
vocab: vocab,
|
||||
prompt: this.vocabTrainerDirection === 'L2R' ? vocab.learning : vocab.reference,
|
||||
answer: this.vocabTrainerDirection === 'L2R' ? vocab.reference : vocab.learning
|
||||
answer: this.vocabTrainerDirection === 'L2R' ? vocab.reference : vocab.learning,
|
||||
key: this.getVocabKey(vocab)
|
||||
};
|
||||
|
||||
// Reset UI
|
||||
this.vocabTrainerAnswer = '';
|
||||
this.vocabTrainerSelectedChoice = null;
|
||||
this.vocabTrainerAnswered = false;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.vocabInput?.focus?.();
|
||||
});
|
||||
|
||||
// Erstelle Choice-Optionen für Multiple Choice
|
||||
if (this.vocabTrainerMode === 'multiple_choice') {
|
||||
this.vocabTrainerChoiceOptions = this.buildChoiceOptions(this.currentVocabQuestion.answer, this.vocabTrainerPool);
|
||||
}
|
||||
|
||||
// Fokussiere Eingabefeld im Typing-Modus
|
||||
if (this.vocabTrainerMode === 'typing') {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.vocabInput?.focus?.();
|
||||
});
|
||||
}
|
||||
},
|
||||
selectVocabChoice(option) {
|
||||
this.vocabTrainerSelectedChoice = option;
|
||||
},
|
||||
normalizeVocab(s) {
|
||||
return String(s || '').trim().toLowerCase().replace(/\s+/g, ' ');
|
||||
},
|
||||
checkVocabAnswer() {
|
||||
if (!this.currentVocabQuestion || !this.vocabTrainerAnswer.trim()) return;
|
||||
const userAnswer = this.normalizeVocab(this.vocabTrainerAnswer);
|
||||
const correctAnswer = this.normalizeVocab(this.currentVocabQuestion.answer);
|
||||
this.vocabTrainerLastCorrect = userAnswer === correctAnswer;
|
||||
if (!this.currentVocabQuestion) return;
|
||||
|
||||
let userAnswer = '';
|
||||
if (this.vocabTrainerMode === 'multiple_choice') {
|
||||
if (!this.vocabTrainerSelectedChoice) return;
|
||||
userAnswer = this.vocabTrainerSelectedChoice;
|
||||
} else {
|
||||
if (!this.vocabTrainerAnswer.trim()) return;
|
||||
userAnswer = this.vocabTrainerAnswer;
|
||||
}
|
||||
|
||||
const normalizedUser = this.normalizeVocab(userAnswer);
|
||||
const normalizedCorrect = this.normalizeVocab(this.currentVocabQuestion.answer);
|
||||
this.vocabTrainerLastCorrect = normalizedUser === normalizedCorrect;
|
||||
|
||||
// Update Stats
|
||||
const stats = this.getVocabStats(this.currentVocabQuestion.vocab);
|
||||
stats.attempts++;
|
||||
this.vocabTrainerTotalAttempts++;
|
||||
|
||||
if (this.vocabTrainerLastCorrect) {
|
||||
this.vocabTrainerCorrect++;
|
||||
stats.correct++;
|
||||
} else {
|
||||
this.vocabTrainerWrong++;
|
||||
stats.wrong++;
|
||||
}
|
||||
|
||||
this.vocabTrainerAnswered = true;
|
||||
|
||||
// Im Typing-Modus: Automatisch zur nächsten Frage nach kurzer Pause (nur bei richtiger Antwort)
|
||||
if (this.vocabTrainerMode === 'typing' && this.vocabTrainerLastCorrect) {
|
||||
setTimeout(() => {
|
||||
this.nextVocabQuestion();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// Im Typing-Modus bei falscher Antwort: Eingabefeld fokussieren für erneuten Versuch
|
||||
if (this.vocabTrainerMode === 'typing' && !this.vocabTrainerLastCorrect) {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.vocabInput?.focus?.();
|
||||
this.vocabTrainerAnswer = '';
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
@@ -921,15 +1131,48 @@ export default {
|
||||
}
|
||||
|
||||
.vocab-trainer-stats {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
padding: 10px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.stats-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.stats-row:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.success-rate {
|
||||
font-weight: bold;
|
||||
color: #28a745;
|
||||
}
|
||||
|
||||
.mode-badge {
|
||||
padding: 5px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 0.9em;
|
||||
background: #e9ecef;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
.mode-badge.mode-active {
|
||||
background: #007bff;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mode-badge.mode-completed {
|
||||
background: #28a745;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-stop-trainer {
|
||||
padding: 5px 15px;
|
||||
background: #dc3545;
|
||||
@@ -969,9 +1212,46 @@ export default {
|
||||
}
|
||||
|
||||
.vocab-answer-area {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.vocab-answer-area.typing {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.vocab-answer-area.multiple-choice {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.choice-buttons {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.choice-button {
|
||||
padding: 12px;
|
||||
border: 2px solid #ddd;
|
||||
border-radius: 4px;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
font-size: 1em;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.choice-button:hover {
|
||||
border-color: #007bff;
|
||||
background: #f0f8ff;
|
||||
}
|
||||
|
||||
.choice-button.selected {
|
||||
border-color: #007bff;
|
||||
background: #007bff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.vocab-input {
|
||||
@@ -982,7 +1262,7 @@ export default {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.vocab-answer-area button {
|
||||
.btn-check {
|
||||
padding: 10px 20px;
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
@@ -992,11 +1272,11 @@ export default {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.vocab-answer-area button:hover:not(:disabled) {
|
||||
.btn-check:hover:not(:disabled) {
|
||||
background: #45a049;
|
||||
}
|
||||
|
||||
.vocab-answer-area button:disabled {
|
||||
.btn-check:disabled {
|
||||
background: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user