Merge branch 'develop'
This commit is contained in:
commit
ec573cafdc
3
.gitignore
vendored
3
.gitignore
vendored
@ -251,3 +251,6 @@ dist
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# CACHES
|
||||
CACHE/
|
||||
|
||||
3
Pipfile
3
Pipfile
@ -9,6 +9,9 @@ django-compressor = "*"
|
||||
qrcode = "*"
|
||||
pillow = "*"
|
||||
django-qr-code = "*"
|
||||
pytz = "*"
|
||||
django-easy-timezones = "*"
|
||||
django-libsass = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
|
||||
81
Pipfile.lock
generated
81
Pipfile.lock
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "d1dd018056bda89f00de6e3fbdd88cfa2fc56b756047e88153a4f8e99171e1bb"
|
||||
"sha256": "fa23d606797893ecd178aaeda5c8301bcff6f72d7b79fcdb1bf4947207b7a9bc"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@ -26,11 +26,11 @@
|
||||
},
|
||||
"django": {
|
||||
"hashes": [
|
||||
"sha256:2d78425ba74c7a1a74b196058b261b9733a8570782f4e2828974777ccca7edf7",
|
||||
"sha256:efa2ab96b33b20c2182db93147a0c3cd7769d418926f9e9f140a60dca7c64ca9"
|
||||
"sha256:169e2e7b4839a7910b393eec127fd7cbae62e80fa55f89c6510426abf673fe5f",
|
||||
"sha256:c6c0462b8b361f8691171af1fb87eceb4442da28477e12200c40420176206ba7"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.1.5"
|
||||
"version": "==3.1.6"
|
||||
},
|
||||
"django-appconf": {
|
||||
"hashes": [
|
||||
@ -47,6 +47,22 @@
|
||||
"index": "pypi",
|
||||
"version": "==2.4"
|
||||
},
|
||||
"django-easy-timezones": {
|
||||
"hashes": [
|
||||
"sha256:1c90f8a9731bf0762b6c7d239beb5b9434f45e8c9bbdc3586faa69851d00c434",
|
||||
"sha256:d28a5e60263de39eeef72240dac01090a11f7212d942dfbd3b4ba4be7b2bf77e"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.8.0"
|
||||
},
|
||||
"django-libsass": {
|
||||
"hashes": [
|
||||
"sha256:38fab4ce1245542f3afd7248dc48f8a0b261f5f6c61e7cc43969a9c9079b5ffd",
|
||||
"sha256:3e74fd8e75ac0e6ebc0443efc3e530167981bf279fecc2294094c820ae266fbb"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.8"
|
||||
},
|
||||
"django-qr-code": {
|
||||
"hashes": [
|
||||
"sha256:5fdd84f4c02127c262e6987bd1a9396a47f2b806be04aa0bebfcb786a9f6a0b7",
|
||||
@ -55,6 +71,31 @@
|
||||
"index": "pypi",
|
||||
"version": "==2.1.0"
|
||||
},
|
||||
"ipaddress": {
|
||||
"hashes": [
|
||||
"sha256:5a3182b322a706525c46282ca6f064d27a02cffbd449f9f47416f1dc96aa71b0",
|
||||
"sha256:935712800ce4760701d89ad677666cd52691fd2f6f0b340c8b4239a3c17988a5"
|
||||
],
|
||||
"version": "==1.0.16"
|
||||
},
|
||||
"libsass": {
|
||||
"hashes": [
|
||||
"sha256:1521d2a8d4b397c6ec90640a1f6b5529077035efc48ef1c2e53095544e713d1b",
|
||||
"sha256:1b2d415bbf6fa7da33ef46e549db1418498267b459978eff8357e5e823962d35",
|
||||
"sha256:25ebc2085f5eee574761ccc8d9cd29a9b436fc970546d5ef08c6fa41eb57dff1",
|
||||
"sha256:2ae806427b28bc1bb7cb0258666d854fcf92ba52a04656b0b17ba5e190fb48a9",
|
||||
"sha256:4a246e4b88fd279abef8b669206228c92534d96ddcd0770d7012088c408dff23",
|
||||
"sha256:553e5096414a8d4fb48d0a48f5a038d3411abe254d79deac5e008516c019e63a",
|
||||
"sha256:697f0f9fa8a1367ca9ec6869437cb235b1c537fc8519983d1d890178614a8903",
|
||||
"sha256:a8fd4af9f853e8bf42b1425c5e48dd90b504fa2e70d7dac5ac80b8c0a5a5fe85",
|
||||
"sha256:c9411fec76f480ffbacc97d8188322e02a5abca6fc78e70b86a2a2b421eae8a2",
|
||||
"sha256:daa98a51086d92aa7e9c8871cf1a8258124b90e2abf4697852a3dca619838618",
|
||||
"sha256:e0e60836eccbf2d9e24ec978a805cd6642fa92515fbd95e3493fee276af76f8a",
|
||||
"sha256:e64ae2587f1a683e831409aad03ba547c245ef997e1329fffadf7a866d2510b8",
|
||||
"sha256:f6852828e9e104d2ce0358b73c550d26dd86cc3a69439438c3b618811b9584f5"
|
||||
],
|
||||
"version": "==0.20.1"
|
||||
},
|
||||
"pillow": {
|
||||
"hashes": [
|
||||
"sha256:165c88bc9d8dba670110c689e3cc5c71dbe4bfb984ffa7cbebf1fac9554071d6",
|
||||
@ -93,12 +134,31 @@
|
||||
"index": "pypi",
|
||||
"version": "==8.1.0"
|
||||
},
|
||||
"pygeoip": {
|
||||
"hashes": [
|
||||
"sha256:1938b9dac7b00d77f94d040b9465ea52c938f3fcdcd318b5537994f3c16aef96",
|
||||
"sha256:f22c4e00ddf1213e0fae36dc60b46ee7c25a6339941ec1a975539014c1f9a96d"
|
||||
],
|
||||
"version": "==0.3.2"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4",
|
||||
"sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5"
|
||||
"sha256:0ca2c5966a10e8044db98bac372ed238f323d8d526bbd9a601c3520b98a4bbd3",
|
||||
"sha256:1ce2d13b6503a7260c950a25fa6d26ba8d4da1a7077e062aa9e82c74949aaf4b",
|
||||
"sha256:35b5a38d6ffda82220a9e6b97b7b7162887b2d7ff82a1b601979e60d13062718",
|
||||
"sha256:4e9d04cb71d5db26123a1602eb402dab9a7b3686e2786d1e170858e31b59850f",
|
||||
"sha256:51ee2cbb7309df4c2f7c1d2c418aeb869ad48928ed590da7689c034dda7c912f",
|
||||
"sha256:58f594447ca62397c7be6c40fc9406c1d60836cb40974f279058062e58752cea",
|
||||
"sha256:62fd4e22635f609cf1f5da3037612214758ff5f510f4e877ec31d3bbbb995802",
|
||||
"sha256:7dd7accd1690ed32fbd90ad9d273c84e8e09178cdc190b195347d27daebd40df",
|
||||
"sha256:8eba058ab00830a8e3c0a8b81fe5d7b367f0fd18277c94afc9d674a99eae5d42",
|
||||
"sha256:937f30580a1ef85c28fea2672871c2e3df9a22fb9070bc77c20d26ab99ea6369",
|
||||
"sha256:b1f51ed44fe5c25f088bc8c7c189060dc1258b157b5bb6d46d08cc033fca6d1a",
|
||||
"sha256:de72bec3c2f2c86bea4c0c83a921031613976b05ff7f14e1bae1149f177b7746",
|
||||
"sha256:f25c9941d5e80865bfab0f49627e7e199e81ac2f47497b19bebb498dc494b7c9"
|
||||
],
|
||||
"version": "==2020.5"
|
||||
"index": "pypi",
|
||||
"version": "==2016.6"
|
||||
},
|
||||
"qrcode": {
|
||||
"hashes": [
|
||||
@ -155,6 +215,13 @@
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==0.4.1"
|
||||
},
|
||||
"wheel": {
|
||||
"hashes": [
|
||||
"sha256:1ebb8ad7e26b448e9caa4773d2357849bf80ff9e313964bcaf79cbf0201a1648",
|
||||
"sha256:ea8033fc9905804e652f75474d33410a07404c1a78dd3c949a66863bd1050ebd"
|
||||
],
|
||||
"version": "==0.29.0"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
|
||||
@ -14,6 +14,7 @@ class Department(models.Model):
|
||||
class Instructor(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
department = models.ForeignKey(Department, on_delete=models.CASCADE)
|
||||
timezone = models.CharField(max_length=20)
|
||||
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
@ -30,6 +31,7 @@ class Student(models.Model):
|
||||
department = models.ForeignKey(Department, on_delete=models.CASCADE)
|
||||
is_clocked_in = models.BooleanField(default=False)
|
||||
current_period_id = models.IntegerField(blank=True, null=True)
|
||||
timezone = models.CharField(max_length=20)
|
||||
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
|
||||
@ -1,19 +1,20 @@
|
||||
{% extends 'application.html' %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Update User</h1>
|
||||
<section class="panel test">
|
||||
<h1>Update User</h1>
|
||||
|
||||
<section>
|
||||
<h3>{{ user.first_name }} {{ user.last_name }}</h3>
|
||||
{% if user.student %}
|
||||
<p>Student ID: {{user.student.student_number}}</p>
|
||||
{% endif %}
|
||||
<p><a href="{% url 'password_change' %}">Change password</a></p>
|
||||
<form method="post" action="{% url 'account-update' user.id %}">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
|
||||
<input type="submit" value="Save changes" />
|
||||
<input type="submit" value="Save changes"> or
|
||||
<a href="{% url 'account-detail' user.id %}">Cancel</a>
|
||||
</form>
|
||||
<p><a href="{% url 'password_change' %}">Change password</a></p>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
23
accounts/templates/accounts/timezone.html
Normal file
23
accounts/templates/accounts/timezone.html
Normal file
@ -0,0 +1,23 @@
|
||||
{% extends 'application.html' %}
|
||||
{% load tz %}
|
||||
{% get_current_timezone as TIME_ZONE %}
|
||||
|
||||
{% block content %}
|
||||
<section class="panel">
|
||||
<h1>Set timezone</h1>
|
||||
<form action="{% url 'set_timezone' %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<p>
|
||||
<label for="timezone">Please select your timezone:</label><br>
|
||||
<select name="timezone">
|
||||
{% for tz in timezones %}
|
||||
<option value="{{ tz }}"{% if tz == TIME_ZONE %} selected{% elif tz == 'US/Mountain' %} selected{% endif %}>{{ tz }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<input type="submit" value="Set timezone">
|
||||
</p>
|
||||
</form>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@ -1,13 +1,14 @@
|
||||
from django.urls import include, path
|
||||
from . import views
|
||||
|
||||
# list/ /users/
|
||||
# create/ /users/new/
|
||||
# detail/ /users/1/
|
||||
# update/ /users/1/update/ (update shift preferences)
|
||||
# delete/ /users/1/delete/
|
||||
# list/ /accounts/
|
||||
# create/ /accounts/new/
|
||||
# detail/ /accounts/1/
|
||||
# update/ /accounts/1/update/
|
||||
# delete/ /accounts/1/delete/
|
||||
|
||||
urlpatterns = [
|
||||
path('timezone/', views.set_timezone, name='set_timezone'),
|
||||
path('', views.AccountListView.as_view(), name='account-list'),
|
||||
path('new/', views.AccountCreateView.as_view(), name='account-create'),
|
||||
path('<int:pk>/', include([
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
from django.shortcuts import render, reverse
|
||||
import pytz
|
||||
from django.shortcuts import render, reverse, redirect
|
||||
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,13 @@ from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.forms import PasswordChangeForm
|
||||
|
||||
def set_timezone(request):
|
||||
if request.method == 'POST':
|
||||
request.session['django_timezone'] = request.POST['timezone']
|
||||
return redirect('attendance-overview')
|
||||
else:
|
||||
return render(request, 'accounts/timezone.html', {'timezones': pytz.common_timezones})
|
||||
|
||||
class AccountListView(LoginRequiredMixin, ListView):
|
||||
model = User
|
||||
template_name = 'accounts/account_list.html'
|
||||
|
||||
21
attendance/templates/attendance/_student_code.html
Normal file
21
attendance/templates/attendance/_student_code.html
Normal file
@ -0,0 +1,21 @@
|
||||
{% 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>
|
||||
{% 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>
|
||||
{% endif %}
|
||||
29
attendance/templates/attendance/_student_periods.html
Normal file
29
attendance/templates/attendance/_student_periods.html
Normal file
@ -0,0 +1,29 @@
|
||||
<table class="attendance__log">
|
||||
<caption class="attendance__month">{% now "F Y" %}</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Station</th>
|
||||
<th>Clocked in</th>
|
||||
<th>Clocked out</th>
|
||||
<th>Duration</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for period in period_list %}
|
||||
{% if period.clocked_out %}
|
||||
<tr>
|
||||
<td>{{ period.station_number }}</td>
|
||||
<td>{{ period.clocked_in }}</td>
|
||||
{% if period.clocked_out %}
|
||||
<td>{{ period.clocked_out }}</td>
|
||||
<td>{{ period.clocked_in|timesince:period.clocked_out }}</td>
|
||||
{% else %}
|
||||
<td colspan="2">Current sesson: {{ period.clocked_in|timesince }}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<tr><td colspan="2">No periods yet.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
@ -1,4 +1,3 @@
|
||||
{% load l10n %}
|
||||
<section>
|
||||
<header>
|
||||
<h1>{{ user.instructor.department.name }}</h1>
|
||||
@ -9,7 +8,7 @@
|
||||
|
||||
<h3>Active sessions</h3>
|
||||
<p>
|
||||
<a href="{% url 'period-create' %}">+ Add new session</a>
|
||||
<a class="action-button" href="{% url 'period-create' %}">+ Add new session</a>
|
||||
</p>
|
||||
<table>
|
||||
<thead>
|
||||
@ -26,9 +25,9 @@
|
||||
<tr>
|
||||
<td>{{ period.student }}</td>
|
||||
<td>{{ period.station_number }}</td>
|
||||
<td>{{ period.clocked_in|localize }}</td>
|
||||
<td>{{ period.clocked_in }}</td>
|
||||
{% if period.clocked_out %}
|
||||
<td>{{ period.clocked_out|localize }}</td>
|
||||
<td>{{ period.clocked_out }}</td>
|
||||
<td>{{ period.clocked_in|timesince:period.clocked_out }}</td>
|
||||
{% else %}
|
||||
<td>Current sesson: {{ period.clocked_in|timesince }}</td>
|
||||
@ -61,9 +60,9 @@
|
||||
<tr>
|
||||
<td>{{ period.student }}</td>
|
||||
<td>{{ period.station_number }}</td>
|
||||
<td>{{ period.clocked_in|localize }}</td>
|
||||
<td>{{ period.clocked_in }}</td>
|
||||
{% if period.clocked_out %}
|
||||
<td>{{ period.clocked_out|localize }}</td>
|
||||
<td>{{ period.clocked_out }}</td>
|
||||
<td>{{ period.clocked_in|timesince:period.clocked_out }}</td>
|
||||
{% else %}
|
||||
<td colspan="2">Current sesson: {{ period.clocked_in|timesince }}</td>
|
||||
|
||||
@ -1,55 +1,22 @@
|
||||
<section>
|
||||
<header class="header">
|
||||
<h1>{{ user.first_name }} {{ user.last_name }}</h1>
|
||||
<a href="{% url 'account-update' user.id %}">Update profile</a>
|
||||
</header>
|
||||
<h5>{{ user.student.department.name }}</h5>
|
||||
{% if user.student.is_clocked_in and user.student.code_set.last %}
|
||||
<p>You are currently clocked in.<br>
|
||||
Current sesson: {{ current_period.clocked_in|timesince }}</p>
|
||||
<a href="{% url 'code-update' user.student.code_set.last.id %}">Clock out →</a>
|
||||
{% elif user.student.is_clocked_in and not user.student.code_set.last %}
|
||||
<p><span class="message info">You are currently clocked in.</span><br>
|
||||
Current sesson: <strong>{{ current_period.clocked_in|timesince }}</strong></p>
|
||||
<a href="{% url 'code-create' %}">Clock out →</a>
|
||||
{% elif user.student.code_set.last %}
|
||||
<p>You are not clocked in.</p>
|
||||
<a href="{% url 'code-update' user.student.code_set.last.id %}">Clock in →</a>
|
||||
<section class="student 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>
|
||||
Clocked in at: <strong>{{ current_period.clocked_in|date:"P" }}</strong><br>
|
||||
Current sesson: <strong>{{ current_period.clocked_in|timesince }}</strong>
|
||||
</p>
|
||||
</div>
|
||||
{% include 'attendance/_student_code.html' with clocked_in=True %}
|
||||
{% else %}
|
||||
<p>You are not clocked in.</p>
|
||||
<a href="{% url 'code-create' %}">Clock in →</a>
|
||||
<div class="status__clocked"></div>You are not clocked in.</p>
|
||||
{% include 'attendance/_student_code.html' with clocked_in=False %}
|
||||
{% endif %}
|
||||
</section>
|
||||
<article>
|
||||
<h2>Attendance log</h2>
|
||||
<p>Total hours for the month: {{period_total}}<br>
|
||||
<section class="attendance">
|
||||
<h2 class="attendance__title">Attendance log</h2>
|
||||
<p class="attendance__total">Total hours for the month: <strong>{{period_total}}</strong><br>
|
||||
<small>(Does not include current session.)</small></p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Station</th>
|
||||
<th>Clocked in</th>
|
||||
<th>Clocked out</th>
|
||||
<th>Duration</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for period in period_list %}
|
||||
{% if period.clocked_out %}
|
||||
<tr>
|
||||
<td>{{ period.station_number }}</td>
|
||||
<td>{{ period.clocked_in|localize }}</td>
|
||||
{% if period.clocked_out %}
|
||||
<td>{{ period.clocked_out|localize }}</td>
|
||||
<td>{{ period.clocked_in|timesince:period.clocked_out }}</td>
|
||||
{% else %}
|
||||
<td colspan="2">Current sesson: {{ period.clocked_in|timesince }}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<tr><td colspan="2">No periods yet.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</article>
|
||||
{% include 'attendance/_student_periods.html' %}
|
||||
</section>
|
||||
|
||||
@ -4,11 +4,9 @@
|
||||
{% block content %}
|
||||
<h1>Clock in</h1>
|
||||
|
||||
<section>
|
||||
<p>
|
||||
{% qr_from_text code.qr_code_str size=24 version=2 %}
|
||||
</p>
|
||||
<section class="code_detail">
|
||||
<p><em>Scan code at clock-in station</em></p>
|
||||
<a href="{% url 'attendance-overview' %}">Done</a>
|
||||
<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>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
@ -44,8 +44,6 @@ class AttendanceOverview(LoginRequiredMixin, TemplateView):
|
||||
clocked_in__month=timezone.now().month
|
||||
).aggregate(total_duration=Sum('duration'))
|
||||
|
||||
print(periods_duration_sum)
|
||||
print(timezone.now().month)
|
||||
hours = 0
|
||||
# Convert to hours floating point
|
||||
if periods_duration_sum['total_duration'] != None:
|
||||
|
||||
@ -62,6 +62,7 @@ hr {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.header {
|
||||
@ -104,13 +105,23 @@ label {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
select {
|
||||
text-align: left;
|
||||
border: 4px solid #bdc3c7;
|
||||
padding: 0.5em;
|
||||
outline: 0;
|
||||
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
input[type=text],
|
||||
input[type=email],
|
||||
input[type=number],
|
||||
input[type=password],
|
||||
select[multiple=multiple],
|
||||
textarea,
|
||||
.action-button,
|
||||
.datepickr {
|
||||
text-align: left;
|
||||
color: #2c3e50;
|
||||
@ -178,6 +189,10 @@ textarea {
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
article {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
|
||||
section {
|
||||
padding: 1em;
|
||||
@ -212,9 +227,31 @@ th {
|
||||
border-color: #bdc3c7;
|
||||
}
|
||||
|
||||
.action-button {
|
||||
|
||||
font-weight: 900;
|
||||
padding: 0.5em 1em;
|
||||
border: none;
|
||||
max-width: 12rem;
|
||||
background-color: #2980B9;
|
||||
color: #ffffff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
|
||||
box-shadow: 0 4px 0 #2980B9;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Messages */
|
||||
.info {color: green;}
|
||||
|
||||
|
||||
.code_detail {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
349
static/css/normalize.css
vendored
Normal file
349
static/css/normalize.css
vendored
Normal file
@ -0,0 +1,349 @@
|
||||
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
|
||||
|
||||
/* Document
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Correct the line height in all browsers.
|
||||
* 2. Prevent adjustments of font size after orientation changes in iOS.
|
||||
*/
|
||||
|
||||
html {
|
||||
line-height: 1.15; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
/* Sections
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the margin in all browsers.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the `main` element consistently in IE.
|
||||
*/
|
||||
|
||||
main {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the font size and margin on `h1` elements within `section` and
|
||||
* `article` contexts in Chrome, Firefox, and Safari.
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
/* Grouping content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in Firefox.
|
||||
* 2. Show the overflow in Edge and IE.
|
||||
*/
|
||||
|
||||
hr {
|
||||
box-sizing: content-box; /* 1 */
|
||||
height: 0; /* 1 */
|
||||
overflow: visible; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
pre {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/* Text-level semantics
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the gray background on active links in IE 10.
|
||||
*/
|
||||
|
||||
a {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Remove the bottom border in Chrome 57-
|
||||
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: none; /* 1 */
|
||||
text-decoration: underline; /* 2 */
|
||||
text-decoration: underline dotted; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font weight in Chrome, Edge, and Safari.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent `sub` and `sup` elements from affecting the line height in
|
||||
* all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
/* Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the border on images inside links in IE 10.
|
||||
*/
|
||||
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
/* Forms
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Change the font styles in all browsers.
|
||||
* 2. Remove the margin in Firefox and Safari.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; /* 1 */
|
||||
font-size: 100%; /* 1 */
|
||||
line-height: 1.15; /* 1 */
|
||||
margin: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the overflow in IE.
|
||||
* 1. Show the overflow in Edge.
|
||||
*/
|
||||
|
||||
button,
|
||||
input { /* 1 */
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inheritance of text transform in Edge, Firefox, and IE.
|
||||
* 1. Remove the inheritance of text transform in Firefox.
|
||||
*/
|
||||
|
||||
button,
|
||||
select { /* 1 */
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the inability to style clickable types in iOS and Safari.
|
||||
*/
|
||||
|
||||
button,
|
||||
[type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inner border and padding in Firefox.
|
||||
*/
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the focus styles unset by the previous rule.
|
||||
*/
|
||||
|
||||
button:-moz-focusring,
|
||||
[type="button"]:-moz-focusring,
|
||||
[type="reset"]:-moz-focusring,
|
||||
[type="submit"]:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the padding in Firefox.
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
padding: 0.35em 0.75em 0.625em;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the text wrapping in Edge and IE.
|
||||
* 2. Correct the color inheritance from `fieldset` elements in IE.
|
||||
* 3. Remove the padding so developers are not caught out when they zero out
|
||||
* `fieldset` elements in all browsers.
|
||||
*/
|
||||
|
||||
legend {
|
||||
box-sizing: border-box; /* 1 */
|
||||
color: inherit; /* 2 */
|
||||
display: table; /* 1 */
|
||||
max-width: 100%; /* 1 */
|
||||
padding: 0; /* 3 */
|
||||
white-space: normal; /* 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
||||
*/
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the default vertical scrollbar in IE 10+.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in IE 10.
|
||||
* 2. Remove the padding in IE 10.
|
||||
*/
|
||||
|
||||
[type="checkbox"],
|
||||
[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the cursor style of increment and decrement buttons in Chrome.
|
||||
*/
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the odd appearance in Chrome and Safari.
|
||||
* 2. Correct the outline style in Safari.
|
||||
*/
|
||||
|
||||
[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
outline-offset: -2px; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inner padding in Chrome and Safari on macOS.
|
||||
*/
|
||||
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inability to style clickable types in iOS and Safari.
|
||||
* 2. Change font properties to `inherit` in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button; /* 1 */
|
||||
font: inherit; /* 2 */
|
||||
}
|
||||
|
||||
/* Interactive
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Add the correct display in Edge, IE 10+, and Firefox.
|
||||
*/
|
||||
|
||||
details {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the correct display in all browsers.
|
||||
*/
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/* Misc
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 10+.
|
||||
*/
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 10.
|
||||
*/
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
0
static/scss/_codes.scss
Normal file
0
static/scss/_codes.scss
Normal file
94
static/scss/_forms.scss
Normal file
94
static/scss/_forms.scss
Normal file
@ -0,0 +1,94 @@
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
input {
|
||||
text-align: left;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
label {
|
||||
text-align: left;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
select {
|
||||
text-align: left;
|
||||
border: 4px solid $grey;
|
||||
padding: 0.5em;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input[type=text],
|
||||
input[type=email],
|
||||
input[type=number],
|
||||
input[type=password],
|
||||
select[multiple=multiple],
|
||||
textarea {
|
||||
display: block;
|
||||
text-align: left;
|
||||
color: $primary-color;
|
||||
border: 4px solid $grey;
|
||||
padding: 0.5rem;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input[type=submit],
|
||||
.action-button {
|
||||
font-weight: 900;
|
||||
padding: 0.5em 1em;
|
||||
border: none;
|
||||
background-color: $blue;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
textarea:focus {
|
||||
border-color: $blue;
|
||||
}
|
||||
|
||||
select[multiple=multiple] {
|
||||
height: 125px;
|
||||
}
|
||||
|
||||
input[type=number] {
|
||||
max-width: 6.25rem;
|
||||
padding: 0 1rem;
|
||||
// height: 3.32em;
|
||||
}
|
||||
|
||||
input[type=checkbox] {
|
||||
width: 1em;
|
||||
vertical-align: text-top;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 6.25rem;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
::-webkit-input-placeholder {
|
||||
font-style: oblique;
|
||||
}
|
||||
::-moz-input-placeholder {
|
||||
font-style: oblique;
|
||||
}
|
||||
::-ms-input-placeholder {
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
.action-button {
|
||||
border-radius: 3.75rem;
|
||||
}
|
||||
81
static/scss/_globals.scss
Normal file
81
static/scss/_globals.scss
Normal file
@ -0,0 +1,81 @@
|
||||
html {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: $bg-color;
|
||||
color: $primary-color;
|
||||
font-family: 'Lato', sans-serif;
|
||||
font-weight: 400;
|
||||
line-height: 1.75;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
h1, h2, h3, h4, h5 {
|
||||
margin: 3rem 0 1.38rem;
|
||||
font-family: 'Lato', sans-serif;
|
||||
line-height: 1.3;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
h1 {
|
||||
margin-top: 0;
|
||||
font-size: 2.488rem;
|
||||
}
|
||||
h2 {
|
||||
font-size: 2.074rem;
|
||||
}
|
||||
h3 {
|
||||
font-size: 1.728rem;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.44rem;
|
||||
}
|
||||
h5 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
small {
|
||||
font-size: 0.833rem;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $blue;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 0;
|
||||
border: 0.8px solid $grey;
|
||||
}
|
||||
|
||||
// BLOCK ELEMENTS
|
||||
main {
|
||||
max-width: 58rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
||||
// TABLES
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
margin-bottom: 1.3em;
|
||||
border: 1px solid $grey;
|
||||
}
|
||||
|
||||
table a {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
text-align: left;
|
||||
font-size: 0.85em;
|
||||
padding: 2px 10px;
|
||||
border-bottom: 1px solid;
|
||||
border-color: $grey;
|
||||
}
|
||||
14
static/scss/_helpers.scss
Normal file
14
static/scss/_helpers.scss
Normal file
@ -0,0 +1,14 @@
|
||||
.panel {
|
||||
max-width: 58rem;
|
||||
padding: 1rem;
|
||||
background-color: white;
|
||||
border-top: 1px solid $grey;
|
||||
border-bottom: 1px solid $grey;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
@media screen and (min-width: 58rem) {
|
||||
.panel {
|
||||
border: 1px solid $grey;
|
||||
}
|
||||
|
||||
}
|
||||
0
static/scss/_instructors.scss
Normal file
0
static/scss/_instructors.scss
Normal file
27
static/scss/_nav.scss
Normal file
27
static/scss/_nav.scss
Normal file
@ -0,0 +1,27 @@
|
||||
.navbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 1rem;
|
||||
|
||||
&__logo {
|
||||
font-weight: bold;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
&__nav {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.nav {
|
||||
&nav__user {
|
||||
|
||||
}
|
||||
&nav__logout {
|
||||
|
||||
}
|
||||
&nav__login {
|
||||
|
||||
}
|
||||
}
|
||||
0
static/scss/_periods.scss
Normal file
0
static/scss/_periods.scss
Normal file
0
static/scss/_registration.scss
Normal file
0
static/scss/_registration.scss
Normal file
33
static/scss/_students.scss
Normal file
33
static/scss/_students.scss
Normal file
@ -0,0 +1,33 @@
|
||||
.student {
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
&__department {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.status {
|
||||
&__clocked {
|
||||
|
||||
}
|
||||
|
||||
&__clocked--clocked-in {
|
||||
background-color: $green;
|
||||
color: white;
|
||||
padding: 0.5rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.attendance {
|
||||
margin: 0 1rem;
|
||||
|
||||
&__month {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
16
static/scss/_variables.scss
Normal file
16
static/scss/_variables.scss
Normal file
@ -0,0 +1,16 @@
|
||||
/*bg (gray) white
|
||||
primary (black) #323834
|
||||
faded (light-black) #747a7c
|
||||
accent 1 (red) #2980B9
|
||||
accent 2 (orange) #9b6f45
|
||||
accent 3 (blue) #242e34
|
||||
*/
|
||||
|
||||
$bg-color: #f7f7f7;
|
||||
$primary-color: #323834;
|
||||
$faded-color: #747a7c;
|
||||
$blue: #2980B9;
|
||||
$orange: #9b6f45;
|
||||
$darkblue: #242e34;
|
||||
$grey: #bdc3c7;
|
||||
$green: green;
|
||||
11
static/scss/main.scss
Normal file
11
static/scss/main.scss
Normal file
@ -0,0 +1,11 @@
|
||||
@import "variables";
|
||||
@import "globals";
|
||||
@import "helpers";
|
||||
@import "forms";
|
||||
@import "nav";
|
||||
@import "registration";
|
||||
@import "students";
|
||||
@import "instructors";
|
||||
@import "periods";
|
||||
@import "codes";
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
{% load static %}
|
||||
{% load compress %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
@ -10,25 +11,33 @@
|
||||
{% block head %}
|
||||
{% endblock %}
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
|
||||
{% compress css %}
|
||||
<link href="{% static 'css/normalize.css' %}" rel="stylesheet" media="screen">
|
||||
<link type="text/x-scss" href="{% static 'scss/main.scss' %}" rel="stylesheet" media="screen">
|
||||
{% endcompress %}
|
||||
</head>
|
||||
<body>
|
||||
<header class="navigation">
|
||||
<p><strong>BTech Time Tracker</strong></p>
|
||||
<header class="navbar">
|
||||
<span class="navbar__logo">BTech Time Tracker</span>
|
||||
<nav class="navbar__nav nav">
|
||||
{% if user.is_authenticated %}
|
||||
<nav>
|
||||
<a href="{% url 'account-update' user.id %}">{{ user.first_name }} {{ user.last_name }}</a> /
|
||||
<a class="logout" href="{% url 'logout' %}">Logout</a>
|
||||
</nav>
|
||||
<a class="nav__user" href="{% url 'account-update' user.id %}">{{ user.first_name }} {{ user.last_name }}</a> /
|
||||
<a class="nav__logout" class="logout" href="{% url 'logout' %}">Logout</a>
|
||||
{% else %}
|
||||
<nav>
|
||||
<a class="login" href="{% url 'login' %}">Login</a>
|
||||
</nav>
|
||||
<a class="nav__login" class="login" href="{% url 'login' %}">Login</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<aside>
|
||||
{% if messages %}
|
||||
<div class="messages">
|
||||
{% for message in messages %}
|
||||
<span {% if message.tags %} class="{{ message.tags }} messages__message"{% endif %}>{{ message }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% block aside %}
|
||||
{% endblock %}
|
||||
</aside>
|
||||
@ -36,13 +45,6 @@
|
||||
<main>
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
{% if messages %}
|
||||
<div class="messages">
|
||||
{% for message in messages %}
|
||||
<p {% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'application.html' %}
|
||||
|
||||
{% block content %}
|
||||
<section>
|
||||
<section class="panel">
|
||||
<p>You have been logged out. <a href="{% url 'login' %}">Log in</a></p>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'application.html' %}
|
||||
|
||||
{% block content %}
|
||||
<section>
|
||||
<section class="panel">
|
||||
<h1>Log in</h1>
|
||||
{% if form.errors %}
|
||||
<p class="error">Your username and password didn't match. Please try again.</p>
|
||||
@ -19,6 +19,7 @@
|
||||
{{ form.password.label_tag }}
|
||||
<br>
|
||||
{{ form.password }}
|
||||
<br>
|
||||
<small>
|
||||
Forgot your password? <a href="{% url 'password_reset' %}">Reset your password here</a>.
|
||||
</small>
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
{% extends 'application.html' %}
|
||||
|
||||
{% block content %}
|
||||
<section>
|
||||
<section class="panel">
|
||||
<h1>Change password</h1>
|
||||
<form method="post" action="{% url 'password_change' %}">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
|
||||
<input type="submit" value="Change my password" />
|
||||
<input type="submit" value="Change my password"> or
|
||||
<a href="{{request.META.HTTP_REFERER}}">Cancel</a>
|
||||
</form>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'application.html' %}
|
||||
|
||||
{% block content %}
|
||||
<sectin>
|
||||
<section class="panel">
|
||||
<p>Password was reset successfully.</p>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
{% block content %}
|
||||
|
||||
{% if validlink %}
|
||||
<section>
|
||||
<section class="panel">
|
||||
<h1>Reset password</h1>
|
||||
<p>Enter a <em>new</em> password below.</p>
|
||||
<form method="post" action=".">
|
||||
@ -15,7 +15,7 @@
|
||||
</section>
|
||||
{% else %}
|
||||
|
||||
<section>
|
||||
<section class="panel">
|
||||
<p>Password reset failed</p>
|
||||
</section>
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'application.html' %}
|
||||
|
||||
{% block content %}
|
||||
<section>
|
||||
<section class="panel">
|
||||
<p>An email with password reset instructions has been sent.</p>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'application.html' %}
|
||||
|
||||
{% block content %}
|
||||
<section>
|
||||
<section class="panel">
|
||||
<h1>Reset your password</h1>
|
||||
<p>Enter your email address below and we'll send you instructions.</p>
|
||||
<form method="post" action="{% url 'password_reset' %}">
|
||||
|
||||
18
tracker/middleware.py
Normal file
18
tracker/middleware.py
Normal file
@ -0,0 +1,18 @@
|
||||
import pytz
|
||||
|
||||
from django.utils import timezone
|
||||
|
||||
class TimezoneMiddleware:
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
|
||||
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)
|
||||
@ -52,6 +52,7 @@ MIDDLEWARE = [
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
'tracker.middleware.TimezoneMiddleware',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'tracker.urls'
|
||||
@ -110,7 +111,7 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
TIME_ZONE = 'US/Mountain'
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
@ -130,13 +131,22 @@ STATICFILES_FINDERS = (
|
||||
)
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
STATICFILES_DIRS = ['static']
|
||||
STATIC_ROOT = '/var/www/static/'
|
||||
COMPRESS_ROOT = BASE_DIR / 'static'
|
||||
STATICFILES_DIRS = [BASE_DIR / 'static']
|
||||
STATICFILES_FINDERS = (
|
||||
'django.contrib.staticfiles.finders.FileSystemFinder',
|
||||
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
||||
'compressor.finders.CompressorFinder',
|
||||
)
|
||||
|
||||
COMPRESS_PRECOMPILERS = (
|
||||
('text/x-scss', 'django_libsass.SassCompiler'),
|
||||
)
|
||||
# Media file storage
|
||||
|
||||
MEDIA_URL = '/media/'
|
||||
MEDIA_ROOT = BASE_DIR / 'media'
|
||||
|
||||
|
||||
LOGIN_REDIRECT_URL = '/attendance'
|
||||
LOGIN_REDIRECT_URL = '/accounts/timezone/'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user