Editor styling

This commit is contained in:
Vivek Santayana 2022-06-20 12:22:29 +01:00
parent de6910b4bf
commit 3025e83b66
4 changed files with 246 additions and 138 deletions

View File

@ -31,7 +31,7 @@ def create_app():
def _check_cookie_consent():
if request.cookies.get('cookie_consent'):
return
if any([ request.path.startswith(x) for x in [ '/admin/static/', '/root/', '/quiz/static', '/cookies/' ] ]):
if any([ request.path.startswith(x) for x in [ '/admin/static/', '/root/', '/quiz/static', '/cookies/', '/admin/editor/static' ] ]):
return
flash(f'<strong>Cookie Consent</strong>: This web site only stores minimal, functional cookies. It does not store any tracking information. By using this site, you consent to this use of cookies. For more information, see our <a href="{url_for("views._privacy")}">privacy policy</a>.', 'cookie_alert')
@ -46,11 +46,13 @@ def create_app():
from .api.views import api
from .quiz.views import quiz
from .views import views
from .editor.views import editor
app.register_blueprint(admin, url_prefix='/admin')
app.register_blueprint(api, url_prefix='/api')
app.register_blueprint(views)
app.register_blueprint(quiz)
app.register_blueprint(editor, url_prefix='/admin/editor')
install_app(app)

View File

@ -0,0 +1,46 @@
.accordion-button {
color: inherit;
background-color: inherit;
display: block;
border: 1px solid rgb(0 0 0 / .3);
height: 60px;
}
.editor-controls {
width: fit-content;
display: block;
margin: 10px auto;
}
.editor-controls a {
margin: 0 10px;
z-index: 10;
}
.accordion-button div {
margin: 0;
position: absolute;
top: 50%;
transform: translate(0, -50%);
}
.accordion-button a {
transform: translate(-50%, -50%);
top: 50%;
right: 0%;
position: absolute;
}
.accordion-button::after {
content: none;
}
.accordion-error {
background-color: #bb2d3b;
color: white;
}
.accordion-error:not(.collapsed) {
background-color: #bb2d3b;
color: white;
}

View File

@ -0,0 +1,68 @@
const root = $('#editor-root')
var data = [
{
"type": "question",
"q_no": 3,
"text": "The ball is gathered by the defensive division and a player throws it forward, hitting the korf in the other division.",
"options": [
"Play on",
"Opposite team restart under their defensive post",
"Opposite team restart where the ball was thrown from"
],
"correct": 0,
"q_type": "Multiple Choice",
"tags": [
"scoring from the defence zone"
]
},
{
"type": "question",
"q_no": 4,
"text": "At the end of the game, after the final whistle, a coach loudly confronts the referee. What can the referee do?",
"options": [
"Ignore the coach as the match has ended",
"Ignore the coach or inform the coach they will be reported",
"Ignore the coach, inform the coach they will be reported and/or show the coach a card"
],
"correct": 2,
"q_type": "List",
"tags": [
"discipline"
]
},
]
for (var i = 0; i < data.length; i++) {
if (data[i]['type'] == 'question') {
var obj = `
<div class="accordion-item" id="i${i}">
<h2 class="accordion-header" id="h${i}">
<div class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#c${i}" aria-expanded="true" aria-controls="c${i}">
<div class="float-start">Question ${i+1}</div>
<a href="javascript:void(0)" class="btn btn-success panel-control" data-id="${i}" data-action="remove">X</a>
</div>
</h2>
<div id="c${i}" class="accordion-collapse collapse" aria-labelledby="h${i}" data-bs-parent="#editor-root">
<div class="accordion-body">
<div class="question-text">
${data[i]['text']}
</div>
<ul>
<li>
${data[i]['options'].join("</li><li>")}
</li>
</ul>
</div>
</div>
</div>
`
root.append(obj)
}
}
$('.panel-control').click(function(event) {
console.log($(this).data('id'))
var id = $(this).data('id')
$(`#i${id}`).remove()
})

View File

