feat: improve public dashboard
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Luca 2025-05-18 16:00:43 +02:00
parent 2bb564ebce
commit 8e9ef718b8
2 changed files with 61 additions and 52 deletions

View File

@ -3,48 +3,44 @@
{% load qrcode %} {% load qrcode %}
{% block everything %} {% block everything %}
<section class="hero"> <main class="is-flex is-flex-direction-column is-flex-grow-1 is-justify-content-center">
<div class="hero-body"> <section class="hero">
<div class="container has-text-centered"> <div class="hero-body">
<h2 class="title is-2">kontakt &ndash; das Kulturfestival</h2> <div class="container has-text-centered">
<h1 class="title is-1">sucht dich!</h1> <h2 class="title is-1">kontakt &ndash; das Kulturfestival</h2>
<h3 class="title">Schnapp dir deine Helfischicht auf https://helfen.kntkt.de</h3> <h1 class="title is-2">sucht dich!</h1>
</div>
</div> </div>
</div> </section>
</section> <section class="hero is-link is-small">
<section class="hero is-link is-small"> <div class="hero-body">
<div class="hero-body"> <div class="container">
<div class="container"> <div class="level">
<div class="level">
{% for description, value in facts %} {% for description, value in facts %}
<div class="level-item has-text-centered"> <div class="level-item has-text-centered">
<div> <div>
<p class="heading">{{ description }}</p> <p class="heading">{{ description }}</p>
<p class="title">{{ value }}</p> <p class="title">{{ value }}</p>
</div>
</div> </div>
</div>
{% endfor %} {% endfor %}
</div>
</div>
</div>
</section>
<section class="section">
<div class="container">
<h3 class="title">Nächste freie Schichten</h3>
<div class="columns">
{% for shift in next_free_shifts %}
<div class="column has-text-centered is-quarter">
<div class="box">
<div class="content">
<p class="is-size-4">{{ shift.start_at }}</p>
{% url 'shift' shift.pk as shift_url %}
{% qrcode "https://helfen.kntkt.de"|add:shift_url %}
<p class="is-size-4 mt-4">{{ shift.room.name }}</p>
</div>
</div> </div>
</div> </div>
{% endfor %}
</div> </div>
</div> </section>
</section> <section class="hero">
<div class="hero-body">
<div class="container has-text-centered">
<h3 class="title">
Schnapp dir deine Helfischicht!
</h3>
{% url 'shift' shift.pk as shift_url %}
{% qrcode "https://helfen.kntkt.de" %}
<h3 class="title mt-3">
https://helfen.kntkt.de
</h3>
</div>
</div>
</section>
</main>
{% endblock %} {% endblock %}

View File

@ -5,9 +5,12 @@ from django.db import models
from django.db.models import Case, Count, ExpressionWrapper, F, Q, Sum, When from django.db.models import Case, Count, ExpressionWrapper, F, Q, Sum, When
from django.shortcuts import render from django.shortcuts import render
from django.utils import timezone from django.utils import timezone
from dynamic_preferences.registries import global_preferences_registry
from .models import Helper, Shift, ShiftRegistration from .models import Helper, Shift, ShiftRegistration
global_preferences = global_preferences_registry.manager()
def public_dashboard(request): def public_dashboard(request):
facts = [] facts = []
@ -20,9 +23,17 @@ def public_dashboard(request):
room__required_helpers__gt=F("reg_count") room__required_helpers__gt=F("reg_count")
) )
total_work_duration = ShiftRegistration.objects.filter( total_work_duration = (
state=ShiftRegistration.RegState.CHECKED_IN ShiftRegistration.objects.annotate(
).aggregate(sum=Sum("shift__duration"))["sum"] shift__end_at=F("shift__start_at") + F("shift__duration")
)
.filter(
state=ShiftRegistration.RegState.CHECKED_IN,
shift__start_at__gte=global_preferences["helper__event_start_at"],
shift__end_at__lte=global_preferences["helper__event_end_at"],
)
.aggregate(sum=Sum("shift__duration"))["sum"]
)
if total_work_duration: if total_work_duration:
total_work_duration = round(total_work_duration.total_seconds() / 60.0) total_work_duration = round(total_work_duration.total_seconds() / 60.0)
facts.append( facts.append(
@ -32,21 +43,23 @@ def public_dashboard(request):
) )
) )
num_free_shifts = ( free_slots = (
Shift.objects.with_reg_count() Shift.objects.with_reg_count()
.filter(help_wanted, start_at__gte=timezone.now()) .annotate(
.count() end_at=F("start_at") + F("duration"),
free_slots=Case(
When(required_helpers=0, then=F("room__required_helpers")),
default=F("required_helpers"),
)
- F("reg_count"),
)
.filter(end_at__gt=timezone.now(), free_slots__gt=0)
.aggregate(sum=Sum("free_slots"))["sum"]
) )
if num_free_shifts > 0: if free_slots:
facts.append(("Zu übernehmende Schichten", num_free_shifts)) facts.append(("Benötigte Helfis", free_slots))
next_free_shifts = ( context = {"facts": facts}
Shift.objects.with_reg_count()
.filter(help_wanted, start_at__gt=timezone.now())
.order_by("start_at")[:4]
)
context = {"facts": facts, "next_free_shifts": next_free_shifts}
return render(request, "public_dashboard.html", context) return render(request, "public_dashboard.html", context)