import os from django.contrib import admin from django import forms from django.utils.translation import gettext_lazy as _ from django.db import models from django.utils.html import format_html from unfold.admin import ModelAdmin from unfold.decorators import display from unfold.contrib.forms.widgets import WysiwygWidget from unfold.contrib.filters.admin import ( ChoicesDropdownFilter, MultipleRelatedDropdownFilter, ) from unfold.widgets import ( UnfoldAdminRadioSelectWidget, ) from utils.admin import project_admin_site from apps.course.models.lesson import Lesson, LessonCompletion from unfold.admin import ModelAdmin, StackedInline, TabularInline class LessonForm(forms.ModelForm): class Meta: model = Lesson fields = '__all__' widgets = { 'content_type': UnfoldAdminRadioSelectWidget(), } from apps.quiz.models import Quiz class LessonAdmin(ModelAdmin): form = LessonForm list_display = ('title', 'course', 'display_duration', 'content_type', 'is_active', 'priority') list_filter = ( ('course', MultipleRelatedDropdownFilter), ('content_type', ChoicesDropdownFilter), 'is_active', ) search_fields = ('title', 'course__title') ordering = ('course', 'priority') autocomplete_fields = ('course', ) list_filter_submit = True radio_fields = { "content_type": admin.HORIZONTAL, } conditional_fields = { 'content_file': "content_type == 'video_file'", 'video_link': "content_type == 'youtube_link'", } fieldsets = ( (None, { 'fields': ('course', 'title', 'priority', 'is_active', 'duration') }), (_('Content'), { 'fields': ('content_type', 'content_file', 'video_link'), 'classes': [], }), ) def get_form(self, request, obj=None, change=False, **kwargs): form = super().get_form(request, obj, change, **kwargs) # Enhanced styling for content_type radio buttons form.base_fields["content_type"].widget = UnfoldAdminRadioSelectWidget( choices=Lesson.ContentTypeChoices.choices, radio_style=admin.HORIZONTAL, attrs={ "class": "radio-inline flex gap-4 p-2 rounded-lg bg-gray-50 shadow-sm", "option_class": "flex items-center p-2 rounded-md hover:bg-white hover:shadow-sm transition-all duration-200", "label_class": "ml-2 font-medium text-gray-700 cursor-pointer", "input_class": "form-radio h-5 w-5 text-blue-600 transition duration-150 ease-in-out cursor-pointer", }, ) return form @display(description=_("Duration")) def display_duration(self, obj): return format_html( '{} min', obj.duration ) def get_queryset(self, request): qs = super().get_queryset(request) return qs.order_by('course', 'priority') class LessonCompletionAdmin(ModelAdmin): list_display = ('student', 'lesson', 'completed_at') search_fields = ('student__fullname', 'student__email', 'lesson__title', 'lesson__course__title') list_filter = ('lesson__course', 'completed_at') ordering = ('-completed_at',) def get_readonly_fields(self, request, obj=None): """ Make fields readonly if the object already exists. """ if obj: return ['student', 'lesson', 'completed_at'] return [] # Register with the project admin site project_admin_site.register(Lesson, LessonAdmin) project_admin_site.register(LessonCompletion, LessonCompletionAdmin)