@ -1,148 +1,140 @@
{% extends "editor/components/base.html" %}
{% block style %}
<link
rel="stylesheet"
href="{{ url_for('.static', filename='css/editor.css') }}"
/>
{% endblock %}
{% block content %}
<h1>Dashboard</h1>
<div class="container">
<div class="row">
<div class="col-sm">
<div class="card m-3">
<div class="card-body">
<h5 class="card-title">Current Exams</h5>
{% if current_tests %}
<div class="card-text">
<table class="table table-striped">
<thead>
<tr>
<th>
Exam Code
</th>
<th>
Expiry Date
</th>
</tr>
</thead>
<tbody>
{% for test in current_tests %}
<tr>
<td>
<a href="{{ url_for('admin._view_test', id=test.id) }}">{{ test.get_code() }}</a>
</td>
<td>
{{ test.end_date.strftime('%d %b %Y') }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<a href="{{ url_for('admin._tests', filter='active') }}" class="btn btn-primary">View Exams</a>
{% else %}
<div class="alert alert-primary">
There are currently no active exams.
</div>
<a href="{{ url_for('admin._tests', filter='create') }}" class="btn btn-primary">Create Exam</a>
{% endif %}
<h1>Editor</h1>
<div class="container editor-panel" id="editor" tabindex="-1">
<div class="accordion" id="editor-root">
<div class="accordion-item" id="i0">
<h2 class="accordion-header" id="h0">
<div class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#c0" aria-expanded="true" aria-controls="c0">
<div class="float-start">Question 1</div>
<a href="javascript:void(0)" class="btn btn-success panel-control" data-id="0" data-action="remove">X</a>
</div>
</div>
</h2>
<div id="c0" class="accordion-collapse collapse" aria-labelledby="h0" data-bs-parent="#editor-root">
<div class="accordion-body">
<div class="question-text">
<div class="input-group mb-3">
<span class="input-group-text">Question 1</span>
<textarea type="text" class="form-control" id="q0-text" aria-describedby="q0-text-caption">Placeholder for Question 1</textarea>
</div>
<div class="input-group mb-3">
<span class="input-group-text">Question Type</span>
<select id="q0-type" class="form-select">
<option value ="Multiple Choice">Multiple Choice</option>
<option value="Yes/No">Yes/No</option>
<option value="List">Ordered List</option>
</select>
</div>
<label for="q0-options" class="form-label">Options</label>
<ul class="options" id="q0-options">
<div class="input-group mb-3">
<span class="input-group-text" id="q0-options-0-caption">0</span>
<input type="text" class="form-control" value="Text for Option 1" id="q0-options-0" aria-describedby="q0-options-0-caption">
</div>
<div class="input-group mb-3">
<span class="input-group-text" id="q0-options-1-caption">1</span>
<input type="text" class="form-control" value="Text for Option 2" id="q0-options-1" aria-describedby="q-options-1-caption">
</div>
</ul>
<div class="editor-controls">
<a href="" class="btn btn-danger" data-action="Cancel">Cancel</a>
<a href="" class="btn btn-success" data-action="Done">Done</a>
</div>
<div class="input-group mb-3">
<span class="input-group-text" id="q0-correct-caption">Correct</span>
<input type="text" class="form-control" value="0" id="q0-correct" aria-describedby="q0-correct-caption">
</div>
<div class="input-group mb-3">
<span class="input-group-text" id="q0-tags-caption">Tags</span>
<textarea type="text" class="form-control" value="Foo" id="q0-tags" aria-describedby="q0-tags-caption">List of tags&#010;List of tags</textarea>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm">
<div class="card m-3">
<div class="card-body">
<h5 class="card-title">Recent Results</h5>
{% if recent_results %}
<div class="card-text">
<table class="table table-striped">
<thead>
<tr>
<th>
Name
</th>
<th>
Date Submitted
</th>
<th>
Result
</th>
</tr>
</thead>
<tbody>
{% for result in recent_results %}
<tr>
<td>
<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') }}
</td>
<td>
{{ (100*result.result['score']/result.result['max'])|round|int }}&percnt; ({{ result.result.grade }})
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<a href="{{ url_for('admin._view_entries') }}" class="btn btn-primary">View Results</a>
{% else %}
<div class="alert alert-primary">
There are currently no exam results to preview.
</div>
{% endif %}
<div class="accordion-item" id="i1">
<h2 class="accordion-header" id="h1">
<div class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#c1" aria-expanded="true" aria-controls="c1">
<div class="float-start">Block 1</div>
<a href="javascript:void(0)" class="btn btn-success panel-control" data-id="0" data-action="remove">X</a>
</div>
</div>
</h2>
<div id="c1" class="accordion-collapse collapse" aria-labelledby="h1" data-bs-parent="#editor-root">
<div class="accordion-body">
<div class="accordion" id="b1">
<div class="accordion-item" id="b1-item">
<h2 class="accordion-header" id="h2">
<div class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#c2" aria-expanded="true" aria-controls="c2">
<div class="float-start">Question 1</div>
<a href="javascript:void(0)" class="btn btn-success panel-control" data-id="0" data-action="remove">X</a>
</div>
</h2>
<div id="c2" class="accordion-collapse collapse" aria-labelledby="h2" data-bs-parent="#b1">
<div class="accordion-body">
<div class="question-text">
<div class="input-group mb-3">
<span class="input-group-text">Question 1</span>
<textarea type="text" class="form-control" id="q0-text" aria-describedby="q0-text-caption">Placeholder for Question 1</textarea>
</div>
<div class="input-group mb-3">
<span class="input-group-text">Question Type</span>
<select id="q0-type" class="form-select">
<option value ="Multiple Choice">Multiple Choice</option>
<option value="Yes/No">Yes/No</option>
<option value="List">Ordered List</option>
</select>
</div>
<label for="q1-options" class="form-label">Options</label>
<ul class="options" id="q1-options">
<div class="input-group mb-3">
<span class="input-group-text" id="q0-options-0-caption">0</span>
<input type="text" class="form-control" value="Text for Option 1" id="q0-options-0" aria-describedby="q0-options-0-caption">
</div>
<div class="input-group mb-3">
<span class="input-group-text" id="q0-options-1-caption">1</span>
<input type="text" class="form-control" value="Text for Option 2" id="q0-options-1" aria-describedby="q-options-1-caption">
</div>
</ul>
<div class="editor-controls">
<a href="" class="btn btn-danger" data-action="Cancel">Cancel</a>
<a href="" class="btn btn-success" data-action="Done">Done</a>
</div>
<div class="input-group mb-3">
<span class="input-group-text" id="q0-correct-caption">Correct</span>
<input type="text" class="form-control" value="0" id="q0-correct" aria-describedby="q0-correct-caption">
</div>
<div class="input-group mb-3">
<span class="input-group-text" id="q0-tags-caption">Tags</span>
<textarea type="text" class="form-control" value="Foo" id="q0-tags" aria-describedby="q0-tags-caption">List of tags&#010;List of tags</textarea>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row g-3">
<div class="col-sm">
<div class="card m-3">
<div class="card-body">
<h5 class="card-title">Upcoming Exams</h5>
{% if upcoming_tests %}
<div class="card-text">
<table class="table table-striped">
<thead>
<tr>
<th>
Exam Code
</th>
<th>
Expiry Date
</th>
</tr>
</thead>
<tbody>
{% for test in upcoming_tests %}
<tr>
<td>
<a href="{{ url_for('admin._view_test', id=test.id) }}">{{ test.get_code() }}</a>
</td>
<td>
{{ test.end_date.strftime('%d %b %Y') }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<a href="{{ url_for('admin._tests', filter='scheduled') }}" class="btn btn-primary">View Exams</a>
{% else %}
<div class="alert alert-primary">
There are currently no upcoming exams.
</div>
<a href="{{ url_for('admin._tests', filter='create') }}" class="btn btn-primary">Create Exam</a>
{% endif %}
</div>
</div>
</div>
<div class="col-sm">
<div class="card m-3">
<div class="card-body">
<h5 class="card-title">Help</h5>
<p class="card-text">This web app was developed by Vivek Santayana. If there are any issues with the app, any bugs you need to report, or any features you would like to request, please feel free to <a href="https://git.vsnt.uk/viveksantayana/ska-referee-test/issues">open an issue at the Git Repository</a>.</p>
<a href="https://git.vsnt.uk/viveksantayana/ska-referee-test/issues" class="btn btn-primary">Open an Issue</a>
</div>
</div>
</div>
{% include "editor/components/client-alerts.html" %}
<div class="editor-controls">
<a href="" class="btn btn-danger" data-action="Cancel">Cancel</a>
<a href="" class="btn btn-success" data-action="Done">Done</a>
</div>
</div>
{% endblock %}
{% block script %}
<script
type="text/javascript"
src="{{ url_for('.static', filename='js/editor.js') }}"
></script>
{% endblock %}