commit
c0b71f4dd4
15 changed files with 672 additions and 17669 deletions
@ -0,0 +1,29 @@ |
|||||||
|
# Generated by Django 2.0.1 on 2018-01-30 08:10 |
||||||
|
|
||||||
|
from django.db import migrations |
||||||
|
import django.db.models.deletion |
||||||
|
import mptt.fields |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('course', '0016_auto_20180129_1756'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='comment', |
||||||
|
name='parent', |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='coursecomment', |
||||||
|
name='parent', |
||||||
|
field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='children', to='course.CourseComment'), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='lessoncomment', |
||||||
|
name='parent', |
||||||
|
field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='children', to='course.LessonComment'), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,17 @@ |
|||||||
|
# Generated by Django 2.0.1 on 2018-01-30 12:48 |
||||||
|
|
||||||
|
from django.db import migrations |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('course', '0017_auto_20180130_0810'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AlterModelOptions( |
||||||
|
name='comment', |
||||||
|
options={'ordering': ('-created_at',)}, |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,27 @@ |
|||||||
|
{% load static %} |
||||||
|
|
||||||
|
<div id="question__{{ node.id }}" class="questions__item {% if node.is_child_node %}questions__item_reply{% endif %}"> |
||||||
|
{% if node.author.photo %} |
||||||
|
<div class="questions__ava ava"> |
||||||
|
<img class="ava__pic" src="{{ node.author.photo.url }}"> |
||||||
|
</div> |
||||||
|
{% else %} |
||||||
|
<div class="questions__ava ava"> |
||||||
|
<img class="ava__pic" src="{% static 'img/user.jpg' %}"> |
||||||
|
</div> |
||||||
|
{% endif %} |
||||||
|
<div class="questions__wrap"> |
||||||
|
<div class="questions__details"> |
||||||
|
<div class="questions__head"> |
||||||
|
<span class="questions__author">{{ node.author.get_full_name }}</span> |
||||||
|
<span class="questions__date">{{ node.created_at_humanize }}</span> |
||||||
|
</div> |
||||||
|
<div class="questions__content">{{ node.content }}</div> |
||||||
|
</div> |
||||||
|
<div class="questions__foot"> |
||||||
|
{% if user.is_authenticated %} |
||||||
|
<button class="questions__action question__reply-button" data-reply-id="{{ node.id }}">ОТВЕТИТЬ</button> |
||||||
|
{% endif %} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
@ -1,30 +1,5 @@ |
|||||||
{% load static %} |
|
||||||
{% load mptt_tags %} |
{% load mptt_tags %} |
||||||
|
|
||||||
{% recursetree course.comments.all %} |
{% recursetree object.comments.all %} |
||||||
<!-- Node template --> |
{% include './comment.html' %} |
||||||
<div class="questions__item {% if node.is_child_node %}questions__item_reply{% endif %}"> |
|
||||||
{% if node.author.photo %} |
|
||||||
<div class="questions__ava ava"> |
|
||||||
<img class="ava__pic" src="{{ node.author.photo.url }}"> |
|
||||||
</div> |
|
||||||
{% else %} |
|
||||||
<div class="questions__ava ava"> |
|
||||||
<img class="ava__pic" src="{% static 'img/user.jpg' %}"> |
|
||||||
</div> |
|
||||||
{% endif %} |
|
||||||
<div class="questions__wrap"> |
|
||||||
<div class="questions__details"> |
|
||||||
<div class="questions__head"> |
|
||||||
<span class="questions__author">{{ node.author.get_full_name }}</span> |
|
||||||
<span class="questions__date">{{ node.created_at_humanize }}</span> |
|
||||||
</div> |
|
||||||
<div class="questions__content">{{ node.content }}</div> |
|
||||||
</div> |
|
||||||
<div class="questions__foot"> |
|
||||||
<button class="questions__action">ОТВЕТИТЬ</button> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<!-- End Node template --> |
|
||||||
{{ children }} {% endrecursetree %} |
{{ children }} {% endrecursetree %} |
||||||
@ -0,0 +1,131 @@ |
|||||||
|
{% extends "templates/lilcity/index.html" %} |
||||||
|
{% load static %} |
||||||
|
{% block title %}{{ lesson.title }} - {{ block.super }}{% endblock title %} |
||||||
|
|
||||||
|
{% block content %} |
||||||
|
<div class="section"> |
||||||
|
<div class="section__center center center_sm"> |
||||||
|
<div class="go"> |
||||||
|
<a class="go__item" href="{% url 'course' lesson.course.id %}"> |
||||||
|
<div class="go__arrow"> |
||||||
|
<svg class="icon icon-arrow-left"> |
||||||
|
<use xlink:href="{% static 'img/sprite.svg' %}#icon-arrow-left"></use> |
||||||
|
</svg> |
||||||
|
</div> |
||||||
|
<div class="go__title">Вернуться к списку уроков</div> |
||||||
|
</a> |
||||||
|
<a class="go__item" href="#"> |
||||||
|
<div class="go__title">Перейти к следующему уроку</div> |
||||||
|
<div class="go__arrow"> |
||||||
|
<svg class="icon icon-arrow-right"> |
||||||
|
<use xlink:href="{% static 'img/sprite.svg' %}#icon-arrow-right"></use> |
||||||
|
</svg> |
||||||
|
</div> |
||||||
|
</a> |
||||||
|
</div> |
||||||
|
<div class="lesson"> |
||||||
|
<div class="lesson__subtitle subtitle">{{ lesson.title }}</div> |
||||||
|
<div class="lesson__content">{{ lesson.short_description }}</div> |
||||||
|
<a class="lesson__video video" href="#"> |
||||||
|
<img class="video__pic" src="{% static 'img/video-1.jpg' %}"> |
||||||
|
<svg class="icon icon-play"> |
||||||
|
<use xlink:href="{% static 'img/sprite.svg' %}#icon-play"></use> |
||||||
|
</svg> |
||||||
|
</a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="section section_gradient"> |
||||||
|
<div class="section__center center center_sm"> |
||||||
|
<div class="title">Примеры техники</div> |
||||||
|
<div class="examples"> |
||||||
|
<div class="examples__item"> |
||||||
|
<img class="examples__pic" src="{% static 'img/box.jpg' %}"> |
||||||
|
</div> |
||||||
|
<div class="examples__item"> |
||||||
|
<img class="examples__pic" src="{% static 'img/box.jpg' %}"> |
||||||
|
</div> |
||||||
|
<div class="examples__item"> |
||||||
|
<img class="examples__pic" src="{% static 'img/box.jpg' %}"> |
||||||
|
</div> |
||||||
|
<div class="examples__item"> |
||||||
|
<img class="examples__pic" src="{% static 'img/box.jpg' %}"> |
||||||
|
</div> |
||||||
|
<div class="examples__item"> |
||||||
|
<img class="examples__pic" src="{% static 'img/box.jpg' %}"> |
||||||
|
</div> |
||||||
|
<div class="examples__item"> |
||||||
|
<img class="examples__pic" src="{% static 'img/box.jpg' %}"> |
||||||
|
</div> |
||||||
|
<div class="examples__item"> |
||||||
|
<img class="examples__pic" src="{% static 'img/box.jpg' %}"> |
||||||
|
</div> |
||||||
|
<div class="examples__item"> |
||||||
|
<img class="examples__pic" src="{% static 'img/box.jpg' %}"> |
||||||
|
</div> |
||||||
|
<div class="examples__item"> |
||||||
|
<img class="examples__pic" src="{% static 'img/box.jpg' %}"> |
||||||
|
</div> |
||||||
|
<div class="examples__item"> |
||||||
|
<img class="examples__pic" src="{% static 'img/box.jpg' %}"> |
||||||
|
</div> |
||||||
|
<div class="examples__item"> |
||||||
|
<img class="examples__pic" src="{% static 'img/box.jpg' %}"> |
||||||
|
</div> |
||||||
|
<div class="examples__item"> |
||||||
|
<img class="examples__pic" src="{% static 'img/box.jpg' %}"> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="section section_gray"> |
||||||
|
<div class="section__center center center_sm"> |
||||||
|
<div class="title">Задавайте вопросы:</div> |
||||||
|
<div class="questions"> |
||||||
|
<div class="questions__form"> |
||||||
|
<div class="questions__ava ava"> |
||||||
|
<img class="ava__pic" src="{% static 'img/user.jpg' %}"> |
||||||
|
</div> |
||||||
|
<div class="questions__wrap"> |
||||||
|
<div class="questions__field"> |
||||||
|
<textarea class="questions__textarea" placeholder="Спросите автора курса интересующие вас вопросы"></textarea> |
||||||
|
</div> |
||||||
|
<button class="questions__btn btn btn_light">ОТПРАВИТЬ</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="questions__list"> |
||||||
|
{% include "./blocks/comments.html" with object=lesson %} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="section"> |
||||||
|
<div class="section__center center center_sm"> |
||||||
|
<div class="share"> |
||||||
|
<div class="share__title">Поделиться уроком</div> |
||||||
|
<div class="share__list"> |
||||||
|
<a class="share__item" href="#"> |
||||||
|
<svg class="icon icon-share-facebook"> |
||||||
|
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-facebook"></use> |
||||||
|
</svg> |
||||||
|
</a> |
||||||
|
<a class="share__item" href="#"> |
||||||
|
<svg class="icon icon-share-twitter"> |
||||||
|
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-twitter"></use> |
||||||
|
</svg> |
||||||
|
</a> |
||||||
|
<a class="share__item" href="#"> |
||||||
|
<svg class="icon icon-share-google"> |
||||||
|
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-google"></use> |
||||||
|
</svg> |
||||||
|
</a> |
||||||
|
<a class="share__item" href="#"> |
||||||
|
<svg class="icon icon-share-pinterest"> |
||||||
|
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-pinterest"></use> |
||||||
|
</svg> |
||||||
|
</a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endblock content %} |
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,60 @@ |
|||||||
|
import $ from 'jquery'; |
||||||
|
|
||||||
|
$(document).ready(function () { |
||||||
|
// Обработчик отправки комментария. Нам не важно, комментарий к курсу или к уроку - URL берется из action формы
|
||||||
|
$('form.questions__form').on('submit', function (e) { |
||||||
|
e.preventDefault(); |
||||||
|
|
||||||
|
const submitButton = $(this).find('button.questions__action'); |
||||||
|
const replyToInput = $(this).find('input[name=reply_id]'); |
||||||
|
const replyToValue = replyToInput.val() ? parseInt(replyToInput.val()) : 0; |
||||||
|
const commentTextarea = $(this).find('textarea.questions__textarea'); |
||||||
|
commentTextarea.attr('disabled', 'disabled'); |
||||||
|
submitButton.attr('disabled', 'disabled'); |
||||||
|
|
||||||
|
$.ajax($(this).attr('action'), { |
||||||
|
method: 'post', |
||||||
|
data: { |
||||||
|
reply_id: replyToValue, |
||||||
|
comment: commentTextarea.val(), |
||||||
|
} |
||||||
|
}) |
||||||
|
.done(function (data) { |
||||||
|
console.log(data); |
||||||
|
if (data.success === true) { |
||||||
|
if (replyToValue > 0) { |
||||||
|
$(`#question__${replyToValue}`).after(data.comment); |
||||||
|
} else { |
||||||
|
$('.questions__list').append(data.comment); |
||||||
|
} |
||||||
|
|
||||||
|
commentTextarea.val(''); |
||||||
|
} |
||||||
|
}) |
||||||
|
.fail(function (xhr) { |
||||||
|
|
||||||
|
}) |
||||||
|
.always(function () { |
||||||
|
commentTextarea.removeAttr('disabled'); |
||||||
|
submitButton.removeAttr('disabled'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
// Обработчик кнопки "Ответить"
|
||||||
|
$('.questions__list').on('click', 'button.question__reply-button', function () { |
||||||
|
const replyId = $(this).attr('data-reply-id'); |
||||||
|
const form = $('form.questions__form'); |
||||||
|
form.find('input[name=reply_id]').val(replyId); |
||||||
|
form.find('.questions__reply-anchor').attr('href', `#question__${replyId}`); |
||||||
|
form.find('.questions__reply-info').show(); |
||||||
|
}); |
||||||
|
|
||||||
|
// Обработчик отмены комментирования в ответ на комментарий
|
||||||
|
$('.questions__reply-cancel').on('click', function (e) { |
||||||
|
e.preventDefault(); |
||||||
|
|
||||||
|
const form = $('form.questions__form'); |
||||||
|
form.find('input[name=reply_id]').val(0); |
||||||
|
form.find('.questions__reply-info').hide(); |
||||||
|
}); |
||||||
|
}); |
||||||
Loading…
Reference in new issue