diff --git a/hackathon/migrations/0038_auto_20210224_1521.py b/hackathon/migrations/0038_auto_20210224_1521.py
new file mode 100644
index 00000000..8996b4c7
--- /dev/null
+++ b/hackathon/migrations/0038_auto_20210224_1521.py
@@ -0,0 +1,25 @@
+# Generated by Django 3.1.3 on 2021-02-24 15:21
+
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('hackathon', '0037_hackathon_teamsize'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='hackathon',
+ name='judges',
+ field=models.ManyToManyField(blank=True, related_name='judged_hackathons', to=settings.AUTH_USER_MODEL),
+ ),
+ migrations.AlterField(
+ model_name='hackathon',
+ name='participants',
+ field=models.ManyToManyField(blank=True, related_name='participated_hackathons', to=settings.AUTH_USER_MODEL),
+ ),
+ ]
diff --git a/hackathon/models.py b/hackathon/models.py
index 1d4745eb..d791bb82 100644
--- a/hackathon/models.py
+++ b/hackathon/models.py
@@ -39,12 +39,12 @@ class Hackathon(models.Model):
# users could be the judges of more than one Hackathon: Many to Many
judges = models.ManyToManyField(User,
blank=True,
- related_name='hackathon_judges')
+ related_name='judged_hackathons')
# Hackathons can have multiple participants judges and
# users could be participating in more than one Hackathon: Many to Many
participants = models.ManyToManyField(User,
blank=True,
- related_name='hackathon_participants')
+ related_name='participated_hackathons')
# Hackathons can have multiple score categories and score categories
# Can belong to multiple hackahtons: Many to Many
score_categories = models.ManyToManyField(
diff --git a/hackathon/templates/hackathon/hackathon_stats.html b/hackathon/templates/hackathon/hackathon_stats.html
new file mode 100644
index 00000000..3fa3a821
--- /dev/null
+++ b/hackathon/templates/hackathon/hackathon_stats.html
@@ -0,0 +1,74 @@
+{% extends 'base.html' %}
+
+{% block content %}
+
+
+
+
+
+
Hackathon Stats
+
+
+
+
+
+
+
+ User Count: {{ users|length }}
+
+
+
+
+
+
+
+
+
+
+ | Slack Display Name |
+ Email |
+ Current LMS Module |
+ Privileges |
+
+
+
+ {% for user in users %}
+
+ |
+ {{ user.slack_display_name }}
+ |
+
+ {{ user.email }}
+ |
+
+ {{ user.current_lms_module }}
+ |
+
+ {% if user.is_staff and user.is_superuser %}
+ Superuser
+ {% elif user.is_staff %}
+ Staff
+ {% else %}
+ Participant
+ {% endif %}
+ |
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/hackathon/urls.py b/hackathon/urls.py
index 992b7a68..f57205ee 100644
--- a/hackathon/urls.py
+++ b/hackathon/urls.py
@@ -11,6 +11,7 @@
view_hackathon,
update_hackathon_status,
change_awards,
+ hackathon_stats,
)
from teams.views import change_teams
@@ -30,4 +31,5 @@
path("/delete", delete_hackathon,
name="delete_hackathon"),
path('enroll/', enroll_toggle, name='enroll_toggle'),
+ path('stats/', hackathon_stats, name='hackathon_stats'),
]
diff --git a/hackathon/views.py b/hackathon/views.py
index 78b2ae53..c00778a4 100644
--- a/hackathon/views.py
+++ b/hackathon/views.py
@@ -9,6 +9,7 @@
from django.shortcuts import render, get_object_or_404, redirect, reverse
from django.contrib import messages
from django.contrib.auth.decorators import login_required
+from django.contrib.auth import get_user_model
from django.core.paginator import Paginator
from django.http import JsonResponse, HttpResponse
from django.utils import timezone
@@ -533,3 +534,17 @@ def change_awards(request, hack_id):
"An unexpected error occurred. Please try again")
return redirect(reverse('hackathon:awards',
kwargs={'hack_id': hack_id}))
+
+
+@login_required
+def hackathon_stats(request):
+ if not request.user.is_superuser:
+ messages.error(request, 'You do not have access to this page.')
+ return reverse(reverse('hackathon:hackathon-list'))
+
+ hackathons = Hackathon.objects.all().exclude(status='deleted')
+ users = get_user_model().objects.all()
+ return render(request, 'hackathon/hackathon_stats.html', {
+ 'hackathons': hackathons,
+ 'users': users,
+ })
diff --git a/static/css/style.css b/static/css/style.css
index 7ff7c0cb..4ce1e96a 100644
--- a/static/css/style.css
+++ b/static/css/style.css
@@ -612,6 +612,11 @@ img.showcase-image-edit {
max-width: none;
}
+/* Hackathon Stats */
+.hide-row{
+ display:none;
+}
+
/* Media Queries */
@media (max-width:453px) {
diff --git a/static/js/script.js b/static/js/script.js
index b1a5496f..0b9e5d74 100644
--- a/static/js/script.js
+++ b/static/js/script.js
@@ -1,5 +1,6 @@
$(document).ready(function(){
$('.edit-image').click(setUpoadImageType);
+ filterUsersByHackathon();
});
function setUpoadImageType(){
@@ -8,3 +9,44 @@ function setUpoadImageType(){
$('#image-upload-type').val(imageType);
$('#image-upload-identifier').val(identifier);
}
+
+function filterUsersByHackathon(){
+ $('#hackathonFilter').change(function(){
+ let userCount = 0;
+ let elementValue = $(this).val();
+ $('#usersTable tbody tr').each(function(){
+ if(elementValue == '0'){
+ $(this).removeClass('hide-row');
+ userCount++;
+ } else {
+ if($(this).data('hackathons').split(',').includes(elementValue)){
+ $(this).removeClass('hide-row');
+ userCount++;
+ } else {
+ $(this).addClass('hide-row');
+ }
+ }
+ });
+ $('#userCount').text(userCount);
+ });
+
+ $('#downloadUsers').click(function(){
+ let csvContent = '';
+ let rows = $('#usersTable tr:not(.hide-row)');
+ rows.each(function(){
+ let tds = $(this).children();
+ let rowText = [];
+ tds.each(function(){
+ rowText.push($(this).text().trim());
+ });
+ csvContent +=rowText.join(',') + '\n';
+ });
+
+ let link = document.createElement('a')
+ link.id = 'download-csv'
+ link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(csvContent));
+ link.setAttribute('download', 'user-export.csv');
+ document.body.appendChild(link);
+ document.querySelector('#download-csv').click();
+ });
+}
diff --git a/templates/includes/navbar.html b/templates/includes/navbar.html
index 20982328..d519bb8d 100644
--- a/templates/includes/navbar.html
+++ b/templates/includes/navbar.html
@@ -62,6 +62,7 @@
My Profile
{% if user.is_superuser %}
Admin Panel
+ Hackthon Stats
{% endif %}
Logout
{% endif %}