From 615c7bf8e9ae9099248d7d11f409e74db29c566e Mon Sep 17 00:00:00 2001 From: igennova Date: Tue, 18 Mar 2025 02:50:52 +0530 Subject: [PATCH 1/3] dasboard_done --- website/templates/stats_dashboard.html | 642 +++++++++++++++++++++---- website/views/core.py | 43 +- 2 files changed, 576 insertions(+), 109 deletions(-) diff --git a/website/templates/stats_dashboard.html b/website/templates/stats_dashboard.html index 9cccc9cfd7..08e5baeebf 100644 --- a/website/templates/stats_dashboard.html +++ b/website/templates/stats_dashboard.html @@ -4,127 +4,563 @@ {% block title %} Statistics Dashboard {% endblock title %} +{% block head %} + + + + +{% endblock head %} {% block content %} {% include "includes/sidenav.html" %} -
-
-
-

Statistics Dashboard

-
- -
- Time Period: - {% for option in period_options %} - - {{ option.label }} - - {% endfor %} -
-
- -
- -
-
-

Users

- -
-
{{ stats.users.total }}
-
- Active: {{ stats.users.active }} - (Total: {{ stats.users.total_all_time }}) -
-
- -
-
-

Issues

- +
+ +
+
+
+

Statistics Dashboard

+

Track platform metrics and growth analytics

+

+ Current period: {{ period }} +

-
{{ stats.issues.total }}
-
- Open: {{ stats.issues.open }} - (Total: {{ stats.issues.total_all_time }}) + +
+ Time Period: +
+ {% for option in period_options %} + + {{ option.label }} + + {% endfor %} +
- -
-
-

Domains

- -
-
{{ stats.domains.total }}
-
- Active: {{ stats.domains.active }} - (Total: {{ stats.domains.total_all_time }}) -
-
- -
-
-

Orgs

- +
+ +
+ +
+ +
+
+
+

Users

+
+ +
+
+
+
+ {{ stats.users.active|default:0 }} +
+
Active users
+
+
+
+ Total: {{ stats.users.total_all_time }} + (Period: {{ stats.users.total }}) +
+
+ {{ stats.users.active_percentage }} +
+
+
+
+
+
+
+
+
-
{{ stats.organizations.total }}
-
- Active: {{ stats.organizations.active }} - (Total: {{ stats.organizations.total_all_time }}) + +
+
+
+

Issues

+
+ +
+
+
+
{{ stats.issues.open|default:0 }}
+
Open issues
+
+
+
+ Total: {{ stats.issues.total_all_time }} + (Period: {{ stats.issues.total }}) +
+
+ {{ stats.issues.open_percentage }} +
+
+
+
+
+
+
+
+
-
- -
-
-

Hunts

- + +
+
+
+

Organizations

+
+ +
+
+
+
+ {{ stats.organizations.active|default:0 }} +
+
Active orgs
+
+
+
+ Total: {{ stats.organizations.total_all_time }} + (Period: {{ stats.organizations.total }}) +
+
+ {{ stats.organizations.active_percentage }} +
+
+
+
+
+
+
+
+
-
{{ stats.hunts.total }}
-
- Active: {{ stats.hunts.active }} - (Total: {{ stats.hunts.total_all_time }}) + +
+
+
+

Points

+
+ +
+
+
+
+ {{ stats.points.total|default:0 }} +
+
Recent points
+
+
+
+ Total: {{ stats.points.total_all_time }} + (Period: {{ stats.points.total }}) +
+
+ {{ stats.points.percentage }} +
+
+
+
+
+
+
+
+
- -
-
-

Points

- + +
+ +
+
+

Activity Over Time

+
+
+ + Issues +
+
+ + Users +
+
+
+
-
{{ stats.points.total }}
-
- (Total: {{ stats.points.total_all_time }}) + +
+

Issue Status Breakdown

+
- -
-
-

Projects

