Skip to content

Commit

Permalink
Dashboard tab for showing registration history
Browse files Browse the repository at this point in the history
  • Loading branch information
henrikskog committed Aug 20, 2024
1 parent ee318e8 commit 0e79282
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 13 deletions.
13 changes: 13 additions & 0 deletions apps/events/dashboard/views.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import json
from collections import OrderedDict
from datetime import datetime, time, timedelta

from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.contenttypes.models import ContentType
from django.core import serializers
from django.core.exceptions import PermissionDenied
from django.forms.models import modelformset_factory
from django.http import HttpResponse, JsonResponse
Expand All @@ -29,6 +31,7 @@
Attendee,
CompanyEvent,
Event,
EventUserAction,
Reservation,
Reservee,
)
Expand Down Expand Up @@ -324,6 +327,16 @@ def event_details(request, event_id, active_tab="details"):
context["active_tab"] = active_tab
context["form"] = dashboard_forms.CreateEventForm(instance=event, user=request.user)

# History of event for analytics pane
registration_history = EventUserAction.objects.filter(event=event)
print(registration_history)
context["registration_history"] = registration_history
context["registration_history_json"] = json.dumps(

Check warning on line 334 in apps/events/dashboard/views.py

View check run for this annotation

Codecov / codecov/patch

apps/events/dashboard/views.py#L331-L334

Added lines #L331 - L334 were not covered by tests
serializers.serialize("json", registration_history)
)
context["event_registration_start"] = event.attendance_event.registration_start
context["event_registration_end"] = event.attendance_event.registration_end

Check warning on line 338 in apps/events/dashboard/views.py

View check run for this annotation

Codecov / codecov/patch

apps/events/dashboard/views.py#L337-L338

Added lines #L337 - L338 were not covered by tests

extras = {}
if event.is_attendance_event() and event.attendance_event.extras:
for extra in event.attendance_event.extras.all():
Expand Down
26 changes: 13 additions & 13 deletions apps/events/signals.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# from django.db.models.signals import post_delete, post_save
# from django.dispatch import receiver
from django.db.models.signals import post_delete, post_save
from django.dispatch import receiver

# from .models import Attendee, EventUserAction
from .models import Attendee, EventUserAction


# @receiver(signal=post_save, sender=Attendee)
# def handle_payment_relation_status_change(sender, instance: Attendee, **kwargs):
# EventUserAction.objects.create(
# user=instance.user, event=instance.event.event, type="register"
# )
@receiver(signal=post_save, sender=Attendee)
def handle_attendee_creation(sender, instance: Attendee, **kwargs):
EventUserAction.objects.create(
user=instance.user, event=instance.event.event, type="register"
)


# @receiver(signal=post_delete, sender=Attendee)
# def handle_payment_transaction_status_change(sender, instance: Attendee, **kwargs):
# EventUserAction.objects.create(
# user=instance.user, event=instance.event.event, type="unregister"
# )
@receiver(signal=post_delete, sender=Attendee)
def handle_attendee_deletion(sender, instance: Attendee, **kwargs):
EventUserAction.objects.create(
user=instance.user, event=instance.event.event, type="unregister"
)
6 changes: 6 additions & 0 deletions templates/events/dashboard/details.html
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ <h3>{{ event }}</h3>
<li role="presentation">
<a href="#company" aria-controls="company" role="tab" data-toggle="tab">Bedrifter</a>
</li>
<li role="presentation">
<a href="#registration-history" aria-controls="registration-history" role="tab" data-toggle="tab">Påmeldingshistorikk</a>
</li>
</ul>
</div>
</div>
Expand Down Expand Up @@ -145,6 +148,9 @@ <h4 class="panel-title">
{% include "events/dashboard/details/company.html" %}
<div id="add-company-view"></div>
</div>
<div role="tabpanel" class="tab-pane" id="registration-history">
{% include "events/dashboard/details/registration-history.html" %}
</div>
</div>

{% endblock content %}
Expand Down
127 changes: 127 additions & 0 deletions templates/events/dashboard/details/registration-history.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<div class="row">
<div class="col-lg-12" style="position: relative; height:40vh; width:80vw">
<canvas id="attendeesChart"></canvas>
</div>
</div>


{% block js %}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js"></script>
<script>
const registrationHistoryRaw = "{{ registration_history_json|escapejs }}";
const registrationHistory = JSON.parse(JSON.parse(registrationHistoryRaw));

// history type:
/*
[{
"model": "events.eventuseraction",
"pk": 1,
"fields": {
"timestamp": "2024-08-20T13:52:55.391Z",
"type": "register",
"user": 1
}
}, ...]
*/

const eventRegistrationStart = new Date("{{ event_registration_start|safe }}");
const eventRegistrationEnd = new Date("{{ event_registration_end|safe }}");

const daysWithTotal = (raw) => {
const base = [{timestamp: eventRegistrationStart, total: 0}];
const end = new Date(Math.min(new Date(), eventRegistrationEnd));
const days = Math.floor((end - eventRegistrationStart) / (1000 * 60 * 60 * 24));

const daysWithTotal = [];
for (let i = 0; i <= days; i++) {
let totalForDay = 0;
const day = new Date(eventRegistrationStart);
day.setDate(day.getDate() + i);

// set time to 23:59:59
day.setHours(23, 59, 59);

for (let j = 0; j < raw.length; j++) {
const actionDate = new Date(raw[j].fields.timestamp);
if (actionDate <= day) {
totalForDay += raw[j].fields.type === 'register' ? 1 : -1;
}
}

daysWithTotal.push({ timestamp: day, total: totalForDay });
}

return daysWithTotal;
}

const totalRegistrationsPerDay = daysWithTotal(registrationHistory);

// plot total registrations over time using chart.js
const ctx = document.getElementById('attendeesChart').getContext('2d');
const chart = new Chart(ctx, {
type: 'line',
data: {
// extract day from timestamp
labels: totalRegistrationsPerDay.map((action, i) => action.timestamp.toLocaleDateString().split('T')[0]),
datasets: [{
label: 'Registrations',
data: totalRegistrationsPerDay.map(action => action.total),
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
// responsive: false,
plugins: {
tooltip: {
callbacks: {
label: function(context) {
const index = context.dataIndex;
const action = totalRegistrationsPerDay[index];
return `Total: ${action.total}, Timestamp: ${action.timestamp.toLocaleString()}`;
}
}
}
}
}
});

// render
chart.render();
</script>
{% endblock %}

<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Historikk</h3>
</div>
<div class="panel-body">
<div id="attendees-content">
<table class="table table-striped table-condensed tablesorter attendees" id="attendees-table">
<thead>
<tr>
<th>#</th>
<th>Tidspunkt</th>
<th>Registrert årstall for bruker</th>
<th>Handling</th>
</tr>
</thead>
<tbody id="attendeelist">
{% for registration in registration_history reversed %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ registration.timestamp }}</td>
<td>{{ registration.user.year }}</td>
<td>{{ registration.type }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>

0 comments on commit 0e79282

Please sign in to comment.