+
+
+
+
{{ $t('socialnetwork.vocab.courses.courseFlowIntensiveStatusTitle') }}
+ +{{ $t('socialnetwork.vocab.courses.courseFlowIntensiveStatusAllDone') }}
+ + +{{ $t('socialnetwork.vocab.courses.courseFlowIntensiveStatusReady', { lesson: intensiveReviewStatus.lesson.title }) }}
+ + +{{ $t('socialnetwork.vocab.courses.courseFlowIntensiveStatusProgress', { + done: intensiveReviewStatus.completedPrerequisiteCount, + total: intensiveReviewStatus.prerequisiteLessons.length, + lesson: intensiveReviewStatus.lesson.title + }) }}
+{{ $t('socialnetwork.vocab.courses.courseFlowIntensiveStatusNoDate') }}
+-
+
- + #{{ lesson.lessonNumber }} {{ lesson.title }} + + +
+
+
+
@@ -376,6 +412,7 @@ export default {
srsDailyLimit: 50,
srsTodayRemaining: null,
srsLoading: false,
+ showIntensiveStatusDialog: false,
showAddLessonDialog: false,
assistantSettings: null,
hardVocabList: [],
@@ -460,20 +497,46 @@ export default {
},
nextIntensiveReviewLesson() {
return this.sortedLessons.find((lesson) => {
- const isIntensive = lesson.pedagogy?.didacticMode === 'intensive_review' || lesson.pedagogy?.isIntensiveReview;
+ const isIntensive = this.isIntensiveReviewLesson(lesson);
if (!isIntensive) return false;
if (this.getLessonProgress(lesson.id, lesson)?.completed) return false;
const blockNumber = lesson.pedagogy?.blockNumber;
const blockLessons = this.sortedLessons.filter((candidate) => {
if ((candidate.pedagogy?.blockNumber || null) !== blockNumber) return false;
- const candidateIsIntensive = candidate.pedagogy?.didacticMode === 'intensive_review' || candidate.pedagogy?.isIntensiveReview;
+ const candidateIsIntensive = this.isIntensiveReviewLesson(candidate);
return !candidateIsIntensive && candidate.lessonNumber < lesson.lessonNumber;
});
return blockLessons.length > 0 && blockLessons.every((candidate) => this.getLessonProgress(candidate.id, candidate)?.completed);
}) || null;
},
+ intensiveReviewStatus() {
+ const lesson = this.sortedLessons.find((candidate) => (
+ this.isIntensiveReviewLesson(candidate)
+ && !this.getLessonProgress(candidate.id, candidate)?.completed
+ ));
+ if (!lesson) {
+ return { allCompleted: true, ready: false, prerequisiteLessons: [], missingPrerequisiteLessons: [], completedPrerequisiteCount: 0 };
+ }
+
+ const prerequisiteLessons = this.sortedLessons.filter((candidate) => (
+ !this.isIntensiveReviewLesson(candidate)
+ && candidate.pedagogy?.blockNumber === lesson.pedagogy?.blockNumber
+ && candidate.lessonNumber < lesson.lessonNumber
+ ));
+ const missingPrerequisiteLessons = prerequisiteLessons.filter((candidate) => (
+ !this.getLessonProgress(candidate.id, candidate)?.completed
+ ));
+ return {
+ allCompleted: false,
+ lesson,
+ ready: prerequisiteLessons.length > 0 && missingPrerequisiteLessons.length === 0,
+ prerequisiteLessons,
+ missingPrerequisiteLessons,
+ completedPrerequisiteCount: prerequisiteLessons.length - missingPrerequisiteLessons.length
+ };
+ },
freePracticeLessons() {
return this.sortedLessons
.filter((lesson) => {
@@ -566,6 +629,9 @@ export default {
}
},
methods: {
+ isIntensiveReviewLesson(lesson) {
+ return lesson?.pedagogy?.didacticMode === 'intensive_review' || Boolean(lesson?.pedagogy?.isIntensiveReview);
+ },
displayCourseTitle(course) {
return localizeVocabCourseTitle(course?.title, this.$i18n?.locale) || '';
},
@@ -935,6 +1001,10 @@ export default {
openLesson(lessonId) {
this.$router.push(`/socialnetwork/vocab/courses/${this.courseId}/lessons/${lessonId}`);
},
+ openIntensivePrerequisite(lessonId) {
+ this.showIntensiveStatusDialog = false;
+ this.openLesson(lessonId);
+ },
todayPlanStepLabel(type) {
const key = {
review_due: 'courseTodayPlanStepReviewDue',
@@ -1382,6 +1452,40 @@ export default {
font-size: 0.92rem;
}
+.course-flow-card__status {
+ margin-top: 10px;
+ padding: 0;
+ border: 0;
+ background: transparent;
+ color: #2f6b3d;
+ font-weight: 650;
+ text-decoration: underline;
+ cursor: pointer;
+}
+
+.intensive-status-dialog__hint {
+ color: var(--color-text-secondary);
+ line-height: 1.5;
+}
+
+.intensive-status-dialog__list {
+ display: grid;
+ gap: 8px;
+ margin: 16px 0;
+ padding: 0;
+ list-style: none;
+}
+
+.intensive-status-dialog__list li {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ padding: 10px 12px;
+ border: 1px solid var(--color-border);
+ border-radius: var(--radius-md);
+}
+
.share-code {
font-family: monospace;
}