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

View File

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

View File

@ -1,5 +1,6 @@
import pytz import pytz
from django.shortcuts import render, reverse, redirect from django.shortcuts import render, reverse, redirect
from django.db.models import Avg, Count, Min, Sum
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.views.generic.edit import FormView, CreateView, UpdateView, DeleteView from django.views.generic.edit import FormView, CreateView, UpdateView, DeleteView
from django.views.generic.detail import DetailView 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.mixins import LoginRequiredMixin
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.auth.forms import PasswordChangeForm from django.contrib.auth.forms import PasswordChangeForm
from attendance.models import Period
def set_timezone(request): def set_timezone(request):
if request.method == 'POST': if request.method == 'POST':
@ -29,6 +31,14 @@ class AccountDetailView(LoginRequiredMixin, DetailView):
model = User model = User
template_name = 'accounts/account_detail.html' 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): class AccountUpdateView(LoginRequiredMixin, UpdateView):
model = User model = User
# form_class = PasswordChangeForm # form_class = PasswordChangeForm

View File

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

View File

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

View File

@ -12,13 +12,15 @@
</div> </div>
{% include 'attendance/_student_code.html' with clocked_in=True %} {% include 'attendance/_student_code.html' with clocked_in=True %}
{% else %} {% else %}
<div class="status__clocked"></div>You are not clocked in.</p> <div class="status__clocked">
{% include 'attendance/_student_code.html' with clocked_in=False %} <p>You are not clocked in.</p>
{% include 'attendance/_student_code.html' with clocked_in=False %}
</div>
{% endif %} {% endif %}
</section> </section>
<section class="student__attendance attendance"> <section class="student__attendance attendance">
<h2 class="attendance__title">Attendance log</h2> <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> <small>(Does not include current session.)</small></p>
{% include 'attendance/_student_periods.html' %} {% include 'attendance/_student_periods.html' %}
</section> </section>

View File

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

View File

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

View File

@ -3,6 +3,10 @@ from django import template
register = template.Library() register = template.Library()
@register.filter() @register.filter()
def dimedelta_format(value, arg=2): def timedelta_format(value, arg=2):
"""Format timedelta""" """Returns timedelta as float rounded to arg, with default of 2"""
return round((value).seconds / 3600, arg) 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 = super().get_context_data(**kwargs)
context['user'] = self.request.user context['user'] = self.request.user
if hasattr(self.request.user, 'instructor'): if hasattr(self.request.user, 'instructor'):
instructor = self.request.user.instructor
context['student_list'] = Student.objects.filter( context['student_list'] = Student.objects.filter(
department=self.request.user.instructor.department department=instructor
).annotate(total_hours=Sum('period__duration')) ).annotate(total_hours=Sum('period__duration'))
context['period_list'] = Period.objects.order_by('-clocked_in') context['period_list'] = Period.objects.order_by('-clocked_in')
elif hasattr(self.request.user, 'student'): elif hasattr(self.request.user, 'student'):
student = self.request.user.student student = self.request.user.student
# sum all duration fields for student # sum all duration fields for student
context['period_total'] = Period.objects.filter( context['period_total'] = Period.objects.filter(
student = student student = student
@ -44,11 +48,6 @@ class AttendanceOverview(LoginRequiredMixin, TemplateView):
clocked_in__month=timezone.now().month clocked_in__month=timezone.now().month
).aggregate(total=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)
context['period_list'] = Period.objects.filter( context['period_list'] = Period.objects.filter(
student=student student=student
).filter( ).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], input[type=submit],
.action-button { .action-button {
font-weight: 900; font-weight: 900;
padding: 0.5em 1em; padding: 0.2rem 1rem;
border: none; border: none;
background-color: $blue; background-color: $blue;
color: white; color: white;
@ -91,5 +91,8 @@ textarea {
} }
.action-button { .action-button {
// margin-bottom: 1rem;
display: inline-block;
padding: 0.2rem 1rem;
border-radius: 3.75rem; border-radius: 3.75rem;
} }

View File

@ -22,7 +22,10 @@
<span class="navbar__logo">BTech Time Tracker</span> <span class="navbar__logo">BTech Time Tracker</span>
<nav class="navbar__nav nav"> <nav class="navbar__nav nav">
{% if user.is_authenticated %} {% 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> <a class="nav__logout" class="logout" href="{% url 'logout' %}">Logout</a>
{% else %} {% else %}
<a class="nav__login" class="login" href="{% url 'login' %}">Login</a> <a class="nav__login" class="login" href="{% url 'login' %}">Login</a>

View File

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