Files
yourpart3/frontend/src/components/widgets/VocabCoursesWidget.vue
Torsten Schulz (local) 6fa36908b2 feat(bisaya-course): refine phase 4 didactics and enhance course content generation
- Corrected grammatical errors and improved the phrasing in the BISAYA_PHASE4_DIDACTICS, ensuring clarity and accuracy in the learning materials.
- Updated the course content generation script to include lessons from phase 5, enhancing the overall structure and flow of the course.
- Introduced a new vocabulary course content synchronization process, improving the integration of vocabulary resources across different modules.
- Enhanced the VocabService to dynamically adjust temperature settings based on the mode, optimizing response generation for different contexts.
- Added new localized titles and vocabulary entries in multiple languages, enriching the learning experience for users.
2026-04-17 16:00:41 +02:00

171 lines
4.3 KiB
Vue

<template>
<div class="vocab-courses-widget">
<p v-if="!courses.length" class="vocab-courses-widget__empty">
{{ $t('widgets.vocabCourses.empty') }}
<router-link class="vocab-courses-widget__link" to="/socialnetwork/vocab/courses">
{{ $t('widgets.vocabCourses.browseCourses') }}
</router-link>
</p>
<ul v-else class="vocab-courses-widget__list">
<li v-for="c in courses" :key="c.courseId" class="vocab-courses-widget__item">
<div class="vocab-courses-widget__main">
<strong class="vocab-courses-widget__course-title">{{ displayCourseTitle(c) }}</strong>
<span v-if="c.currentLesson" class="vocab-courses-widget__lesson">
{{ $t('widgets.vocabCourses.lessonLine', { number: c.currentLesson.lessonNumber, title: c.currentLesson.title }) }}
</span>
<span v-else class="vocab-courses-widget__lesson vocab-courses-widget__lesson--muted">
{{ $t('widgets.vocabCourses.noLessons') }}
</span>
<span v-if="c.allLessonsCompleted && c.currentLesson" class="vocab-courses-widget__badge">
{{ $t('widgets.vocabCourses.allDone') }}
</span>
</div>
<button
v-if="c.currentLesson"
type="button"
class="vocab-courses-widget__btn"
@click="goToLesson(c.courseId, c.currentLesson.id)"
>
{{ $t('widgets.vocabCourses.openLesson') }}
</button>
<button
v-else
type="button"
class="vocab-courses-widget__btn vocab-courses-widget__btn--secondary"
@click="goToCourse(c.courseId)"
>
{{ $t('widgets.vocabCourses.openCourse') }}
</button>
</li>
</ul>
</div>
</template>
<script>
import { localizeVocabCourseTitle } from '@/utils/vocabCourseTitle.js';
export default {
name: 'VocabCoursesWidget',
props: {
data: { type: Object, default: null }
},
computed: {
courses() {
const raw = this.data;
if (!raw || typeof raw !== 'object') {
return [];
}
const list = raw.courses ?? raw.Courses;
return Array.isArray(list) ? list : [];
}
},
methods: {
displayCourseTitle(course) {
return localizeVocabCourseTitle(course?.title, this.$i18n?.locale) || this.$t('widgets.vocabCourses.unnamedCourse');
},
goToLesson(courseId, lessonId) {
this.$router.push({
name: 'VocabLesson',
params: { courseId: String(courseId), lessonId: String(lessonId) }
});
},
goToCourse(courseId) {
this.$router.push({
name: 'VocabCourse',
params: { courseId: String(courseId) }
});
}
}
};
</script>
<style scoped>
.vocab-courses-widget__empty {
margin: 0;
font-size: 0.9rem;
color: var(--color-text-secondary, #555);
line-height: 1.45;
}
.vocab-courses-widget__link {
display: inline-block;
margin-top: 0.35rem;
font-weight: 600;
color: var(--color-primary-orange-dark, #c2410c);
}
.vocab-courses-widget__list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 12px;
}
.vocab-courses-widget__item {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
justify-content: space-between;
gap: 8px 12px;
padding-bottom: 10px;
border-bottom: 1px solid var(--dashboard-widget-border, #e9ecef);
}
.vocab-courses-widget__item:last-child {
border-bottom: none;
padding-bottom: 0;
}
.vocab-courses-widget__main {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 2px;
}
.vocab-courses-widget__course-title {
font-size: 0.92rem;
color: var(--color-text-primary, #222);
}
.vocab-courses-widget__lesson {
font-size: 0.82rem;
color: var(--color-text-secondary, #555);
line-height: 1.35;
}
.vocab-courses-widget__lesson--muted {
font-style: italic;
}
.vocab-courses-widget__badge {
font-size: 0.75rem;
font-weight: 600;
color: #198754;
margin-top: 2px;
}
.vocab-courses-widget__btn {
flex-shrink: 0;
padding: 6px 12px;
font-size: 0.82rem;
font-weight: 600;
border: none;
border-radius: 6px;
cursor: pointer;
background: var(--color-primary-orange, #f97316);
color: #fff;
}
.vocab-courses-widget__btn:hover {
filter: brightness(1.05);
}
.vocab-courses-widget__btn--secondary {
background: var(--color-text-secondary, #6c757d);
}
</style>