From d541205f223e9ba293669e705cdcda81b7f2a97c Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Fri, 6 Jun 2025 15:37:08 +0200 Subject: [PATCH] add tournaments dashboard --- tournaments/admin.py | 56 +++- .../admin/tournaments/dashboard.html | 286 ++++++++++++++++++ .../tournaments/tournament/change_list.html | 18 ++ 3 files changed, 359 insertions(+), 1 deletion(-) create mode 100644 tournaments/templates/admin/tournaments/dashboard.html create mode 100644 tournaments/templates/admin/tournaments/tournament/change_list.html diff --git a/tournaments/admin.py b/tournaments/admin.py index 6be27c2..9575633 100644 --- a/tournaments/admin.py +++ b/tournaments/admin.py @@ -3,8 +3,11 @@ from django.contrib.auth.admin import UserAdmin from django.utils import timezone from django.contrib.admin.models import LogEntry, ADDITION, CHANGE, DELETION from django.utils.html import escape -from django.urls import reverse +from django.urls import reverse, path # Add path import from django.utils.safestring import mark_safe +from django.shortcuts import render # Add this import +from django.db.models import Sum, Count, Avg, Q # Add these imports +from datetime import datetime, timedelta # Add this import from .models import Club, TeamScore, Tournament, CustomUser, Event, Round, GroupStage, Match, TeamRegistration, PlayerRegistration, Purchase, Court, DateInterval, FailedApiCall, Log, DeviceToken, DrawLog, UnregisteredTeam, UnregisteredPlayer, Image from .forms import CustomUserCreationForm, CustomUserChangeForm @@ -85,6 +88,57 @@ class TournamentAdmin(SyncedObjectAdmin): ordering = ['-start_date'] search_fields = ['id'] + def dashboard_view(self, request): + """Tournament dashboard view with comprehensive statistics""" + + # Calculate date ranges + now = timezone.now() + today = now.date() + week_ago = today - timedelta(days=7) + month_ago = today - timedelta(days=30) + + # Tournament statistics - running today + tournaments_today = Tournament.objects.filter( + start_date__date__lte=today, + end_date__date__gte=today + ).exclude(is_deleted=True) + + tournaments_today_private = tournaments_today.filter(is_private=True).count() + tournaments_today_public = tournaments_today.filter(is_private=False).count() + tournaments_today_total = tournaments_today.count() + + # All time tournament statistics + all_tournaments = Tournament.objects.exclude(is_deleted=True) + tournaments_all_total = all_tournaments.count() + + # Team and player statistics + total_teams = TeamRegistration.objects.count() + total_players = PlayerRegistration.objects.count() + + # Match statistics + total_matches = Match.objects.count() + matches_played = Match.objects.filter(end_date__isnull=False).count() + + context = { + 'tournaments_today_total': tournaments_today_total, + 'tournaments_today_private': tournaments_today_private, + 'tournaments_today_public': tournaments_today_public, + 'tournaments_all_total': tournaments_all_total, + 'total_teams': total_teams, + 'total_players': total_players, + 'total_matches': total_matches, + 'matches_played': matches_played, + } + + return render(request, 'admin/tournaments/dashboard.html', context) + + def get_urls(self): + urls = super().get_urls() + custom_urls = [ + path('dashboard/', self.admin_site.admin_view(self.dashboard_view), name='tournaments_tournament_dashboard'), + ] + return custom_urls + urls + class TeamRegistrationAdmin(SyncedObjectAdmin): list_display = ['player_names', 'group_stage', 'name', 'tournament', 'registration_date'] list_filter = [SimpleTournamentListFilter] diff --git a/tournaments/templates/admin/tournaments/dashboard.html b/tournaments/templates/admin/tournaments/dashboard.html new file mode 100644 index 0000000..e1269b3 --- /dev/null +++ b/tournaments/templates/admin/tournaments/dashboard.html @@ -0,0 +1,286 @@ +{% extends "admin/base_site.html" %} +{% load admin_urls %} + +{% block title %}Tournament Dashboard{% endblock %} + +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} +
+

🏆 Tournament Dashboard

+ + +
+ + +
+

+ 🎾 Running Tournaments +

+
+
+
+
{{ tournaments_today_total }}
+
Today
+
+
+
{{ tournaments_today_private }}/{{ tournaments_today_public }}
+
Private/Public
+
+
+
+
+
{{ tournaments_week_total }}
+
This Week
+
+
+
{{ tournaments_week_private }}/{{ tournaments_week_public }}
+
Private/Public
+
+
+
+
+
{{ tournaments_month_total }}
+
This Month
+
+
+
{{ tournaments_month_private }}/{{ tournaments_month_public }}
+
Private/Public
+
+
+
+
+ + +
+

+ 🏁 Ended Tournaments +

+
+
+
{{ tournaments_ended_today }}
+
Today
+
+
+
{{ tournaments_ended_week }}
+
This Week
+
+
+
{{ tournaments_ended_month }}
+
This Month
+
+
+
{{ tournaments_ended_all }}
+
All Time
+
+
+
+ + +
+

+ 👥 Participants +

+
+
+
{{ total_teams }}
+
Total Teams
+
+
+
{{ total_players }}
+
Total Players
+
+
+
{{ avg_teams_per_tournament }}
+
Avg Teams/Tournament
+
+
+
+ + +
+

+ 🏓 Matches +

+
+
+
{{ total_matches }}
+
Total Matches
+
+
+
{{ matches_played }}
+
Played
+
+
+
{{ matches_pending }}
+
Pending
+
+
+
+
+ + +
+

+ 📊 All Time Overview +

+
+
+
{{ tournaments_all_total }}
+
Total Tournaments
+
+ {{ tournaments_all_private }} Private | {{ tournaments_all_public }} Public +
+
+
+
{{ tournaments_with_online_reg }}
+
Online Registration
+
+
+
{{ tournaments_with_payment }}
+
Online Payment
+
+
+
€{{ avg_entry_fee }}
+
Avg Entry Fee
+
+
+
+ + +
+

📈 Tournament Breakdown

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PeriodRunningPrivatePublicEnded
Today + + {{ tournaments_today_total }} + + {{ tournaments_today_private }}{{ tournaments_today_public }}{{ tournaments_ended_today }}
This Week + + {{ tournaments_week_total }} + + {{ tournaments_week_private }}{{ tournaments_week_public }}{{ tournaments_ended_week }}
This Month + + {{ tournaments_month_total }} + + {{ tournaments_month_private }}{{ tournaments_month_public }}{{ tournaments_ended_month }}
All Time + + {{ tournaments_all_total }} + + {{ tournaments_all_private }}{{ tournaments_all_public }}{{ tournaments_ended_all }}
+
+
+ + + +
+ + +{% endblock %} diff --git a/tournaments/templates/admin/tournaments/tournament/change_list.html b/tournaments/templates/admin/tournaments/tournament/change_list.html new file mode 100644 index 0000000..28ea9b6 --- /dev/null +++ b/tournaments/templates/admin/tournaments/tournament/change_list.html @@ -0,0 +1,18 @@ +{% extends "admin/change_list.html" %} + +{% block object-tools %} + +{% endblock %}