Enhance survival sentences exercises and VocabCourseView for improved user experience

- Added multiple choice exercises for common phrases in Bisaya, including questions and explanations to aid learning.
- Introduced a gap fill exercise for completing survival sentences, enhancing interactive learning.
- Updated VocabCourseView to display a button for continuing the current lesson, ensuring smoother navigation.
- Implemented logic to prevent starting lessons without completing previous ones, improving course progression management.
This commit is contained in:
Torsten Schulz (local)
2026-01-21 12:01:31 +01:00
parent a76aae3d12
commit a21a2314d7
5 changed files with 989 additions and 3 deletions

View File

@@ -19,6 +19,11 @@
</div>
<div v-if="course.lessons && course.lessons.length > 0" class="lessons-list">
<div class="current-lesson-section" v-if="currentLesson">
<button @click="openLesson(currentLesson.id)" class="btn-current-lesson">
{{ $t('socialnetwork.vocab.courses.continueCurrentLesson') }}
</button>
</div>
<h3>{{ $t('socialnetwork.vocab.courses.lessons') }}</h3>
<table class="lessons-table">
<thead>
@@ -53,7 +58,12 @@
</td>
<td class="lesson-actions">
<div class="lesson-actions-content">
<button @click="openLesson(lesson.id)" class="btn-start">
<button
@click="openLesson(lesson.id)"
class="btn-start"
:disabled="!canStartLesson(lesson)"
:title="!canStartLesson(lesson) ? $t('socialnetwork.vocab.courses.previousLessonRequired') : ''"
>
{{ getLessonProgress(lesson.id)?.completed ? $t('socialnetwork.vocab.courses.review') : $t('socialnetwork.vocab.courses.start') }}
</button>
<button v-if="isOwner" @click="editLesson(lesson.id)" class="btn-edit">{{ $t('socialnetwork.vocab.courses.edit') }}</button>
@@ -134,6 +144,25 @@ export default {
...mapGetters(['user']),
isOwner() {
return this.course && this.course.ownerUserId === this.user?.id;
},
currentLesson() {
if (!this.course || !this.course.lessons || this.course.lessons.length === 0) {
return null;
}
// Sortiere Lektionen nach lessonNumber
const sortedLessons = [...this.course.lessons].sort((a, b) => a.lessonNumber - b.lessonNumber);
// Finde die erste nicht abgeschlossene Lektion
for (const lesson of sortedLessons) {
const progress = this.getLessonProgress(lesson.id);
if (!progress || !progress.completed) {
return lesson;
}
}
// Alle Lektionen abgeschlossen - zeige die letzte Lektion
return sortedLessons[sortedLessons.length - 1];
}
},
watch: {
@@ -177,6 +206,31 @@ export default {
getLessonProgress(lessonId) {
return this.progress.find(p => p.lessonId === lessonId);
},
canStartLesson(lesson) {
if (!this.course || !this.course.lessons) {
return false;
}
// Sortiere Lektionen nach lessonNumber
const sortedLessons = [...this.course.lessons].sort((a, b) => a.lessonNumber - b.lessonNumber);
// Finde den Index der aktuellen Lektion
const currentIndex = sortedLessons.findIndex(l => l.id === lesson.id);
// Die erste Lektion kann immer gestartet werden
if (currentIndex === 0) {
return true;
}
// Wenn es nicht die erste Lektion ist, prüfe ob die vorherige abgeschlossen wurde
if (currentIndex > 0) {
const previousLesson = sortedLessons[currentIndex - 1];
const previousProgress = this.getLessonProgress(previousLesson.id);
return previousProgress && previousProgress.completed;
}
return false;
},
async addLesson() {
try {
await apiClient.post(`/api/vocab/courses/${this.courseId}/lessons`, this.newLesson);
@@ -256,6 +310,33 @@ export default {
margin-top: 30px;
}
.current-lesson-section {
margin-bottom: 20px;
padding: 15px;
background: #f8f9fa;
border-radius: 8px;
display: flex;
justify-content: center;
}
.btn-current-lesson {
padding: 12px 24px;
background: #F9A22C;
color: #000000;
border: 1px solid #F9A22C;
border-radius: 4px;
cursor: pointer;
font-size: 1em;
font-weight: 600;
transition: background 0.05s;
}
.btn-current-lesson:hover {
background: #fdf1db;
color: #7E471B;
border: 1px solid #7E471B;
}
.lessons-table {
width: 100%;
border-collapse: separate;
@@ -420,12 +501,20 @@ export default {
transition: background 0.05s;
}
.btn-start:hover {
.btn-start:hover:not(:disabled) {
background: #fdf1db;
color: #7E471B;
border: 1px solid #7E471B;
}
.btn-start:disabled {
background: #e0e0e0;
color: #999;
border: 1px solid #ccc;
cursor: not-allowed;
opacity: 0.6;
}
.btn-edit {
padding: 6px 12px;
background: #F9A22C;