Change templates, update timedelta filter

This commit is contained in:
Nathan Chapman 2021-02-05 23:05:16 -07:00
parent 2065c6d1ee
commit ee472fb9a0
14 changed files with 111 additions and 75 deletions

View File

@ -1,12 +1,15 @@
{% extends 'application.html' %}
{% load timedelta_filter %}
{% block content %}
<h1>User</h1>
<section>
<h3>{{ user.first_name }} {{ user.last_name }}</h3>
<p>{{ user.email }}</p>
<p>
<a href="{% url 'account-update' user.id %}">Update</a>
</p>
</section>
<section class="panel">
<h1>{{ user.first_name }} {{ user.last_name }}</h1>
<p>{{ user.email }}</p>
{% if periods %}
<p>Total clocked hours: <strong>{{ periods.total|timedelta_format }}</strong></p>
{% endif %}
<p>
<a href="{% url 'account-update' user.id %}">Update</a>
</p>
</section>
{% endblock %}

View File

@ -1,15 +1,24 @@
{% extends 'application.html' %}
{% block content %}
<h1>Users</h1>
<section>
<section class="panel">
<h1>Users</h1>
<table>
<thead>
<th>Username</th>
<th>Name</th>
<th>Role</th>
</thead>
<tbody>
{% for user in user_list %}
<tr>
<td>{{ user.username }}</td>
<td>{{user.first_name}} {{user.last_name}}</td>
<td><a href="{% url 'account-detail' user.id %}">Update</a></td>
<td><a href="{% url 'account-detail' user.id %}">{{user.first_name}} {{user.last_name}}</a></td>
{% if user.student %}
<td>Student</td>
{% elif user.instructor %}
<td>Instructor</td>
{% endif %}
</tr>
{% empty %}
<tr><td>No users yet.</td></tr>

View File

@ -1,5 +1,6 @@
import pytz
from django.shortcuts import render, reverse, redirect
from django.db.models import Avg, Count, Min, Sum
from django.urls import reverse_lazy
from django.views.generic.edit import FormView, CreateView, UpdateView, DeleteView
from django.views.generic.detail import DetailView
@ -8,6 +9,7 @@ from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
from django.contrib.auth.forms import PasswordChangeForm
from attendance.models import Period
def set_timezone(request):
if request.method == 'POST':
@ -29,6 +31,14 @@ class AccountDetailView(LoginRequiredMixin, DetailView):
model = User
template_name = 'accounts/account_detail.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if hasattr(context['object'], 'student'):
context['periods'] = Period.objects.filter(
student = context['object'].student
).aggregate(total=Sum('duration'))
return context
class AccountUpdateView(LoginRequiredMixin, UpdateView):
model = User
# form_class = PasswordChangeForm

View File

@ -1,21 +1,17 @@
{% if user.student.code_set.last %}
<p class="student__code code">
<a class="code__button action-button" href="{% url 'code-update' user.student.code_set.last.id %}">
{% if clocked_in %}
Clock out →
{% else %}
Clock in →
{% endif %}
</a>
</p>
<a class="code__button action-button" href="{% url 'code-update' user.student.code_set.last.id %}">
{% if clocked_in %}
Clock out →
{% else %}
Clock in →
{% endif %}
</a>
{% else %}
<p class="student__code code">
<a class="action-button" href="{% url 'code-create' %}">
{% if clocked_in %}
Clock out →
{% else %}
Clock in →
{% endif %}
</a>
</p>
<a class="action-button" href="{% url 'code-create' %}">
{% if clocked_in %}
Clock out →
{% else %}
Clock in →
{% endif %}
</a>
{% endif %}

View File

@ -2,15 +2,10 @@
<article class="instructor">
<section class="instructor__header panel">
<h1 class="instructor__department">{{ user.instructor.department.name }}</h1>
<p>
<a class="instructor__generate-reports" href="">Generate Reports</a>
</p>
</header>
<div class="instructor__active_periods">
<h3>Students clocked-in</h3>
<p>
<a class="action-button" href="{% url 'period-create' %}">+ Add new session</a>
</p>
<a class="action-button instructor__add_period" href="{% url 'period-create' %}">+ Add new session</a>
<table>
<thead>
<tr>
@ -46,6 +41,7 @@
<section class="instructor__attendance_log">
<div>
<h3>Attendance log</h3>
<a class="instructor__generate_reports action-button" href="">Generate Reports</a>
<table>
<thead>
<tr>
@ -80,23 +76,24 @@
</div>
</section>
<section class="instructor__total_hours">
<h3>Total hours</h3>
<table>
<thead>
<thead>
<tr>
<th>Student</th>
<th>Total hours</th>
</tr>
</thead>
<tbody>
{% for student in student_list %}
<tr>
<th>Student</th>
<th>Total hours</th>
<td>{{ student.user.first_name }} {{ student.user.last_name }}</td>
<td><strong>{{ student.total_hours|timedelta_format }}</strong></td>
</tr>
</thead>
<tbody>
{% for student in student_list %}
<tr>
<td>{{ student.user.first_name }} {{ student.user.last_name }}</td>
<td>{{ student.total_hours|dimedelta_format }}</td>
</tr>
{% empty %}
<tr><td colspan="2">No periods yet.</td></tr>
{% endfor %}
</tbody>
</table>
{% empty %}
<tr><td colspan="2">No periods yet.</td></tr>
{% endfor %}
</tbody>
</table>
</section>
</article>

