from django.contrib import admin
from django.contrib.auth.forms import UserChangeForm, UsernameField
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.admin import GroupAdmin as BaseGroupAdmin
from django.utils.translation import gettext_lazy as _
from rest_framework.authtoken.models import TokenProxy
from ajaxdatatable.admin import AjaxDatatable
from apps.account.models import User, Notification, LocationHistory
from django import forms
from django.contrib import admin
from django.urls import path, reverse
from django.shortcuts import render, redirect
from django.contrib import messages
from apps.account.models import ClientUser, AdminUser, StudentUser, ProfessorUser
from phonenumber_field.formfields import PhoneNumberField
from utils.admin import project_admin_site
from unfold.forms import AdminPasswordChangeForm, UserChangeForm, UserCreationForm
from unfold.admin import ModelAdmin, StackedInline, TabularInline
from django.contrib.auth.models import Group
from django.db import models
from unfold.contrib.forms.widgets import WysiwygWidget
from unfold.decorators import action, display
from unfold.sections import TableSection
from unfold.contrib.filters.admin import (
AutocompleteSelectMultipleFilter,
ChoicesDropdownFilter,
MultipleRelatedDropdownFilter,
RangeDateFilter,
RangeDateTimeFilter,
RangeNumericFilter,
SingleNumericFilter,
TextFilter,
)
from apps.account.admin.location import LocationHistoryInline
class UserAdmin(BaseUserAdmin, ModelAdmin):
form = UserChangeForm
add_form = UserCreationForm
change_password_form = AdminPasswordChangeForm
compressed_fields = False
list_before_template = "account/user_list_section.html"
list_display = (
'fullname', 'email', 'is_active', 'display_date_joined',
)
ordering = ("-id",)
search_fields = (
'email', 'fullname', 'username',
)
list_filter = [
"is_active",
"is_staff",
("last_login", RangeDateTimeFilter),
("date_joined", RangeDateTimeFilter),
]
inlines = [LocationHistoryInline]
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ( ('fullname', 'email'), 'phone_number', 'birthdate', 'gender','avatar', 'skill', 'info'),
}),
(_('Location'), {
'fields': ('city', 'country'),
'classes': ('collapse',),
}),
(_('Password'), {
'fields': ('password1', 'password2'),
'classes': ('collapse',),
}),
(_('Permissions'), {
'fields': ('is_active', 'is_staff', 'is_superuser', 'groups'),
'classes': ('collapse',),
}),
)
fieldsets = (
(None, {"fields": ("email", "fullname")}),
(
_("Basic Information"),
{
"fields": ("gender", "avatar", "phone_number", "birthdate", 'info', 'skill', "password"),
"classes": ["tab"],
},
),
(
_('Country & City'), {
'fields': ('city', 'country'),
"classes": ["tab"],
}
),
(
_('Device Information'), {
'fields': ('device_id', 'device_os', 'fcm', 'language', ),
"classes": ["tab"],
}
),
(
_('Authentication'), {
'fields': ('display_auth_token',),
"classes": ["tab"],
}
),
(
_('Permissions'), {
'fields': ('user_type', 'is_active', 'is_staff', 'groups'),
"classes": ["tab"],
}
),
(
_('Important dates'), {
'fields': ('last_login', 'date_joined', 'deleted_at'),
"classes": ["tab"],
}
),
)
formfield_overrides = {
models.TextField: {
"widget": WysiwygWidget,
}
}
radio_fields = {
"gender": admin.HORIZONTAL,
}
readonly_fields = ["last_login", "date_joined", "display_auth_token"]
@display(description=_("Date Joined"))
def display_date_joined(self, instance: User):
return instance.date_joined.strftime("%Y-%m-%d %H:%M") if instance.date_joined else "-"
@display(description=_("Last Login"))
def display_last_login(self, instance: User):
return instance.last_login.strftime("%Y-%m-%d %H:%M") if instance.last_login else "-"
@display(description=_("Authentication Token"))
def display_auth_token(self, instance: User):
from rest_framework.authtoken.models import Token
from django.utils.html import format_html
try:
token, created = Token.objects.get_or_create(user=instance)
return format_html('{}', token.key)
except Exception as e:
return format_html('{}', str(e))
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.filter(email__isnull=False)
class GuestUserAdmin(UserAdmin):
list_display = (
'device_id', 'device_os', 'is_active', 'display_date_joined',
)
# Inherits fieldsets from UserAdmin, which now include the auth token
def has_add_permission(self, request):
if '_popup' in request.GET and request.GET['_popup'] == '1':
return True
return False
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.filter(email__isnull=True)
@display(description=_("Date Joined"))
def display_date_joined(self, instance: User):
return instance.date_joined.strftime("%Y-%m-%d %H:%M") if instance.date_joined else "-"
class StudentUserAdmin(UserAdmin):
list_display = (
'display_header', 'email', 'gender', 'display_age', 'courses_count'
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': (('fullname', 'email'), 'phone_number', 'avatar', 'birthdate', 'gender'),
}),
(_('Location'), {
'fields': (('city', 'country'),),
'classes': ('collapse',),
}),
(_('password'), {
'fields': ('password1', 'password2',),
'classes': ('collapse',),
}),
)
# Ensure the fieldsets from UserAdmin are used, which now include the auth token
@display(description=_("Student"), header=True)
def display_header(self, instance: StudentUser):
from django.templatetags.static import static
# Get avatar image path - use user's avatar if available, otherwise use default
avatar_path = instance.avatar.url if instance.avatar else static("images/reading(1).png")
return [
instance.fullname,
None,
None,
{
"path": avatar_path,
"height": 30,
"width": 36,
"borderless": True,
# "squared": True,
},
]
@display(description=_("Age"))
def display_age(self, instance: StudentUser):
from django.utils.html import format_html
from datetime import date
if not instance.birthdate:
return "-"
today = date.today()
birthdate = instance.birthdate
age = today.year - birthdate.year - ((today.month, today.day) < (birthdate.month, birthdate.day))
formatted_date = birthdate.strftime("%Y-%m-%d")
return format_html(
'{}',
f"Born on {formatted_date}",
age
)
@display(description=_("Courses"), dropdown=True)
def courses_count(self, instance: StudentUser):
from django.utils.html import format_html
total = instance.participated_courses.count()
items = []
for participant in instance.participated_courses.all():
course = participant.course
title = format_html(
"""