Add custom timedelta filter and styles

This commit is contained in:
Nathan Chapman 2021-02-05 20:32:27 -07:00
parent ec573cafdc
commit 2065c6d1ee
18 changed files with 192 additions and 148 deletions

View File

@ -29,10 +29,9 @@ class Period(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
# def duration(self):
# duration = self.clocked_out - self.clocked_in
# duration_in_s = duration.total_seconds()
# return divmod(duration_in_s, 3600)[0]
@property
def p_duration(self):
return round((self.clocked_out - self.clocked_in).seconds / 3600, 2)
def get_absolute_url(self):
return reverse('period-detail', kwargs={'pk': self.pk})

View File

@ -1,10 +1,9 @@
{% extends 'application.html' %}
{% block content %}
<section class="clockin panel">
<h1>Scan code to clock-in/out</h1>
<section>
<form method="post" action="{% url 'attendance-update' %}">
<form class="clockin__form" method="post" action="{% url 'attendance-update' %}">
{% csrf_token %}
{{ form.as_p }}

View File

@ -1,12 +1,13 @@
<section>
<header>
<h1>{{ user.instructor.department.name }}</h1>
{% load timedelta_filter %}
<article class="instructor">
<section class="instructor__header panel">
<h1 class="instructor__department">{{ user.instructor.department.name }}</h1>
<p>
<a href="">Generate Reports</a>
<a class="instructor__generate-reports" href="">Generate Reports</a>
</p>
</header>
<h3>Active sessions</h3>
<div class="instructor__active_periods">
<h3>Students clocked-in</h3>
<p>
<a class="action-button" href="{% url 'period-create' %}">+ Add new session</a>
</p>
@ -40,8 +41,9 @@
{% endfor %}
</tbody>
</table>
</div>
</section>
<article>
<section class="instructor__attendance_log">
<div>
<h3>Attendance log</h3>
<table>
@ -76,8 +78,8 @@
</tbody>
</table>
</div>
</article>
<article>
</section>
<section class="instructor__total_hours">
<table>
<thead>
<tr>
@ -89,11 +91,12 @@
{% for student in student_list %}
<tr>
<td>{{ student.user.first_name }} {{ student.user.last_name }}</td>
<td>{{ student.total_hours }}</td>
<td>{{ student.total_hours|dimedelta_format }}</td>
</tr>
{% empty %}
<tr><td colspan="2">No periods yet.</td></tr>
{% endfor %}
</tbody>
</table>
</section>
</article>

View File

@ -1,9 +1,11 @@
<section class="student panel">
{% load timedelta_filter %}
<article class="student">
<section class="student__header panel">
<h1 class="student__department">{{ user.student.department.name }}</h1>
{% if user.student.is_clocked_in %}
<div class="student__statusbar status">
<p><span class="status__clocked--clocked-in">You are currently clocked in.</span></p>
<p>
<p class="status__clocked-info">
Clocked in at: <strong>{{ current_period.clocked_in|date:"P" }}</strong><br>
Current sesson: <strong>{{ current_period.clocked_in|timesince }}</strong>
</p>
@ -14,9 +16,10 @@
{% include 'attendance/_student_code.html' with clocked_in=False %}
{% endif %}
</section>
<section class="attendance">
<section class="student__attendance attendance">
<h2 class="attendance__title">Attendance log</h2>
<p class="attendance__total">Total hours for the month: <strong>{{period_total}}</strong><br>
<p class="attendance__total">Total hours for the month: <strong>{{ period_total.total|dimedelta_format:2 }}</strong><br>
<small>(Does not include current session.)</small></p>
{% include 'attendance/_student_periods.html' %}
</section>
</article>

View File

@ -2,11 +2,10 @@
{% load qr_code %}
{% block content %}
<section class="code-detail panel">
<h1>Clock in</h1>
<section class="code_detail">
<p><em>Scan code at clock-in station</em></p>
<span>{% qr_from_text code.qr_code_str size=24 version=2 %}</span>
<span><a class="action-button" href="{% url 'attendance-overview' %}">Done</a></span>
<p class="code-detail__instructions"><em>Scan code at clock-in station</em></p>
<span class="code-detail__qrcode">{% qr_from_text code.qr_code_str size=24 version=2 %}</span>
<span class="code-detail__done"><a class="action-button" href="{% url 'attendance-overview' %}">Done</a></span>
</section>
{% endblock %}

View File

@ -1,10 +1,10 @@
{% extends 'application.html' %}
{% block content %}
<h1>Generate code</h1>
<section>
<form method="post" action="{% url 'code-create' %}">
<section class="code-update panel">
<h1>Generate code</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}

