diff options
-rw-r--r-- | yaksh/models.py | 19 | ||||
-rw-r--r-- | yaksh/static/yaksh/css/custom.css | 49 | ||||
-rw-r--r-- | yaksh/templates/yaksh/course_forum.html | 224 | ||||
-rw-r--r-- | yaksh/templates/yaksh/lessons_forum.html | 70 | ||||
-rw-r--r-- | yaksh/templates/yaksh/post_comments.html | 6 | ||||
-rw-r--r-- | yaksh/templates/yaksh/show_video.html | 2 | ||||
-rw-r--r-- | yaksh/templates/yaksh/sidebar.html | 8 | ||||
-rw-r--r-- | yaksh/urls.py | 4 | ||||
-rw-r--r-- | yaksh/views.py | 29 |
9 files changed, 286 insertions, 125 deletions
diff --git a/yaksh/models.py b/yaksh/models.py index 67f981e..df70fc1 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1102,6 +1102,25 @@ class Course(models.Model): learning_units.extend(module.get_learning_units()) return learning_units + def get_lesson_posts(self, user): + learning_units = self.get_learning_units() + comments = [] + for unit in learning_units: + if unit.lesson is not None: + lesson_ct = ContentType.objects.get_for_model(unit.lesson) + title = unit.lesson.name + try: + post = Post.objects.get( + target_ct=lesson_ct, + target_id=unit.lesson.id, + active=True, title=title, creator=user + ) + except Post.DoesNotExist: + post = None + if post is not None: + comments.append(post) + return comments + def remove_trial_modules(self): learning_modules = self.learning_module.all() for module in learning_modules: diff --git a/yaksh/static/yaksh/css/custom.css b/yaksh/static/yaksh/css/custom.css index 26efbed..edb9530 100644 --- a/yaksh/static/yaksh/css/custom.css +++ b/yaksh/static/yaksh/css/custom.css @@ -109,12 +109,49 @@ body, .dropdown-menu { FORUM STYLE ----------------------------------------------------- */ -.brown-light { - background: #f4a460; - padding-left: 0.3em; - padding-right: 0.3em; - padding-top: 0.2em; - padding-bottom: 0.2em; + #wrapper { + overflow-x: hidden; + } + +#sidebar-wrapper { + min-height: 100vh; + margin-left: -15rem; + -webkit-transition: margin .25s ease-out; + -moz-transition: margin .25s ease-out; + -o-transition: margin .25s ease-out; + transition: margin .25s ease-out; +} + +#sidebar-wrapper .sidebar-heading { + padding: 0.875rem 1.25rem; + font-size: 1.2rem; +} + +#sidebar-wrapper .list-group { + width: 15rem; +} + +#page-content-wrapper { + min-width: 100vw; +} + +#wrapper.toggled #sidebar-wrapper { + margin-left: 0; +} + +@media (min-width: 768px) { + #sidebar-wrapper { + margin-left: 0; + } + + #page-content-wrapper { + min-width: 0; + width: 100%; + } + + #wrapper.toggled #sidebar-wrapper { + margin-left: -15rem; + } } .post_image, .comment_image { diff --git a/yaksh/templates/yaksh/course_forum.html b/yaksh/templates/yaksh/course_forum.html index 4724981..a9bda6f 100644 --- a/yaksh/templates/yaksh/course_forum.html +++ b/yaksh/templates/yaksh/course_forum.html @@ -4,124 +4,126 @@ {{course.name}}: Discussion Forum {% endblock title %} {% block content %} - <div class="container"> - <div> - <h2><center>{{course.name}}</center></h2> - <center>Discussion Forum</center> - </div> - <div class="d-flex p-2 bd-highlight"> - <div class="col-md-4"> - {% if moderator %} - <a href="{% url 'yaksh:course_detail' course.id %}" class="btn btn-primary"> - <i class="fa fa-arrow-left"></i> Back - </a> - {% else %} - <a href="{% url 'yaksh:course_modules' course.id %}" class="btn btn-primary"> - <i class="fa fa-arrow-left"></i> Back - </a> - {% endif %} + <div id="wrapper" class="d-flex"> + {% include "yaksh/sidebar.html" %} + <div class="container" id="page-content-wrapper"> + <div> + <h2><center>{{course.name}}</center></h2> + <center>Discussion Forum</center> </div> - <div class="col-md"> - <button type="button" class="btn btn-success pull-right" data-toggle="modal" data-target="#newPostModal"> - <i class="fa fa-plus-circle"></i> New Post - </button> + <div class="d-flex p-2 bd-highlight"> + <div class="col-md-4"> + {% if moderator %} + <a href="{% url 'yaksh:course_detail' course.id %}" class="btn btn-primary"> + <i class="fa fa-arrow-left"></i> Back + </a> + {% else %} + <a href="{% url 'yaksh:course_modules' course.id %}" class="btn btn-primary"> + <i class="fa fa-arrow-left"></i> Back + </a> + {% endif %} + </div> + <div class="col-md"> + <button type="button" class="btn btn-success pull-right" data-toggle="modal" data-target="#newPostModal"> + <i class="fa fa-plus-circle"></i> New Post + </button> + </div> </div> - </div> - <!-- Modal --> - <div id="newPostModal" class="modal fade" role="dialog"> - <div class="modal-dialog"> + <!-- Modal --> + <div id="newPostModal" class="modal fade" role="dialog"> + <div class="modal-dialog"> - <!-- Modal content--> - <div class="modal-content"> - <div class="modal-header"> - <h4 class="modal-title">Create a new Post</h4> - <button type="button" class="close" data-dismiss="modal">×</button> - </div> - <div class="modal-body"> - <form action="." method="POST" enctype='multipart/form-data'> - <div class="form-group"> - {% csrf_token %} - {{form}} - </div> - <input type="submit" class="btn btn-primary" value="Create Post"> - </form> - </div> - <div class="modal-footer"> - <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> + <!-- Modal content--> + <div class="modal-content"> + <div class="modal-header"> + <h4 class="modal-title">Create a new Post</h4> + <button type="button" class="close" data-dismiss="modal">×</button> + </div> + <div class="modal-body"> + <form action="." method="POST" enctype='multipart/form-data'> + <div class="form-group"> + {% csrf_token %} + {{form}} + </div> + <input type="submit" class="btn btn-primary" value="Create Post"> + </form> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> + </div> + </div> </div> </div> - - </div> - </div> - <br> - <div class="row justify-content-center"> - <div class="col-md-6"> - <form class="my-2 my-lg-0" action="" method="GET"> - <div class="input-group"> - <input type="search" placeholder="Search Post" name="search_post" class="form-control"> - <span class="input-group-append"> - <button class="btn btn-outline-info"> - <i class="fa fa-search"></i> Search - </button> - </span> - </div> - </form> - </div> - <div class="col-md-4"> - <a class="btn btn-outline-danger" href="{% url 'yaksh:course_forum' course.id %}"> - <i class="fa fa-times"></i> Clear Search - </a> - </div> - </div> - <br> - {% with objects as posts %} - {% if posts %} - {% include "yaksh/paginator.html" %} <br> - <table id="posts_table" class="tablesorter table"> - <thead class="thread-inverse"> - <tr> - <th width="700">Posts</th> - <th>Created by</th> - <th>Replies</th> - <th>Last reply</th> - <th></th> - </tr> - </thead> - <tbody> - {% for post in posts %} - <tr> - <td> - <a href="{% url 'yaksh:post_comments' course.id post.uid %}">{{post.title}}</a> - <small class="text-muted d-block">{{ post.description|truncatewords:30 }}</small> - <small class="text-muted"><strong>Last updated: {{post.modified_at}}</strong></small> - </td> - <td>{{post.creator.username}}</td> - <td>{{post.get_comments_count}}</td> - <td> - {% with post.get_last_comment as last_comment %} - {% if last_comment %} - {{last_comment.creator}} - {% else %} - None - {% endif %} - {% endwith %} - </td> - <td> - {% if user.profile.is_moderator %} - <small><a href="{% url 'yaksh:hide_post' course.id post.uid %}" class="pull-right btn btn-danger">Delete</i></a></small> - {% endif %} - </td> - </tr> - {% endfor %} - </tbody> - </table> + <div class="row justify-content-center"> + <div class="col-md-6"> + <form class="my-2 my-lg-0" action="" method="GET"> + <div class="input-group"> + <input type="search" placeholder="Search Post" name="search_post" class="form-control"> + <span class="input-group-append"> + <button class="btn btn-outline-info"> + <i class="fa fa-search"></i> Search + </button> + </span> + </div> + </form> + </div> + <div class="col-md-4"> + <a class="btn btn-outline-danger" href="{% url 'yaksh:course_forum' course.id %}"> + <i class="fa fa-times"></i> Clear Search + </a> + </div> + </div> <br> - {% include "yaksh/paginator.html" %} - {% else %} - No discussion posts are there yet. Create one to start discussing. - {% endif %} - {% endwith %} + {% with objects as posts %} + {% if posts %} + {% include "yaksh/paginator.html" %} + <br> + <table id="posts_table" class="tablesorter table"> + <thead class="thread-inverse"> + <tr> + <th width="700">Posts</th> + <th>Created by</th> + <th>Replies</th> + <th>Last reply</th> + <th></th> + </tr> + </thead> + <tbody> + {% for post in posts %} + <tr> + <td> + <a href="{% url 'yaksh:post_comments' course.id post.uid %}">{{post.title}}</a> + <small class="text-muted d-block">{{ post.description|truncatewords:30 }}</small> + <small class="text-muted"><strong>Last updated: {{post.modified_at}}</strong></small> + </td> + <td>{{post.creator.username}}</td> + <td>{{post.get_comments_count}}</td> + <td> + {% with post.get_last_comment as last_comment %} + {% if last_comment %} + {{last_comment.creator}} + {% else %} + None + {% endif %} + {% endwith %} + </td> + <td> + {% if user.profile.is_moderator %} + <small><a href="{% url 'yaksh:hide_post' course.id post.uid %}" class="pull-right fa fa-trash"></i></a></small> + {% endif %} + </td> + </tr> + {% endfor %} + </tbody> + </table> + <br> + {% include "yaksh/paginator.html" %} + {% else %} + No discussion posts are there yet. Create one to start discussing. + {% endif %} + {% endwith %} + </div> </div> {% endblock content %} {% block script %} diff --git a/yaksh/templates/yaksh/lessons_forum.html b/yaksh/templates/yaksh/lessons_forum.html new file mode 100644 index 0000000..a4fd23b --- /dev/null +++ b/yaksh/templates/yaksh/lessons_forum.html @@ -0,0 +1,70 @@ +{% extends base_template %} +{% load static %} +{% block title %} + {{course.name}}: Lessons Forum +{% endblock title %} +{% block content %} + <div id="wrapper" class="d-flex"> + {% include "yaksh/sidebar.html" %} + <div class="container" id="page-content-wrapper"> + <div> + <h2><center>{{course.name}}</center></h2> + <center>Discussion Forum</center> + </div> + <div class="d-flex p-2 bd-highlight"> + <div class="col-md-4"> + {% if moderator %} + <a href="{% url 'yaksh:course_detail' course.id %}" class="btn btn-primary"> + <i class="fa fa-arrow-left"></i> Back + </a> + {% else %} + <a href="{% url 'yaksh:course_modules' course.id %}" class="btn btn-primary"> + <i class="fa fa-arrow-left"></i> Back + </a> + {% endif %} + </div> + </div> + {% if posts %} + <table class="table"> + <thead class="thread-inverse"> + <tr> + <th width="700">Posts</th> + <th>Created by</th> + <th>Replies</th> + <th>Last reply</th> + <th></th> + </tr> + </thead> + <tbody> + {% for post in posts %} + <tr> + <td> + <a href="{% url 'yaksh:post_comments' course.id post.uid %}">{{post.title}}</a> + <small class="text-muted d-block">{{ post.description|truncatewords:30 }}</small> + <small class="text-muted"><strong>Last updated: {{post.modified_at}}</strong></small> + </td> + <td>{{post.creator.username}}</td> + <td>{{post.get_comments_count}}</td> + <td> + {% with post.get_last_comment as last_comment %} + {% if last_comment %} + {{last_comment.creator}} + {% else %} + None + {% endif %} + {% endwith %} + </td> + <td> + {% if user.profile.is_moderator %} + <small><a href="{% url 'yaksh:hide_post' course.id post.uid %}" class="pull-right fa fa-trash"></i></a></small> + {% endif %} + </td> + </tr> + {% endfor %} + </tbody> + </table> + {% endif %} + </div> + </div> +{% endblock content %} + diff --git a/yaksh/templates/yaksh/post_comments.html b/yaksh/templates/yaksh/post_comments.html index f0f1593..6051b6e 100644 --- a/yaksh/templates/yaksh/post_comments.html +++ b/yaksh/templates/yaksh/post_comments.html @@ -6,7 +6,7 @@ {% block content %} <div class="container"> - <a class="btn btn-primary" href="{% url 'yaksh:course_forum' post.target.id %}"> + <a class="btn btn-primary" href="{% url 'yaksh:course_forum' course.id %}"> <i class="fa fa-arrow-left"></i> Back to Posts </a> <br> @@ -18,7 +18,7 @@ <small> <strong>{{post.creator.username}}</strong> {{post.created_at}} - {% if user.profile.is_moderator %}<a href="{% url 'yaksh:hide_post' post.target.id post.uid %}" class="pull-right btn btn-danger">Delete</a>{% endif %} + {% if user.profile.is_moderator %}<a href="{% url 'yaksh:hide_post' post.target.id post.uid %}" class="pull-right fa fa-trash"></a>{% endif %} </small> </div> @@ -41,7 +41,7 @@ <strong class="text-muted">{{comment.creator.username}}</strong> </div> <div class="col-6 text-right"> - <small class="text-muted">{{comment.created_at}} {% if user.profile.is_moderator %} <a href="{% url 'yaksh:hide_comment' post.target.id comment.uid %}" class="btn btn-danger">Delete</a>{% endif %}</small> + <small class="text-muted">{{comment.created_at}} {% if user.profile.is_moderator %} <a href="{% url 'yaksh:hide_comment' post.target.id comment.uid %}" class="fa fa-trash"></a>{% endif %}</small> </div> </div> <p class="card-text description">{{comment.description}}</p> diff --git a/yaksh/templates/yaksh/show_video.html b/yaksh/templates/yaksh/show_video.html index 76a48d4..ef6f459 100644 --- a/yaksh/templates/yaksh/show_video.html +++ b/yaksh/templates/yaksh/show_video.html @@ -236,7 +236,7 @@ <strong class="text-muted">{{comment.creator.username}}</strong> </div> <div class="col-6 text-right"> - <small class="text-muted">{{comment.created_at}} {% if user.profile.is_moderator %} <a href="{% url 'yaksh:hide_comment' course.id comment.uid %}" class="btn btn-danger">Delete</a>{% endif %}</small> + <small class="text-muted">{{comment.created_at}} {% if user.profile.is_moderator %} <a href="{% url 'yaksh:hide_comment' course.id comment.uid %}" class="fa fa-trash"></a>{% endif %}</small> </div> </div> <p class="card-text description">{{comment.description}}</p> diff --git a/yaksh/templates/yaksh/sidebar.html b/yaksh/templates/yaksh/sidebar.html new file mode 100644 index 0000000..7d0ac74 --- /dev/null +++ b/yaksh/templates/yaksh/sidebar.html @@ -0,0 +1,8 @@ +<!-- Sidebar --> +<div class="bg-light border-right" id="sidebar-wrapper"> + <div class="list-group list-group-flush"> + <a href="{% url 'yaksh:course_forum' course.id %}" class="list-group-item list-group-item-action {% if '/course_forum/' in request.path %}active{% endif %}">Course Forum</a> + <a href="{% url 'yaksh:lessons_forum' course.id %}" class="list-group-item list-group-item-action {% if '/lessons_forum/' in request.path %}active{% endif %}">Lessons Forum</a> + </div> +</div> +<!-- /#sidebar-wrapper --> diff --git a/yaksh/urls.py b/yaksh/urls.py index b60b5f5..82785ca 100644 --- a/yaksh/urls.py +++ b/yaksh/urls.py @@ -60,9 +60,11 @@ urlpatterns = [ views.get_next_unit, name='next_unit'), url(r'^course_modules/(?P<course_id>\d+)/$', views.course_modules, name='course_modules'), - url(r'^forum/(?P<course_id>\d+)/$', + url(r'^forum/course_forum/(?P<course_id>\d+)/$', views.course_forum, name='course_forum'), + url(r'^forum/lessons_forum/(?P<course_id>\d+)/$', + views.lessons_forum, name='lessons_forum'), url(r'^forum/(?P<course_id>\d+)/post/(?P<uuid>[0-9a-f-]+)/$', views.post_comments, name='post_comments'), diff --git a/yaksh/views.py b/yaksh/views.py index ae00fc6..084ec1e 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -2811,7 +2811,6 @@ def show_lesson(request, lesson_id, module_id, course_id): post = Post.objects.get( target_ct=lesson_ct, target_id=learn_unit.lesson.id, active=True, title=title, creator=user, - description=f'Discussion on {title} lesson', ) except Post.DoesNotExist: post = Post.objects.create( @@ -3519,6 +3518,27 @@ def course_forum(request, course_id): @login_required @email_verified +def lessons_forum(request, course_id): + user = request.user + base_template = 'user.html' + moderator = False + if is_moderator(user): + base_template = 'manage.html' + moderator = True + course = get_object_or_404(Course, id=course_id) + course_ct = ContentType.objects.get_for_model(course) + lesson_posts = course.get_lesson_posts(user) + return render(request, 'yaksh/lessons_forum.html', { + 'user': user, + 'base_template': base_template, + 'moderator': moderator, + 'course': course, + 'posts': lesson_posts, + }) + + +@login_required +@email_verified def post_comments(request, course_id, uuid): user = request.user base_template = 'user.html' @@ -3545,6 +3565,7 @@ def post_comments(request, course_id, uuid): 'base_template': base_template, 'form': form, 'user': user, + 'course': course }) @@ -3554,7 +3575,9 @@ def hide_post(request, course_id, uuid): user = request.user course = get_object_or_404(Course, id=course_id) if (not course.is_creator(user) or not course.is_teacher(user)): - raise Http404(f'Only a course creator or a teacher can delete the post.') + raise Http404( + 'Only a course creator or a teacher can delete the post.' + ) post = get_object_or_404(Post, uid=uuid) post.comment.active = False post.active = False @@ -3570,7 +3593,7 @@ def hide_comment(request, course_id, uuid): course = get_object_or_404(Course, id=course_id) if (not course.is_creator(user) or not course.is_teacher(user)): raise Http404( - f'Only a course creator or a teacher can delete the comments' + 'Only a course creator or a teacher can delete the comments' ) comment = get_object_or_404(Comment, uid=uuid) post_uid = comment.post_field.uid |