- + +
+ +
+
+ +
+
+
Domains
+
{{ stats.domains.total|default:0 }}
+
Active: {{ stats.domains.active }} / Total: {{ stats.domains.total_all_time }}
+
-
{{ stats.projects.total }}
-
- (Total: {{ stats.projects.total_all_time }}) -
- {% csrf_token %} - -
+ +
+
+ +
+
+
Bug Hunts
+
{{ stats.hunts.total|default:0 }}
+
Active: {{ stats.hunts.active }} / Total: {{ stats.hunts.total_all_time }}
+
-
- -
-
-

Activities

- + +
+
+ +
+
+
Projects
+
+ {{ stats.projects.total|default:0 }} +
+
+ Total: {{ stats.projects.total_all_time }} + +
+
-
{{ stats.activities.total }}
-
- (Total: {{ stats.activities.total_all_time }}) + +
+
+ +
+
+
Activities
+
+ {{ stats.activities.total|default:0 }} +
+
Total: {{ stats.activities.total_all_time }}
+
+ + {% endblock content %} +{% block scripts %} + +{% endblock scripts %} diff --git a/website/views/core.py b/website/views/core.py index b04bec3d05..98ba3bb7f6 100644 --- a/website/views/core.py +++ b/website/views/core.py @@ -1487,17 +1487,48 @@ def stats_dashboard(request): # Combine all stats stats = { - "users": {"total": users["total"], "active": users["active"], "total_all_time": total_users}, - "issues": {"total": issues["total"], "open": issues["open"], "total_all_time": total_issues}, - "domains": {"total": domains["total"], "active": domains["active"], "total_all_time": total_domains}, + "users": { + "total": users["total"], + "active": users["active"], + "total_all_time": total_users, + "active_percentage": round((users["active"] / users["total"] * 100) if users["total"] > 0 else 0), + }, + "issues": { + "total": issues["total"], + "open": issues["open"], + "total_all_time": total_issues, + "open_percentage": round((issues["open"] / issues["total"] * 100) if issues["total"] > 0 else 0), + }, + "domains": { + "total": domains["total"], + "active": domains["active"], + "total_all_time": total_domains, + "active_percentage": round((domains["active"] / domains["total"] * 100) if domains["total"] > 0 else 0), + }, "organizations": { "total": organizations["total"], "active": organizations["active"], "total_all_time": total_organizations, + "active_percentage": round( + (organizations["active"] / organizations["total"] * 100) if organizations["total"] > 0 else 0 + ), + }, + "hunts": { + "total": hunts["total"], + "active": hunts["active"], + "total_all_time": total_hunts, + "active_percentage": round((hunts["active"] / hunts["total"] * 100) if hunts["total"] > 0 else 0), + }, + "points": { + "total": points, + "total_all_time": total_points, + "percentage": round((points / total_points * 100) if total_points > 0 else 0), + }, + "projects": { + "total": projects, + "total_all_time": total_projects, + "percentage": round((projects / total_projects * 100) if total_projects > 0 else 0), }, - "hunts": {"total": hunts["total"], "active": hunts["active"], "total_all_time": total_hunts}, - "points": {"total": points, "total_all_time": total_points}, - "projects": {"total": projects, "total_all_time": total_projects}, "activities": { "total": activities, "total_all_time": total_activities, From 8fefe60b86ba0a4425b4edbba79a1015d823fa47 Mon Sep 17 00:00:00 2001 From: igennova Date: Tue, 18 Mar 2025 03:11:08 +0530 Subject: [PATCH 2/3] done --- website/templates/stats_dashboard.html | 8 +++--- website/views/core.py | 37 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/website/templates/stats_dashboard.html b/website/templates/stats_dashboard.html index 08e5baeebf..4156034baf 100644 --- a/website/templates/stats_dashboard.html +++ b/website/templates/stats_dashboard.html @@ -359,10 +359,10 @@

Issue Status Breakdown

