You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

61 lines
2.3 KiB

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from django.utils import timezone
from datetime import timedelta
from django.db.models import Count
from django.db.models.functions import TruncDate
from rest_framework.authentication import TokenAuthentication
from apps.account.models import User, LoginHistory
from apps.api.models import AppVersion, SupportMessage
class AdminDashboardStatsView(APIView):
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated, IsAdminUser]
def get(self, request):
now = timezone.now()
thirty_days_ago = now - timedelta(days=30)
seven_days_ago = now - timedelta(days=7)
# 1. User metrics
total_users = User.objects.count()
active_users = User.objects.filter(is_active=True).count()
new_users_30d = User.objects.filter(date_joined__gte=thirty_days_ago).count()
staff_users = User.objects.filter(is_staff=True).count()
# 2. Login activity
logins_7d = LoginHistory.objects.filter(at_time__gte=seven_days_ago).count()
login_chart_qs = (
LoginHistory.objects.filter(at_time__gte=seven_days_ago)
.annotate(date=TruncDate('at_time'))
.values('date')
.annotate(count=Count('id'))
.order_by('date')
)
login_chart = [
{"date": entry['date'].strftime('%Y-%m-%d'), "count": entry['count']}
for entry in login_chart_qs
]
# 3. System info
latest_version = AppVersion.get_latest_active()
unresolved_support = SupportMessage.objects.filter(is_resolved=False).count()
data = {
"summary": {
"total_users": total_users,
"active_users": active_users,
"new_users_30d": new_users_30d,
"staff_users": staff_users,
"logins_7d": logins_7d,
"unresolved_support": unresolved_support,
"latest_app_version": latest_version.version if latest_version else None,
},
"charts": {
"logins_by_day": login_chart,
}
}
return Response(data)