View File

View File

@ -0,0 +1,8 @@
from django import template
register = template.Library()
@register.filter()
def dimedelta_format(value, arg=2):
"""Format timedelta"""
return round((value).seconds / 3600, arg)

View File

@ -27,7 +27,7 @@ class AttendanceOverview(LoginRequiredMixin, TemplateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['user'] = User.objects.get(pk=self.request.user.id)
context['user'] = self.request.user
if hasattr(self.request.user, 'instructor'):
context['student_list'] = Student.objects.filter(
department=self.request.user.instructor.department
@ -36,18 +36,18 @@ class AttendanceOverview(LoginRequiredMixin, TemplateView):
elif hasattr(self.request.user, 'student'):
student = self.request.user.student
# sum all duration fields for student
periods_duration_sum = Period.objects.filter(
context['period_total'] = Period.objects.filter(
student = student
).filter(
clocked_in__year=timezone.now().year
).filter(
clocked_in__month=timezone.now().month
).aggregate(total_duration=Sum('duration'))
).aggregate(total=Sum('duration'))
hours = 0
# Convert to hours floating point
if periods_duration_sum['total_duration'] != None:
hours = round((periods_duration_sum['total_duration'].total_seconds() / 3600), 2)
# hours = 0
# # Convert to hours floating point
# if periods_duration_sum['total_duration'] != None:
# hours = round((periods_duration_sum['total_duration'].total_seconds() / 3600), 2)
context['period_list'] = Period.objects.filter(
student=student
@ -56,7 +56,6 @@ class AttendanceOverview(LoginRequiredMixin, TemplateView):
).filter(
clocked_in__month=timezone.now().month
).order_by('-clocked_in')
context['period_total'] = hours
if student.current_period_id != None:
context['current_period'] = Period.objects.get(pk=student.current_period_id)
return context
@ -141,7 +140,7 @@ class CodeDetailView(LoginRequiredMixin, DetailView):
class CodeUpdateView(LoginRequiredMixin, UpdateView):
model = Code
fields = ['station_number']
template_name = 'attendance/code_update_form.html'
template_name = 'attendance/code_form.html'
def get_success_url(self):
pk = self.kwargs["pk"]

View File

View File

@ -0,0 +1,16 @@
.code-detail {
display: flex;
flex-direction: column;
align-items: center;
&__instructions {
}
&__qrcode {
}
&__done {
margin: 1rem 0;
}
}

View File

@ -51,6 +51,7 @@ input[type=submit],
color: white;
cursor: pointer;
text-decoration: none;
border-radius: 3.75rem;
}
input:focus,

View File

@ -51,7 +51,7 @@ hr {
}
// BLOCK ELEMENTS
main {
main, aside {
max-width: 58rem;
margin: 0 auto;
}

View File

@ -0,0 +1,14 @@
.instructor {
&__active_periods {
}
&__attendance_log {
margin: 0 1rem;
}
&__total_hours {
margin: 0 1rem;
}
}

View File

@ -0,0 +1,3 @@
.messages {
}

View File

@ -1,9 +1,7 @@
.student {
&__header {
display: flex;
justify-content: space-between;
align-items: baseline;
}
&__department {

View File

@ -3,9 +3,11 @@
@import "helpers";
@import "forms";
@import "nav";
@import "messages";
@import "registration";
@import "students";
@import "instructors";
@import "attendance";
@import "periods";
@import "codes";

View File

@ -32,7 +32,7 @@
<aside>
{% if messages %}
<div class="messages">
<div class="messages panel">
{% for message in messages %}
<span {% if message.tags %} class="{{ message.tags }} messages__message"{% endif %}>{{ message }}</span>
{% endfor %}