12 Commits

9 changed files with 55 additions and 15 deletions

View File

@ -50,7 +50,7 @@
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">Start Time</h5>
</div>
{{ entry.start_time.strftime('%d %b %Y %H:%M:%S') }}
{{ entry.start_time.strftime('%d %b %Y %H:%M:%S') if entry.start_time else None }}
</li>
<li class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
@ -59,7 +59,7 @@
<span class="badge bg-danger">Late</span>
{% endif %}
</div>
{{ entry.end_time.strftime('%d %b %Y %H:%M:%S') }}
{{ entry.end_time.strftime('%d %b %Y %H:%M:%S') if entry.end_time else None }}
</li>
<li class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">

View File

@ -28,7 +28,7 @@
<a href="{{ url_for('admin._view_test', id=test.id) }}">{{ test.get_code() }}</a>
</td>
<td>
{{ test.end_date.strftime('%d %b %Y') }}
{{ test.end_date.strftime('%d %b %Y') if test.end_date else None }}
</td>
</tr>
{% endfor %}
@ -72,10 +72,14 @@
<a href="{{ url_for('admin._view_entry', id=result.id) }}">{{ result.get_surname() }}, {{ result.get_first_name() }}</a>
</td>
<td>
{{ result.end_time.strftime('%d %b %Y %H:%M') }}
{{ result.end_time.strftime('%d %b %Y %H:%M') if result.end_time else None }}
</td>
<td>
{{ (100*result.result['score']/result.result['max'])|round|int }}&percnt; ({{ result.result.grade }})
{% if result.result %}
{{ (100*result.result['score']/result.result['max'])|round|int }}&percnt; ({{ result.result.grade }})
{% else %}
Incomplete
{% endif %}
</td>
</tr>
{% endfor %}
@ -117,7 +121,7 @@
<a href="{{ url_for('admin._view_test', id=test.id) }}">{{ test.get_code() }}</a>
</td>
<td>
{{ test.end_date.strftime('%d %b %Y') }}
{{ test.end_date.strftime('%d %b %Y') if test.end_date else None }}
</td>
</tr>
{% endfor %}

View File

@ -49,7 +49,7 @@
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">Start Time</h5>
</div>
{{ entry.start_time.strftime('%d %b %Y %H:%M:%S') }}
{{ entry.start_time.strftime('%d %b %Y %H:%M:%S') if entry.start_time else None }}
</li>
{% endif %}
<li class="list-group-item list-group-item-action">

View File

@ -32,13 +32,13 @@
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">Start Date</h5>
</div>
{{ test.start_date.strftime('%d %b %Y %H:%M') }}
{{ test.start_date.strftime('%d %b %Y %H:%M') if test.start_date else None }}
</li>
<li class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">Expiry Date</h5>
</div>
{{ test.end_date.strftime('%d %b %Y %H:%M') }}
{{ test.end_date.strftime('%d %b %Y %H:%M') if test.end_date else None }}
</li>
<li class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">

View File

@ -10,7 +10,7 @@ from flask import abort, Blueprint, jsonify, render_template, request, send_file
from flask.helpers import abort, flash, redirect, url_for
from flask_login import current_user, login_required
from datetime import date, datetime, timedelta
from datetime import date, datetime, MINYEAR, timedelta
from json import loads
from os import path
import secrets
@ -34,11 +34,11 @@ def _home():
write('system.log', f'Database error when processing request \'{request.url}\': {exception}')
return abort(500)
current_tests = [ test for test in tests if test.end_date >= datetime.now() and test.start_date.date() <= date.today() ]
current_tests.sort(key= lambda x: x.end_date, reverse=True)
current_tests.sort(key= lambda x: x.end_date or datetime(MINYEAR,1,1), reverse=True)
upcoming_tests = [ test for test in tests if test.start_date.date() > datetime.now().date()]
upcoming_tests.sort(key= lambda x: x.start_date)
upcoming_tests.sort(key= lambda x: x.start_date or datetime(MINYEAR,1,1))
recent_results = [result for result in results if not result.status == 'started' ]
recent_results.sort(key= lambda x: x.end_time, reverse=True)
recent_results.sort(key= lambda x: x.end_time or datetime(MINYEAR,1,1), reverse=True)
return render_template('/admin/index.html', current_tests = current_tests, upcomimg_tests = upcoming_tests, recent_results = recent_results)
@admin.route('/settings/')
@ -309,7 +309,7 @@ def _tests(filter:str=None):
if filter in [None, '', 'active']:
tests = [ test for test in _tests if test.end_date >= now and test.start_date <= now ]
display_title = 'Active Exams'
error_none = 'There are no exams that are currently active. You can create one using the Creat Exam form.'
error_none = 'There are no exams that are currently active. You can create one using the Create Exam form.'
if filter == 'expired':
tests = [ test for test in _tests if test.end_date < now ]
display_title = 'Expired Exams'

View File

@ -14,6 +14,9 @@
<div class="container quiz-start-text">
You can use this panel to adjust the display settings for the exam. Please use the menu below to select the font face and font size. Below is a sample question so you can see how the exam will render with your chosen settings.
</div>
<div class="container quiz-start-text">
These settings will be stored locally on your browser window. No information about your preferences below will be collected by the app.
</div>
<div class="alert alert-primary quiz-start-text" role="alert">
<strong>Note</strong>: Some fonts may not be available depending on your device and/or operating system.
</div>

View File

@ -56,6 +56,8 @@
integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13"
crossorigin="anonymous"
></script>
<!-- jQuery UI -->
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<!-- Custom js -->
<script type="text/javascript">
var csrf_token = "{{ csrf_token() }}";

View File

@ -1,6 +1,10 @@
{% extends "quiz/components/base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block style %}
<link rel="stylesheet" href="https://code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
{% endblock %}
{% block content %}
<div class="form-container">
<form name="form-quiz-start" class="form-quiz-start">
@ -43,4 +47,14 @@
</div>
</form>
</div>
{% endblock %}
{% block script %}
<script>
$( function() {
const clubs = {{ clubs|tojson }}
$('#club').autocomplete({
source: clubs
})
} )
</script>
{% endblock %}

View File

@ -29,6 +29,23 @@ def _instructions():
@quiz.route('/start/', methods=['GET', 'POST'])
def _start():
clubs = [
'Dundee Korfball Club',
'Edinburgh City Korfball Club',
'Edinburgh Mavericks Korfball Club',
'Edinburgh University Korfball Club',
'Glasgow Korfball Club',
'Saint Andrews University Korfball Club',
'Strathclyde University Korfball Club'
]
try: entries = Entry.query.all()
except Exception as exception:
write('system.log', f'Database error when processing request \'{request.url}\': {exception}')
return abort(500)
for entry in entries: clubs.append(entry.get_club())
clubs = list(set(clubs))
try: clubs.remove('')
except: pass
form = StartQuiz()
if request.method == 'POST':
if form.validate_on_submit():
@ -58,7 +75,7 @@ def _start():
}), 200
return jsonify({'error': 'There was an error processing the user test and/or user codes.'}), 400
return send_errors_to_client(form=form)
return render_template('/quiz/start_quiz.html', form = form)
return render_template('/quiz/start_quiz.html', form = form, clubs = clubs)
@quiz.route('/quiz/')
def _quiz():