View File

@ -12,13 +12,15 @@
</div>
{% include 'attendance/_student_code.html' with clocked_in=True %}
{% else %}
<div class="status__clocked"></div>You are not clocked in.</p>
{% include 'attendance/_student_code.html' with clocked_in=False %}
<div class="status__clocked">
<p>You are not clocked in.</p>
{% include 'attendance/_student_code.html' with clocked_in=False %}
</div>
{% endif %}
</section>
<section class="student__attendance attendance">
<h2 class="attendance__title">Attendance log</h2>
<p class="attendance__total">Total hours for the month: <strong>{{ period_total.total|dimedelta_format:2 }}</strong><br>
<p class="attendance__total">Total hours for the month: <strong>{{ period_total.total|timedelta_format:2 }}</strong><br>
<small>(Does not include current session.)</small></p>
{% include 'attendance/_student_periods.html' %}
</section>

View File

@ -3,9 +3,8 @@
{% block content %}
<section class="code-detail panel">
<h1>Clock in</h1>
<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>
<h1>Scan code</h1>
<span class="code-detail__qrcode">{% qr_from_text code.qr_code_str size=18 version=2 %}</span>
<a class="code-detail__done action-button" href="{% url 'attendance-overview' %}">Done</a>
</section>
{% endblock %}

View File

@ -1,15 +1,15 @@
{% extends 'application.html' %}
{% block content %}
<h1>Generate Period</h1>
<section>
<section class="period panel">
<h1>Generate Period</h1>
<form method="post" action="">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save changes" /> or
<a href="{{request.META.HTTP_REFERER}}">Cancel</a>
<a href="{% url 'attendance-overview' %}">Cancel</a>
</form>
</section>
{% endblock %}

View File

@ -3,6 +3,10 @@ from django import template
register = template.Library()
@register.filter()
def dimedelta_format(value, arg=2):
"""Format timedelta"""
return round((value).seconds / 3600, arg)
def timedelta_format(value, arg=2):
"""Returns timedelta as float rounded to arg, with default of 2"""
if value.days:
return round((value.days*24) + value.seconds/3600, arg)
elif value.seconds:
return round(value.seconds/3600, arg)
return 0

View File

@ -29,12 +29,16 @@ class AttendanceOverview(LoginRequiredMixin, TemplateView):
context = super().get_context_data(**kwargs)
context['user'] = self.request.user
if hasattr(self.request.user, 'instructor'):
instructor = self.request.user.instructor
context['student_list'] = Student.objects.filter(
department=self.request.user.instructor.department
department=instructor
).annotate(total_hours=Sum('period__duration'))
context['period_list'] = Period.objects.order_by('-clocked_in')
elif hasattr(self.request.user, 'student'):
student = self.request.user.student
# sum all duration fields for student
context['period_total'] = Period.objects.filter(
student = student
@ -44,11 +48,6 @@ class AttendanceOverview(LoginRequiredMixin, TemplateView):
clocked_in__month=timezone.now().month
).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)
context['period_list'] = Period.objects.filter(
student=student
).filter(

View File

@ -0,0 +1,14 @@
.clockin {
display: flex;
flex-direction: column;
align-items: center;
&__form {
text-align: center;
input[type=text] {
width: 300px;
}
}
}

View File

@ -45,7 +45,7 @@ textarea {
input[type=submit],
.action-button {
font-weight: 900;
padding: 0.5em 1em;
padding: 0.2rem 1rem;
border: none;
background-color: $blue;
color: white;
@ -91,5 +91,8 @@ textarea {
}
.action-button {
// margin-bottom: 1rem;
display: inline-block;
padding: 0.2rem 1rem;
border-radius: 3.75rem;
}

View File

@ -22,7 +22,10 @@
<span class="navbar__logo">BTech Time Tracker</span>
<nav class="navbar__nav nav">
{% if user.is_authenticated %}
<a class="nav__user" href="{% url 'account-update' user.id %}">{{ user.first_name }} {{ user.last_name }}</a> /
<a class="nav__user" href="{% url 'account-detail' user.id %}">{{ user.first_name }} {{ user.last_name }}</a> /
<a href="{% url 'attendance-overview' %}">Attendance</a> /
<a href="{% url 'attendance-update' %}">Clock</a> /
<a href="{% url 'account-list' %}">Users</a> /
<a class="nav__logout" class="logout" href="{% url 'logout' %}">Logout</a>
{% else %}
<a class="nav__login" class="login" href="{% url 'login' %}">Login</a>

View File

@ -8,11 +8,8 @@ class TimezoneMiddleware:
def __call__(self, request):
tzname = request.session.get('django_timezone')
print(tzname)
if tzname:
timezone.activate(pytz.timezone(tzname))
print("tz activated")
else:
timezone.deactivate()
print("tz deactivated")
return self.get_response(request)