Add course
This commit is contained in:
parent
d409f0e9b4
commit
83579891b9
27 changed files with 1308 additions and 484 deletions
|
@ -1,12 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Courses</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
{% extends "two-column-content.html" %}
|
||||
|
||||
{% block left_sidebar %}
|
||||
{% include "course/left_sidebar.html" %}
|
||||
{% endblock %}
|
39
templates/course/course.html
Normal file
39
templates/course/course.html
Normal file
|
@ -0,0 +1,39 @@
|
|||
{% extends "course/base.html" %}
|
||||
|
||||
{% block middle_content %}
|
||||
<center><h2>{{title}}</h2></center>
|
||||
<h3 class="course-content-title">{{_("About")}}</h3>
|
||||
<div>
|
||||
{{ course.about|markdown|reference|str|safe }}
|
||||
</div>
|
||||
<h3 class="course-content-title">{{_("Lessons")}}</h3>
|
||||
<ul class="lesson-list">
|
||||
{% for lesson in lessons %}
|
||||
<a href="{{url('course_lesson_detail', course.slug, lesson.id)}}">
|
||||
{% set progress = lesson_progress[lesson.id] %}
|
||||
<li>
|
||||
<div class="lesson-title">
|
||||
{{ lesson.title }}
|
||||
<div class="lesson-points">
|
||||
{{progress['achieved_points'] | floatformat(1)}} / {{lesson.points}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-container">
|
||||
<div class="progress-bar" style="width: {{progress['percentage']}}%;">{{progress['percentage']|floatformat(0)}}%</div>
|
||||
</div>
|
||||
</li>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<h3 class="course-content-title">
|
||||
{% set total_progress = lesson_progress['total'] %}
|
||||
{% set achieved_points = total_progress['achieved_points'] %}
|
||||
{% set total_points = total_progress['total_points'] %}
|
||||
{% set percentage = total_progress['percentage'] %}
|
||||
|
||||
{{_("Total achieved points")}}:
|
||||
<span style="float: right; font-weight: normal;">
|
||||
{{ achieved_points | floatformat(2) }} / {{ total_points }} ({{percentage|floatformat(1)}}%)
|
||||
</span>
|
||||
</h3>
|
||||
{% endblock %}
|
58
templates/course/edit_lesson.html
Normal file
58
templates/course/edit_lesson.html
Normal file
|
@ -0,0 +1,58 @@
|
|||
{% extends "course/base.html" %}
|
||||
|
||||
{% block two_col_media %}
|
||||
{{ form.media.css }}
|
||||
<style type="text/css">
|
||||
.field-order, .field-title, .field-points {
|
||||
display: inline-flex;
|
||||
}
|
||||
.form-header {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block two_col_js %}
|
||||
{{ form.media.js }}
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ formset.management_form }}
|
||||
{% for form in formset %}
|
||||
<h3 class="toggle {{'open' if form.errors else 'closed'}} form-header"><i class="fa fa-chevron-right fa-fw"></i>
|
||||
{% if form.title.value() %}
|
||||
{{form.order.value()}}. {{form.title.value()}}
|
||||
{% else %}
|
||||
+ {{_("Add new")}}
|
||||
{% endif %}
|
||||
</h3>
|
||||
<div class="toggled" style="{{'display: none;' if not form.errors}} margin-bottom: 1em">
|
||||
{{form.id}}
|
||||
{% if form.errors %}
|
||||
<div class="alert alert-danger alert-dismissable">
|
||||
<a href="#" class="close">x</a>
|
||||
{{_("Please fix below errors")}}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for field in form %}
|
||||
{% if not field.is_hidden %}
|
||||
<div style="margin-bottom: 1em;">
|
||||
{{ field.errors }}
|
||||
<label for="{{field.id_for_label }}"><b>{{ field.label }}{% if field.field.required %}<span class="red"> * </span>{% endif %}:</b> </label>
|
||||
<div class="org-field-wrapper field-{{field.name}}" id="org-field-wrapper-{{field.html_name}}">
|
||||
{{ field }}
|
||||
</div>
|
||||
{% if field.help_text %}
|
||||
<small class="org-help-text"><i class="fa fa-exclamation-circle"></i> {{ field.help_text|safe }}</small>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<hr/>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<input type="submit" value="{{_('Save')}}" style="float: right">
|
||||
</form>
|
||||
{% endblock %}
|
127
templates/course/grades.html
Normal file
127
templates/course/grades.html
Normal file
|
@ -0,0 +1,127 @@
|
|||
{% extends "course/base.html" %}
|
||||
|
||||
{% block two_col_media %}
|
||||
<style type="text/css">
|
||||
table {
|
||||
font-size: 15px;
|
||||
}
|
||||
td {
|
||||
height: 2.5em;
|
||||
}
|
||||
.user-name {
|
||||
padding-left: 1em !important;
|
||||
}
|
||||
#search-input {
|
||||
float: right;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block two_col_js %}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
var $searchInput = $("#search-input");
|
||||
var $usersTable = $("#users-table");
|
||||
var tableBorderColor = $('#users-table td').css('border-bottom-color');
|
||||
|
||||
$searchInput.on("keyup", function() {
|
||||
var value = $(this).val().toLowerCase();
|
||||
$("#users-table tbody tr").filter(function() {
|
||||
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
|
||||
});
|
||||
|
||||
if(value) {
|
||||
$('#users-table').css('border-bottom', '1px solid ' + tableBorderColor);
|
||||
} else {
|
||||
$('#users-table').css('border-bottom', '');
|
||||
}
|
||||
});
|
||||
|
||||
$('#sortSelect').select2({
|
||||
minimumResultsForSearch: -1,
|
||||
width: "10em",
|
||||
});
|
||||
|
||||
$('#sortSelect').on('change', function() {
|
||||
var rows = $('#users-table tbody tr').get();
|
||||
var sortBy = $(this).val();
|
||||
rows.sort(function(a, b) {
|
||||
var keyA = $(a).find(sortBy === 'username' ? '.user-name' : 'td:last-child').text().trim();
|
||||
var keyB = $(b).find(sortBy === 'username' ? '.user-name' : 'td:last-child').text().trim();
|
||||
|
||||
if(sortBy === 'total') {
|
||||
// Convert percentage string to number for comparison
|
||||
keyA = -parseFloat(keyA.replace('%', ''));
|
||||
keyB = -parseFloat(keyB.replace('%', ''));
|
||||
}
|
||||
else {
|
||||
keyA = keyA.toLowerCase();
|
||||
keyB = keyB.toLowerCase();
|
||||
}
|
||||
|
||||
if(keyA < keyB) return -1;
|
||||
if(keyA > keyB) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
$.each(rows, function(index, row) {
|
||||
$('#users-table tbody').append(row);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
<center><h2>{{title}}</h2></center>
|
||||
{% set lessons = course.lessons.all() %}
|
||||
{{_("Sort by")}}:
|
||||
<select id="sortSelect">
|
||||
<option value="username">{{_("Username")}}</option>
|
||||
<option value="total">{{_("Score")}}</option>
|
||||
</select>
|
||||
<input type="text" id="search-input" placeholder="{{_('Search')}}" autofocus>
|
||||
<table class="table striped" id="users-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{_('Student')}}</th>
|
||||
{% if grades|length > 0 %}
|
||||
{% for lesson in lessons %}
|
||||
<th class="points">
|
||||
<a href="{{url('course_lesson_detail', course.slug, lesson.id)}}">
|
||||
{{ lesson.title }}
|
||||
<div class="point-denominator">{{lesson.points}}</div>
|
||||
</a>
|
||||
</th>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<th>{{_('Total')}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for student, grade in grades.items() %}
|
||||
<tr>
|
||||
<td class="user-name">
|
||||
<div>
|
||||
{{link_user(student)}}
|
||||
</div>
|
||||
<div>
|
||||
{{student.first_name}}
|
||||
</div>
|
||||
</td>
|
||||
{% for lesson in lessons %}
|
||||
<td class="partial-score">
|
||||
<a href="{{url('course_lesson_detail', course.slug, lesson.id)}}?user={{student.username}}">
|
||||
{{ grade[lesson.id]['percentage'] | floatformat(0) }}%
|
||||
</a>
|
||||
</td>
|
||||
{% endfor %}
|
||||
<td style="font-weight: bold">
|
||||
{{ grade['total']['percentage'] | floatformat(0) }}%
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
10
templates/course/left_sidebar.html
Normal file
10
templates/course/left_sidebar.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
<div class="left-sidebar">
|
||||
{{ make_tab_item('home', 'fa fa-home', course.get_absolute_url(), _('Home')) }}
|
||||
{% if is_editable %}
|
||||
{{ make_tab_item('edit_lesson', 'fa fa-edit', url('edit_course_lessons', course.slug), _('Edit lessons')) }}
|
||||
{{ make_tab_item('grades', 'fa fa-check-square-o', url('course_grades', course.slug), _('Grades')) }}
|
||||
{% endif %}
|
||||
{% if perms.judge.change_course %}
|
||||
{{ make_tab_item('admin', 'fa fa-edit', url('admin:judge_course_change', course.id), _('Admin')) }}
|
||||
{% endif %}
|
||||
</div>
|
39
templates/course/lesson.html
Normal file
39
templates/course/lesson.html
Normal file
|
@ -0,0 +1,39 @@
|
|||
{% extends "course/base.html" %}
|
||||
|
||||
{% block two_col_media %}
|
||||
<style>
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
<center><h2>{{title}}</h2></center>
|
||||
<h3 class="course-content-title">{{_("Content")}}</h3>
|
||||
<div>
|
||||
{{ lesson.content|markdown|reference|str|safe }}
|
||||
</div>
|
||||
<h3 class="course-content-title">{{_("Problems")}}</h3>
|
||||
<ul class="course-problem-list">
|
||||
{% for problem in lesson.problems.all() %}
|
||||
<a href="{{url('problem_detail', problem.code)}}">
|
||||
<li>
|
||||
{% if problem.id in completed_problem_ids %}
|
||||
<i class="solved-problem-color fa fa-check-circle"></i>
|
||||
{% elif problem.id in attempted_problems %}
|
||||
<i class="attempted-problem-color fa fa-minus-circle"></i>
|
||||
{% else %}
|
||||
<i class="unsolved-problem-color fa fa-minus-circle"></i>
|
||||
{% endif %}
|
||||
<span class="problem-name">{{problem.name}}</span>
|
||||
{% set pp = problem_points[problem.id] %}
|
||||
<span class="score">
|
||||
{% if pp %}
|
||||
{{pp.case_points|floatformat(1)}} / {{pp.case_total|floatformat(0)}}
|
||||
{% else %}
|
||||
0
|
||||
{% endif %}
|
||||
</span>
|
||||
</li>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
|
@ -1,19 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Enrolling</h1>
|
||||
{% for course in enrolling %}
|
||||
<h2> {{ course }} </h2>
|
||||
{% extends "two-column-content.html" %}
|
||||
|
||||
{% block two_col_media %}
|
||||
{% endblock %}
|
||||
|
||||
{% block left_sidebar %}
|
||||
<div class="left-sidebar">
|
||||
{{ make_tab_item('list', 'fa fa-list', url('course_list'), _('Courses')) }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
<div class="course-list">
|
||||
{% for course in courses %}
|
||||
<div class="course-item">
|
||||
<div class="course-image">
|
||||
<img src="{{course.image_url}}">
|
||||
</div>
|
||||
<div class="course-content">
|
||||
<a href="{{url('course_detail', course.slug)}}" class="course-name">{{course.name}}</a>
|
||||
{% set teachers = course.get_teachers() %}
|
||||
{% if teachers %}
|
||||
<div class="course-teachers">{{_('Teachers')}}: {{link_users(teachers)}}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<h1> Available </h1>
|
||||
{% for course in available %}
|
||||
<h2> {{ course }} </h2>
|
||||
{% endfor %}
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
{% endblock %}
|
Loading…
Add table
Add a link
Reference in a new issue