const activityChartOptions = { series: [{ name: 'Issues', - data: [28, 45, 35, 50, 32, 55, 23, 30, 25, 40, 30, 45] + data: {{ issues_time_series|safe|default:'[0,0,0,0,0,0,0,0,0,0,0,0]' }} }, { name: 'Users', - data: [14, 25, 20, 25, 28, 15, 21, 35, 15, 25, 20, 15] + data: {{ users_time_series|safe|default:'[0,0,0,0,0,0,0,0,0,0,0,0]' }} }], chart: { type: 'area', @@ -472,7 +472,9 @@

Issue Status Breakdown

const issueStatusChartOptions = { series: [ parseInt(document.getElementById('issuesCounter').getAttribute('data-value') || '0', 10), - 42, 35, 20 + {{ stats.issues.fixed|default:0 }}, + {{ stats.issues.in_review|default:0 }}, + {{ stats.issues.invalid|default:0 }} ], chart: { type: 'donut', diff --git a/website/views/core.py b/website/views/core.py index 98ba3bb7f6..acd4c59ecc 100644 --- a/website/views/core.py +++ b/website/views/core.py @@ -1498,6 +1498,9 @@ def stats_dashboard(request): "open": issues["open"], "total_all_time": total_issues, "open_percentage": round((issues["open"] / issues["total"] * 100) if issues["total"] > 0 else 0), + "fixed": Issue.objects.filter(created__gte=start_date, status="fixed").count(), + "in_review": Issue.objects.filter(created__gte=start_date, status="in_review").count(), + "invalid": Issue.objects.filter(created__gte=start_date, status="invalid").count(), }, "domains": { "total": domains["total"], @@ -1536,6 +1539,38 @@ def stats_dashboard(request): }, } + # Get time series data for charts (last 12 months or the selected period) + months_data = [] + if days == "ytd": + months_to_fetch = end_date.month + elif days > 365: + months_to_fetch = min(12, days // 30) + else: + months_to_fetch = min(12, max(1, days // 30)) + + # Generate time series data + issues_time_series = [] + users_time_series = [] + + for i in range(months_to_fetch): + month_end = end_date - timedelta(days=i * 30) + month_start = month_end - timedelta(days=30) + + month_issues = Issue.objects.filter(created__gte=month_start, created__lte=month_end).count() + month_users = User.objects.filter(date_joined__gte=month_start, date_joined__lte=month_end).count() + + issues_time_series.insert(0, month_issues) + users_time_series.insert(0, month_users) + + # Fill remaining months with zeros if we have less than 12 months + while len(issues_time_series) < 12: + issues_time_series.insert(0, 0) + users_time_series.insert(0, 0) + + # Add time series data to the stats dictionary + stats["issues_time_series"] = issues_time_series + stats["users_time_series"] = users_time_series + # Cache the results for 5 minutes cache.set(cache_key, stats, timeout=300) @@ -1551,6 +1586,8 @@ def stats_dashboard(request): {"value": "365", "label": "1 Year"}, {"value": "1825", "label": "5 Years"}, ], + "issues_time_series": json.dumps(stats.get("issues_time_series", [])), + "users_time_series": json.dumps(stats.get("users_time_series", [])), } return render(request, "stats_dashboard.html", context) From 397ca844ae777de8a7cf806476ba91a9d66412ae Mon Sep 17 00:00:00 2001 From: igennova Date: Tue, 18 Mar 2025 03:20:44 +0530 Subject: [PATCH 3/3] done --- website/templates/stats_dashboard.html | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/website/templates/stats_dashboard.html b/website/templates/stats_dashboard.html index 4156034baf..78d54640cc 100644 --- a/website/templates/stats_dashboard.html +++ b/website/templates/stats_dashboard.html @@ -6,9 +6,13 @@ {% endblock title %} {% block head %} - + - + {% endblock head %} {% block content %} {% include "includes/sidenav.html" %}