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:
@@ -394,6 +394,9 @@
|
||||
"correctAnswer": "Richtige Antwort",
|
||||
"alternatives": "Alternative Antworten",
|
||||
"notStarted": "Nicht begonnen",
|
||||
"continueCurrentLesson": "Zur aktuellen Lektion",
|
||||
"previousLessonRequired": "Bitte schließe zuerst die vorherige Lektion ab",
|
||||
"lessonNumberShort": "#",
|
||||
"readingAloudInstruction": "Lies den Text laut vor. Klicke auf 'Aufnahme starten' und beginne zu sprechen.",
|
||||
"speakingFromMemoryInstruction": "Sprich frei aus dem Kopf. Verwende die angezeigten Schlüsselwörter.",
|
||||
"startRecording": "Aufnahme starten",
|
||||
|
||||
@@ -394,6 +394,9 @@
|
||||
"correctAnswer": "Correct Answer",
|
||||
"alternatives": "Alternative Answers",
|
||||
"notStarted": "Not Started",
|
||||
"continueCurrentLesson": "Continue Current Lesson",
|
||||
"previousLessonRequired": "Please complete the previous lesson first",
|
||||
"lessonNumberShort": "#",
|
||||
"readingAloudInstruction": "Read the text aloud. Click 'Start Recording' and begin speaking.",
|
||||
"speakingFromMemoryInstruction": "Speak freely from memory. Use the displayed keywords.",
|
||||
"startRecording": "Start Recording",
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user