Some checks failed
Backend (courses app): - courses/serializers.py: Course, Module, Lesson, Page, Enrollment, PageProgress serializers - courses/views.py: CourseListView, CourseDetailView, CourseEnrollView, CourseMyProgressView, MyEnrollmentsView, PageDetailView - courses/urls.py: expose all 6 endpoints under /api/v1/courses/ Frontend: - courses.html + courses.js: course catalog with "Meine Kurse" and "Alle Kurse" sections, enroll button with toast feedback, progress bars - course-player.html + course-player.js: full-screen player with collapsible sidebar nav (module → lesson → page tree), page content renderer (text/video/embed), dwell gate, prev/next navigation, enrollment CTA, completion screen - courses.css: course grid, player layout, sidebar nav, progress bar, dwell gate - Add Kurse nav link to meetings.html, attendance.html - Update index.html hero and workflow grid to include Kurse Co-Authored-By: Paperclip <noreply@paperclip.ing>
102 lines
3.4 KiB
Python
102 lines
3.4 KiB
Python
from django.db.models import Count
|
|
from rest_framework import serializers
|
|
|
|
from tracking.models import Enrollment, PageProgress
|
|
|
|
from .models import Course, Lesson, Module, Page
|
|
|
|
|
|
class PageSummarySerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Page
|
|
fields = ["id", "title", "order", "content_type", "is_required", "required_seconds"]
|
|
|
|
|
|
class PageDetailSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Page
|
|
fields = ["id", "title", "order", "content_type", "content_body", "is_required", "required_seconds"]
|
|
|
|
|
|
class LessonSerializer(serializers.ModelSerializer):
|
|
pages = PageSummarySerializer(many=True, read_only=True)
|
|
|
|
class Meta:
|
|
model = Lesson
|
|
fields = ["id", "title", "order", "pages"]
|
|
|
|
|
|
class ModuleSerializer(serializers.ModelSerializer):
|
|
lessons = LessonSerializer(many=True, read_only=True)
|
|
|
|
class Meta:
|
|
model = Module
|
|
fields = ["id", "title", "order", "lessons"]
|
|
|
|
|
|
class EnrollmentSerializer(serializers.ModelSerializer):
|
|
course_id = serializers.UUIDField(source="course.id", read_only=True)
|
|
course_title = serializers.CharField(source="course.title", read_only=True)
|
|
course_slug = serializers.SlugField(source="course.slug", read_only=True)
|
|
course_description = serializers.CharField(source="course.description", read_only=True)
|
|
progress_percent = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Enrollment
|
|
fields = [
|
|
"id", "course_id", "course_title", "course_slug", "course_description",
|
|
"enrolled_at", "completed_at", "progress_percent",
|
|
]
|
|
read_only_fields = fields
|
|
|
|
def get_progress_percent(self, obj):
|
|
return getattr(obj, "_progress_percent", 0)
|
|
|
|
|
|
class CourseSummarySerializer(serializers.ModelSerializer):
|
|
module_count = serializers.IntegerField(read_only=True)
|
|
my_enrollment = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Course
|
|
fields = ["id", "title", "slug", "description", "module_count", "is_published", "my_enrollment", "updated_at"]
|
|
|
|
def get_my_enrollment(self, obj):
|
|
enrollment = getattr(obj, "_my_enrollment", None)
|
|
if enrollment is None:
|
|
return None
|
|
return {
|
|
"id": str(enrollment.id),
|
|
"enrolled_at": enrollment.enrolled_at,
|
|
"completed_at": enrollment.completed_at,
|
|
"progress_percent": getattr(enrollment, "_progress_percent", 0),
|
|
}
|
|
|
|
|
|
class CourseDetailSerializer(serializers.ModelSerializer):
|
|
modules = ModuleSerializer(many=True, read_only=True)
|
|
my_enrollment = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Course
|
|
fields = ["id", "title", "slug", "description", "version", "is_published", "modules", "my_enrollment", "updated_at"]
|
|
|
|
def get_my_enrollment(self, obj):
|
|
enrollment = getattr(obj, "_my_enrollment", None)
|
|
if enrollment is None:
|
|
return None
|
|
return {
|
|
"id": str(enrollment.id),
|
|
"enrolled_at": enrollment.enrolled_at,
|
|
"completed_at": enrollment.completed_at,
|
|
"progress_percent": getattr(enrollment, "_progress_percent", 0),
|
|
}
|
|
|
|
|
|
class PageProgressSerializer(serializers.ModelSerializer):
|
|
page_id = serializers.UUIDField(source="page_id", read_only=True)
|
|
|
|
class Meta:
|
|
model = PageProgress
|
|
fields = ["page_id", "is_complete", "accumulated_seconds", "last_seen_at"]
|