from django.contrib import admin from django.utils import timezone from unfold.admin import ModelAdmin from .access import has_lifetime_premium from .models import DailyMissionClaim, PremiumEntitlement, StudentProfile @admin.register(StudentProfile) class StudentProfileAdmin(ModelAdmin): list_display = ("user", "premium_status", "target_band", "daily_goal", "xp", "streak") search_fields = ("user__username", "user__email", "user__first_name", "user__last_name") list_filter = ("target_band", "daily_goal") actions = ("grant_lifetime_premium", "revoke_lifetime_premium") @admin.display(description="Membership", boolean=True) def premium_status(self, obj): return has_lifetime_premium(obj.user) @admin.action(description="Grant Lifetime Premium") def grant_lifetime_premium(self, request, queryset): granted = 0 for profile in queryset.select_related("user"): entitlement, created = PremiumEntitlement.objects.get_or_create( user=profile.user, defaults={"source": PremiumEntitlement.SOURCE_ADMIN}, ) if entitlement.revoked_at is not None: entitlement.revoked_at = None entitlement.save(update_fields=["revoked_at"]) if created or entitlement.is_active: granted += 1 self.message_user(request, f"Lifetime Premium is active for {granted} user(s).") @admin.action(description="Revoke Lifetime Premium") def revoke_lifetime_premium(self, request, queryset): updated = PremiumEntitlement.objects.filter( user__studentprofile__in=queryset, revoked_at__isnull=True, ).update(revoked_at=timezone.now()) self.message_user(request, f"Revoked Lifetime Premium for {updated} user(s).") @admin.register(PremiumEntitlement) class PremiumEntitlementAdmin(ModelAdmin): list_display = ("user", "status", "source", "order_reference", "granted_at", "revoked_at") list_filter = ("source", "revoked_at", "granted_at") search_fields = ("user__username", "user__email", "order_reference") readonly_fields = ("granted_at",) list_select_related = ("user",) @admin.display(description="Status") def status(self, obj): return "Active" if obj.is_active else "Revoked" @admin.register(DailyMissionClaim) class DailyMissionClaimAdmin(ModelAdmin): list_display = ("user", "mission_key", "completed_on", "xp_awarded", "claimed_at") list_filter = ("mission_key", "completed_on") search_fields = ("user__username", "user__email") readonly_fields = ("claimed_at",)