Merge remote-tracking branch 'origin/master'

remotes/origin/hotfix/LIL-661
nikita 8 years ago
commit 6767ce67d9
  1. 4
      api/v1/serializers/content.py
  2. 5
      api/v1/serializers/course.py
  3. 11
      apps/content/admin.py
  4. 6
      apps/content/models.py
  5. 12
      apps/content/templates/content/contest_work.html
  6. 18
      apps/course/migrations/0042_like_ip.py
  7. 4
      apps/course/models.py
  8. 28
      apps/course/templates/course/course_only_lessons.html
  9. 2
      apps/course/templates/course/lesson.html
  10. 2
      apps/payment/templates/payment/payment_success.html
  11. 17
      apps/payment/views.py
  12. 10
      apps/school/models.py
  13. 4
      apps/school/templates/blocks/day_pay_btn.html
  14. 2
      apps/school/templates/blocks/online.html
  15. 2
      apps/school/templates/blocks/promo.html
  16. 14
      apps/school/templates/blocks/schedule_item.html
  17. 2
      apps/school/templates/school/livelesson_detail.html
  18. 2
      apps/school/templates/school/livelessons_list.html
  19. 4
      apps/school/templates/summer/online.html
  20. 12
      apps/school/templates/summer/promo.html
  21. 6
      apps/school/templates/summer/schedule_purchased.html
  22. 3
      apps/school/urls.py
  23. 89
      apps/school/views.py
  24. 2
      apps/user/forms.py
  25. 18
      apps/user/migrations/0023_user_trial_lesson.py
  26. 1
      apps/user/models.py
  27. 13
      apps/user/templates/user/profile-settings.html
  28. 8
      apps/user/templates/user/profile.html
  29. 5
      apps/user/views.py
  30. 1
      project/settings.py
  31. 22
      project/templates/blocks/about.html
  32. 1
      project/templates/blocks/footer.html
  33. 11
      project/templates/blocks/header.html
  34. 2
      project/templates/blocks/last_courses.html
  35. 4
      project/templates/blocks/live.html
  36. 20
      project/templates/blocks/partners.html
  37. 12
      project/templates/blocks/popup_auth.html
  38. 2
      project/templates/blocks/popup_buy.html
  39. 17
      project/templates/blocks/promo.html
  40. 29
      project/templates/blocks/share.html
  41. 17
      project/templates/blocks/teachers.html
  42. 1
      project/templates/lilcity/index.html
  43. 4
      project/views.py
  44. 2
      requirements.txt
  45. 30
      web/src/components/ContestWorks.vue
  46. 2
      web/src/components/blocks/ContestWork.vue
  47. 8
      web/src/components/blocks/Image.vue
  48. 2
      web/src/js/app.js
  49. 28
      web/src/js/modules/auth.js
  50. 37
      web/src/js/modules/popup.js
  51. 19
      web/src/sass/_common.sass

@ -85,12 +85,16 @@ class ImageObjectSerializer(serializers.ModelSerializer):
image = Base64ImageField( image = Base64ImageField(
required=True, allow_empty_file=False, allow_null=False, read_only=False, required=True, allow_empty_file=False, allow_null=False, read_only=False,
) )
image_thumbnail = Base64ImageField(
required=False, allow_empty_file=True, allow_null=True, read_only=True,
)
class Meta: class Meta:
model = ImageObject model = ImageObject
fields = ( fields = (
'id', 'id',
'image', 'image',
'image_thumbnail',
'created_at', 'created_at',
'update_at', 'update_at',
) )

@ -1,3 +1,5 @@
from ipware import get_client_ip
from rest_framework import serializers from rest_framework import serializers
from rest_framework.validators import UniqueValidator from rest_framework.validators import UniqueValidator
@ -88,13 +90,14 @@ class LikeCreateSerializer(serializers.ModelSerializer):
return Like() return Like()
obj_type = validated_data.pop('obj_type') obj_type = validated_data.pop('obj_type')
obj_id = validated_data.pop('obj_id') obj_id = validated_data.pop('obj_id')
client_ip, is_routable = get_client_ip(self.context['request'])
if obj_type == self.OBJ_TYPE_CONTEST_WORK: if obj_type == self.OBJ_TYPE_CONTEST_WORK:
contest_work = ContestWork.objects.get(pk=obj_id) contest_work = ContestWork.objects.get(pk=obj_id)
# FIXME in prod: fixed # FIXME in prod: fixed
if contest_work.user == user or contest_work.likes.filter(user=user).exists(): if contest_work.user == user or contest_work.likes.filter(user=user).exists():
# if contest_work.likes.filter(user=user).exists(): # if contest_work.likes.filter(user=user).exists():
return Like() return Like()
like = Like.objects.create(user=user) like = Like.objects.create(user=user, ip=client_ip)
contest_work.likes.add(like) contest_work.likes.add(like)
return like return like

@ -8,6 +8,7 @@ from polymorphic.admin import (
from apps.content.models import ( from apps.content.models import (
Baner, Content, Image, Text, ImageText, Video, Baner, Content, Image, Text, ImageText, Video,
Gallery, GalleryImage, ImageObject, Gallery, GalleryImage, ImageObject,
Contest,ContestWork,
) )
@ -79,3 +80,13 @@ class ContentAdmin(PolymorphicParentModelAdmin):
@admin.register(GalleryImage) @admin.register(GalleryImage)
class GalleryImageAdmin(admin.ModelAdmin): class GalleryImageAdmin(admin.ModelAdmin):
pass pass
@admin.register(Contest)
class ContestAdmin(admin.ModelAdmin):
base_model = Contest
@admin.register(ContestWork)
class ContestWorkAdmin(admin.ModelAdmin):
base_model = ContestWork

@ -2,6 +2,8 @@ from urllib.parse import urlparse
from django.db import models from django.db import models
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.urls import reverse_lazy from django.urls import reverse_lazy
from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToCover
from polymorphic.models import PolymorphicModel from polymorphic.models import PolymorphicModel
@ -11,6 +13,10 @@ User = get_user_model()
class ImageObject(models.Model): class ImageObject(models.Model):
image = models.ImageField('Изображение', upload_to='content/imageobject') image = models.ImageField('Изображение', upload_to='content/imageobject')
image_thumbnail = ImageSpecField(source='image',
processors=[ResizeToCover(300, 200, False)],
format='JPEG',
options={'quality': 85})
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True) update_at = models.DateTimeField(auto_now=True)

@ -1,8 +1,14 @@
{% extends "templates/lilcity/index.html" %} {% extends "templates/lilcity/index.html" %}
{% load rupluralize from plural %}
{% load static %} {% load static %}
{% block title %}{{ contest_work.child_full_name }}, {{ contest_work.age }} лет{% endblock title %} {% block title %}Конкурс Lil.School{% endblock title %}
{% block description %}Работа {{ contest_work.child_full_name }}, {{ contest_work.age | rupluralize:"год,года,лет" }}{% endblock description%}
{% block ogdescription %}Работа {{ contest_work.child_full_name }}, {{ contest_work.age | rupluralize:"год,года,лет" }}{% endblock ogdescription %}
{% block ogimage %}http://{{request.META.HTTP_HOST}}{{ contest_work.image.image.url }}{% endblock ogimage %} {% block ogimage %}http://{{request.META.HTTP_HOST}}{{ contest_work.image.image.url }}{% endblock ogimage %}
{% block head %}
<meta property="og:image:height" content="{{ contest_work.image.image.height }}">
<meta property="og:image:width" content="{{ contest_work.image.image.width }}">
{% endblock head %}
{% block content %} {% block content %}
<div class="section" style="padding-bottom: 25px;"> <div class="section" style="padding-bottom: 25px;">
@ -25,7 +31,7 @@
<div class="contest-work__info"> <div class="contest-work__info">
<div class="contest-work__bio"> <div class="contest-work__bio">
<div>{{ contest_work.child_full_name }}</div> <div>{{ contest_work.child_full_name }}</div>
<div class="contest-work__age">{{ contest_work.age }} {% if contest_work.age < 5 %}года{% else %}лет{% endif %}</div> <div class="contest-work__age">{{ contest_work.age | rupluralize:"год,года,лет" }}</div>
</div> </div>
<div class="contest-work__likes"> <div class="contest-work__likes">
<likes obj-type="contest_work" obj-id="{{ contest_work.id }}" <likes obj-type="contest_work" obj-id="{{ contest_work.id }}"

@ -0,0 +1,18 @@
# Generated by Django 2.0.6 on 2018-08-16 16:45
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('course', '0041_auto_20180813_1306'),
]
operations = [
migrations.AddField(
model_name='like',
name='ip',
field=models.GenericIPAddressField(blank=True, null=True),
),
]

@ -4,7 +4,6 @@ from uuid import uuid4
from django.db import models from django.db import models
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils import timezone from django.utils import timezone
from django.utils.text import slugify
from django.utils.timezone import now from django.utils.timezone import now
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.urls import reverse_lazy from django.urls import reverse_lazy
@ -13,8 +12,6 @@ from polymorphic_tree.models import PolymorphicMPTTModel, PolymorphicTreeForeign
from project.mixins import BaseModel, DeactivatedMixin from project.mixins import BaseModel, DeactivatedMixin
from .manager import CategoryQuerySet
from apps.content.models import ImageObject, Gallery, Video, ContestWork from apps.content.models import ImageObject, Gallery, Video, ContestWork
User = get_user_model() User = get_user_model()
@ -22,6 +19,7 @@ User = get_user_model()
class Like(models.Model): class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE)
ip = models.GenericIPAddressField(blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True) update_at = models.DateTimeField(auto_now=True)

@ -184,7 +184,7 @@
<div class="lessons__preview"> <div class="lessons__preview">
<div class="lessons__pic-wrapper"> <div class="lessons__pic-wrapper">
<img class="lessons__pic" <img class="lessons__pic"
src="{% if lesson.cover %}{{ lesson.cover.image.url }}{% else %}{% static 'img/no_cover.png' %}{% endif %}"> src="{% if lesson.cover %}{{ lesson.cover.image_thumbnail.url }}{% else %}{% static 'img/no_cover.png' %}{% endif %}">
</div> </div>
</div> </div>
<div> <div>
@ -233,31 +233,7 @@
</div> </div>
<div class="section"> <div class="section">
<div class="section__center center center_sm"> <div class="section__center center center_sm">
<div class="share"> {% include 'templates/blocks/share.html' with share_object_name='курсом' %}
<div class="share__title">Поделиться курсом</div>
<div class="share__list likely">
<a class="share__item facebook" href="#">
<svg class="icon icon-share-facebook">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-facebook"></use>
</svg>
</a>
<a class="share__item twitter" href="#">
<svg class="icon icon-share-twitter">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-twitter"></use>
</svg>
</a>
<a class="share__item gplus" href="#">
<svg class="icon icon-share-google">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-google"></use>
</svg>
</a>
<a class="share__item pinterest" href="#">
<svg class="icon icon-share-pinterest">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-pinterest"></use>
</svg>
</a>
</div>
</div>
</div> </div>
</div> </div>
{% endblock content %} {% endblock content %}

@ -31,7 +31,7 @@
<div class="lesson__preview"> <div class="lesson__preview">
<div class="lesson__pic-wrapper"> <div class="lesson__pic-wrapper">
<img class="lesson__pic" <img class="lesson__pic"
src="{% if lesson.cover %}{{ lesson.cover.image.url }}{% else %}{% static 'img/no_cover.png' %}{% endif %}"> src="{% if lesson.cover %}{{ lesson.cover.image_thumbnail.url }}{% else %}{% static 'img/no_cover.png' %}{% endif %}">
</div> </div>
</div> </div>
<div> <div>

@ -5,7 +5,7 @@
{% if school %} {% if school %}
<div class="done__title title">Вы успешно приобрели доступ к урокам онлайн-школы!</div> <div class="done__title title">Вы успешно приобрели доступ к урокам онлайн-школы!</div>
<div class="done__foot"> <div class="done__foot">
<a class="done__btn btn btn_md btn_stroke" href="{% url 'user' request.user.id %}">ПЕРЕЙТИ К ШКОЛЕ</a> <a class="done__btn btn btn_md btn_stroke" href="{% url 'school:school' %}">ПЕРЕЙТИ К ШКОЛЕ</a>
</div> </div>
{% else %} {% else %}
<div class="done__title title">Вы успешно приобрели курс!</div> <div class="done__title title">Вы успешно приобрели курс!</div>

@ -109,12 +109,15 @@ class SchoolBuyView(TemplateView):
messages.error(request, 'Ошибка выбора дней недели.') messages.error(request, 'Ошибка выбора дней недели.')
return redirect('school:summer-school') return redirect('school:summer-school')
if add_days: if add_days:
_school_payment = SchoolPayment.objects.get( _school_payment = SchoolPayment.objects.filter(
user=request.user, user=request.user,
date_start__lte=now().date(), date_start__lte=now().date(),
date_end__gte=now().date(), date_end__gte=now().date(),
add_days=False, add_days=False,
) ).first()
if not _school_payment:
add_days = False
if add_days:
school_payment = SchoolPayment.objects.create( school_payment = SchoolPayment.objects.create(
user=request.user, user=request.user,
weekdays=weekdays, weekdays=weekdays,
@ -175,6 +178,7 @@ class PaymentwallCallbackView(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
payment_raw_data = request.GET.copy() payment_raw_data = request.GET.copy()
pingback = Pingback(payment_raw_data, self.get_request_ip()) pingback = Pingback(payment_raw_data, self.get_request_ip())
september2018 = datetime.date(2018, 9, 1)
if pingback.validate(): if pingback.validate():
product_type_name, payment_id = pingback.get_product().get_id().split('_') product_type_name, payment_id = pingback.get_product().get_id().split('_')
@ -223,16 +227,15 @@ class PaymentwallCallbackView(View):
).last() ).last()
if school_payment: if school_payment:
if payment.add_days: if payment.add_days:
date_start = self.add_months(sourcedate=now().replace(hour=0, minute=0, day=1), months=1) date_start = now().date()
date_end = school_payment.date_end date_end = school_payment.date_end
else: else:
date_start = arrow.get(school_payment.date_end, settings.TIME_ZONE).shift(days=1).datetime date_start = arrow.get(school_payment.date_end, settings.TIME_ZONE).shift(days=1).datetime
date_end = arrow.get(date_start, settings.TIME_ZONE).shift(months=1).datetime date_end = arrow.get(date_start, settings.TIME_ZONE).shift(months=1).datetime
else: else:
#month = 0 if now().day >= 1 and now().day <= 10 else 1 date_start = now().date()
# Логика июльского лагеря: до конца июля приобретаем только на текущий месяц if date_start < september2018:
month = 0 date_start = september2018
date_start = self.add_months(sourcedate=now().replace(hour=0, minute=0, day=1), months=month)
date_end = arrow.get(date_start, settings.TIME_ZONE).shift(months=1, minutes=-1).datetime date_end = arrow.get(date_start, settings.TIME_ZONE).shift(months=1, minutes=-1).datetime
payment.date_start = date_start payment.date_start = date_start
payment.date_end = date_end payment.date_end = date_end

@ -1,9 +1,10 @@
import arrow import arrow
from datetime import datetime, timedelta from datetime import datetime, timedelta, date
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.functional import cached_property
from django.utils.timezone import now from django.utils.timezone import now
from project.mixins import BaseModel, DeactivatedMixin from project.mixins import BaseModel, DeactivatedMixin
@ -50,15 +51,18 @@ class SchoolSchedule(models.Model):
end_at = datetime.combine(now().today(), self.start_at) + timedelta(hours=1) end_at = datetime.combine(now().today(), self.start_at) + timedelta(hours=1)
return self.start_at <= now().time() and end_at.time() >= now().time() and self.weekday == now().isoweekday() return self.start_at <= now().time() and end_at.time() >= now().time() and self.weekday == now().isoweekday()
@cached_property
def current_live_lesson(self): def current_live_lesson(self):
now_time = now() september2018 = date(2018, 9, 1)
date_start = max(september2018, now().date())
live_lesson = LiveLesson.objects.filter( live_lesson = LiveLesson.objects.filter(
date__week_day=self.weekday % 7 + 1, date__week_day=self.weekday % 7 + 1,
date__range=[now_time.date(), (now_time + timedelta(days=6)).date()], date__range=[date_start, date_start + timedelta(days=6)],
deactivated_at__isnull=True, deactivated_at__isnull=True,
).first() ).first()
return live_lesson return live_lesson
@cached_property
def previous_live_lesson(self): def previous_live_lesson(self):
now_time = now() now_time = now()
live_lesson = LiveLesson.objects.filter( live_lesson = LiveLesson.objects.filter(

@ -1,7 +1,5 @@
<a <a
{% if not user.is_authenticated %} data-popup=".js-popup-buy"
data-popup=".js-popup-auth"
{% endif %}
class="timing__btn btn" class="timing__btn btn"
href="{% url 'school-checkout' %}?weekdays={{ school_schedule.weekday }}&add_days=true" href="{% url 'school-checkout' %}?weekdays={{ school_schedule.weekday }}&add_days=true"
>купить</a> >купить</a>

@ -1,7 +1,7 @@
{% load static %} {% load static %}
<a class="online" target="_blank" href="https://www.youtube.com/watch?v=PhZ8qQbIej0" style="background-image: url({% static 'img/video-1.jpg' %});"> <a class="online" target="_blank" href="https://www.youtube.com/watch?v=PhZ8qQbIej0" style="background-image: url({% static 'img/video-1.jpg' %});">
<div class="online__center center"> <div class="online__center center">
<div class="online__type">ПРЯМОЙ ЭФИР</div> <div class="online__type">ВИДЕОУРОКИ</div>
<div class="online__title">Каждый день в 17.00 (по Мск) </div> <div class="online__title">Каждый день в 17.00 (по Мск) </div>
<div class="online__text text">Кроме выходных. Запись эфира доступна по завершению трансляции</div> <div class="online__text text">Кроме выходных. Запись эфира доступна по завершению трансляции</div>
<div class="online__action"> <div class="online__action">

@ -17,7 +17,7 @@
<use xlink:href="{% static 'img/sprite.svg' %}#icon-online"></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-online"></use>
</svg> </svg>
</div> </div>
<div class="school__title">Прямой эфир</div> <div class="school__title">Видеоуроки</div>
<div class="school__text">С понедельника по&nbsp;пятницу кроме выходных</div> <div class="school__text">С понедельника по&nbsp;пятницу кроме выходных</div>
</div> </div>
<div class="school__col"> <div class="school__col">

@ -5,19 +5,17 @@
<div class="timing__day{% if school_schedule.is_online %} active{% endif %}"> <div class="timing__day{% if school_schedule.is_online %} active{% endif %}">
{{ school_schedule }} {{ school_schedule }}
</div> </div>
{% if purchased and live_lesson %} {% if is_purchased and live_lesson %}
<div class="timing__date">{{ live_lesson.date }}</div> <div class="timing__date">{{ live_lesson.date }}</div>
{% endif %} {% endif %}
<div class="timing__time">{{ school_schedule.start_at }} (МСК)</div> <div class="timing__time">{{ school_schedule.start_at }} (МСК)</div>
<div class="timing__buy"> <div class="timing__buy">
{% if purchased %} {% if is_purchased %}
{% if school_schedule.weekday in school_schedules_purchased %} {% if school_schedule.weekday in school_schedules_purchased and live_lesson and live_lesson.title %}
{% if live_lesson and live_lesson.title %} {% include './open_lesson.html' %}
{% include './open_lesson.html' %}
{% endif %}
{% else %}
{% include './day_pay_btn.html' %}
{% endif %} {% endif %}
{% else %}
{% include './day_pay_btn.html' %}
{% endif %} {% endif %}
</div> </div>
</div> </div>

@ -26,7 +26,7 @@
</div> </div>
{% for content in livelesson.content.all %} {% for content in livelesson.content.all %}
{% with template="course/content/"|add:content.ctype|add:".html" %} {% with template="content/blocks/"|add:content.ctype|add:".html" %}
{% include template %} {% include template %}
{% endwith %} {% endwith %}

@ -9,7 +9,7 @@
<div class="kit__body"> <div class="kit__body">
<div class="lessons__list"> <div class="lessons__list">
{% for livelesson in livelesson_list %} {% for livelesson in livelesson_list %}
<div class="lessons__item" v-for="(lesson, index) in lessons"> <div class="lessons__item">
<div class="lessons__actions lessons__actions__no-hover"> <div class="lessons__actions lessons__actions__no-hover">
<a target="_blank" class="lessons__action" href="{% url 'school:lesson-detail' livelesson.id %}"> <a target="_blank" class="lessons__action" href="{% url 'school:lesson-detail' livelesson.id %}">
<svg class="icon icon-eye"> <svg class="icon icon-eye">

@ -1,9 +1,9 @@
{% load static %} {% load static %}
<a class="online" target="_blank" href="https://www.youtube.com/watch?v=PhZ8qQbIej0" style="background-image: url({% static 'img/video-1.jpg' %});"> <a class="online" target="_blank" href="https://www.youtube.com/watch?v=PhZ8qQbIej0" style="background-image: url({% static 'img/video-1.jpg' %});">
<div class="online__center center"> <div class="online__center center">
<div class="online__type">ПРЯМОЙ ЭФИР</div> <div class="online__type">ВИДЕОУРОКИ</div>
<div class="online__title">В 17.00 (по Мск) </div> <div class="online__title">В 17.00 (по Мск) </div>
<div class="online__text text">Понедельник, среда, пятница.</div> <div class="online__text text">Каждый день с 1 сентября</div>
<div class="online__action"> <div class="online__action">
<svg class="icon icon-play"> <svg class="icon icon-play">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-play"></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-play"></use>

@ -5,21 +5,17 @@
<span class="main__bold">Lil School</span> — первая образовательная онлайн-платформа креативного мышления для детей <span class="main__bold">Lil School</span> — первая образовательная онлайн-платформа креативного мышления для детей
</div> </div>
<div class="main__subtitle"> <div class="main__subtitle">
Присоединяйтесь в Рисовальный лагерь Старт школы - 1 сентября
</div> </div>
<div class="main__actions"> <div class="main__actions">
<a <a
{% if not is_purchased_future %} {% if not is_purchased_future %}
{% if not user.is_authenticated %}
data-popup=".js-popup-auth"
{% else %}
data-popup=".js-popup-buy" data-popup=".js-popup-buy"
{% endif %}
{% endif %} {% endif %}
class="main__btn btn" class="main__btn btn"
href="#" href="#"
> >
{% if not is_purchased and not is_purchased_future %}Получить доступ{% endif %} {% if not is_purchased and not is_purchased_future %}Купить доступ от {{ min_school_price }} руб./месяц{% endif %}
{% if is_purchased_future and not is_purchased %}ваша подписка начинается {{school_purchased_future.date_start}}{% endif %} {% if is_purchased_future and not is_purchased %}ваша подписка начинается {{school_purchased_future.date_start}}{% endif %}
{% if is_purchased %}ваша подписка истекает {{ subscription_ends_humanize }}<br/>перейти к оплате{% endif %} {% if is_purchased %}ваша подписка истекает {{ subscription_ends_humanize }}<br/>перейти к оплате{% endif %}
</a> </a>
@ -32,8 +28,8 @@
<use xlink:href="{% static 'img/sprite.svg' %}#icon-online"></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-online"></use>
</svg> </svg>
</div> </div>
<div class="school__title">Прямой эфир</div> <div class="school__title">Видеоуроки</div>
<div class="school__text">Понедельник, среда, пятница</div> <div class="school__text">Каждый день с 1 сентября</div>
</div> </div>
<div class="school__col"> <div class="school__col">
<div class="school__preview"> <div class="school__preview">

@ -26,14 +26,12 @@
<div class="casing__title title">Новые уроки</div> <div class="casing__title title">Новые уроки</div>
{% endif %} {% endif %}
{% comment %}
<label class="casing__switcher switcher"> <label class="casing__switcher switcher">
<span class="switcher__wrap"> <span class="switcher__wrap">
<a href="{% url 'school:summer-school' %}?is_previous=true" class="switcher__item{% if is_previous %} active{% endif %}">запись уроков</a> <a href="{% url 'school:school' %}?is_previous=true" class="switcher__item{% if is_previous %} active{% endif %}">запись уроков</a>
<a href="{% url 'school:summer-school' %}" class="switcher__item{% if not is_previous %} active{% endif %}">новые уроки</a> <a href="{% url 'school:school' %}" class="switcher__item{% if not is_previous %} active{% endif %}">новые уроки</a>
</span> </span>
</label> </label>
{% endcomment %}
</div> </div>
{% endif %} {% endif %}
<div class="casing__timing timing js-timing"> <div class="casing__timing timing js-timing">

@ -3,12 +3,11 @@ from django.urls import path, include
from .views import ( from .views import (
LiveLessonsView, LiveLessonEditView, LiveLessonsView, LiveLessonEditView,
LiveLessonsDetailView, SchoolView, LiveLessonsDetailView, SchoolView,
SchoolSchedulesPrintView, SummerSchoolView, SchoolSchedulesPrintView,
) )
urlpatterns = [ urlpatterns = [
path('', SchoolView.as_view(), name='school'), path('', SchoolView.as_view(), name='school'),
path('summer', SummerSchoolView.as_view(), name='summer-school'),
path('schedules/print', SchoolSchedulesPrintView.as_view(), name='school_schedules-print'), path('schedules/print', SchoolSchedulesPrintView.as_view(), name='school_schedules-print'),
path('lessons/', LiveLessonsView.as_view(), name='lessons'), path('lessons/', LiveLessonsView.as_view(), name='lessons'),
path('lessons/create', LiveLessonEditView.as_view(), name='lessons-create'), path('lessons/create', LiveLessonEditView.as_view(), name='lessons-create'),

@ -1,4 +1,4 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta, date
from paymentwall import Pingback from paymentwall import Pingback
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
@ -34,19 +34,22 @@ class LiveLessonsView(ListView):
template_name = 'school/livelessons_list.html' template_name = 'school/livelessons_list.html'
def get_queryset(self): def get_queryset(self):
september2018 = date(2018, 9, 1)
date_start = (now() - timedelta(days=7)).date()
if date_start < september2018:
date_start = september2018
date_range = Q( date_range = Q(
date__range=[ date__range=[
(now() - timedelta(days=7)).date(), date_start,
(now() + timedelta(days=10)).date(), date_start + timedelta(days=17),
] ]
) )
queryset = LiveLesson.objects.filter(date_range) queryset = LiveLesson.objects.filter(date_range)
if queryset.count() < 17: if queryset.count() < 17:
start_date = now() - timedelta(days=7)
for i in range(18): for i in range(18):
try: try:
LiveLesson.objects.create( LiveLesson.objects.create(
date=(start_date + timedelta(days=i)).date(), date=date_start + timedelta(days=i),
) )
except IntegrityError: except IntegrityError:
pass pass
@ -61,6 +64,7 @@ class LiveLessonsDetailView(DetailView):
def get(self, request, pk=None): def get(self, request, pk=None):
response = super().get(request, pk=pk) response = super().get(request, pk=pk)
# ??? где проверка?
#try: #try:
# school_payment = SchoolPayment.objects.get( # school_payment = SchoolPayment.objects.get(
# user=request.user, # user=request.user,
@ -107,75 +111,8 @@ class LiveLessonEditView(TemplateView):
class SchoolView(TemplateView): class SchoolView(TemplateView):
template_name = 'school/school.html'
def get_context_data(self):
context = super().get_context_data()
is_previous = 'is_previous' in self.request.GET
date_now = now().date()
now_time = now()
try:
school_schedule = SchoolSchedule.objects.get(weekday=now_time.isoweekday())
except SchoolSchedule.DoesNotExist:
online = False
else:
end_at = datetime.combine(now_time.today(), school_schedule.start_at)
online = (
school_schedule.start_at <= now_time.time() and
(end_at + timedelta(hours=1)).time() >= now_time.time() and
school_schedule.current_live_lesson()
)
if self.request.user.is_authenticated:
school_payment = SchoolPayment.objects.filter(
user=self.request.user,
status__in=[
Pingback.PINGBACK_TYPE_REGULAR,
Pingback.PINGBACK_TYPE_GOODWILL,
Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,
],
date_start__lte=date_now,
date_end__gte=date_now
)
school_payment_exists = school_payment.exists()
school_schedules_purchased = school_payment.annotate(
joined_weekdays=Func(F('weekdays'), function='unnest',)
).values_list('joined_weekdays', flat=True).distinct()
else:
school_payment_exists = False
school_schedules_purchased = []
if school_payment_exists and is_previous:
live_lessons = LiveLesson.objects.filter(
date__gte=school_payment.last().date_start,
date__range=[(now_time - timedelta(days=8)).date(), (now_time - timedelta(days=1)).date()],
deactivated_at__isnull=True,
)
live_lessons_exists = live_lessons.exists()
else:
live_lessons = None
live_lessons_exists = False
context.update({
'online': online,
'live_lessons': live_lessons,
'live_lessons_exists': live_lessons_exists,
'is_previous': is_previous,
'course_items': Course.objects.filter(status=Course.PUBLISHED)[:6],
'is_purchased': school_payment_exists,
'min_school_price': SchoolSchedule.objects.aggregate(Min('month_price'))['month_price__min'],
'school_schedules': SchoolSchedule.objects.all(),
'school_schedules_purchased': school_schedules_purchased,
'subscription_ends': school_payment.filter(add_days=False).first().date_end if school_payment_exists else None,
})
return context
class SummerSchoolView(TemplateView):
template_name = 'school/summer_school.html' template_name = 'school/summer_school.html'
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
if not context.get('is_purchased'):
return redirect('/')
return self.render_to_response(context)
def get_context_data(self): def get_context_data(self):
context = super().get_context_data() context = super().get_context_data()
is_previous = 'is_previous' in self.request.GET is_previous = 'is_previous' in self.request.GET
@ -193,10 +130,14 @@ class SummerSchoolView(TemplateView):
online = ( online = (
school_schedule.start_at <= now_time.time() and school_schedule.start_at <= now_time.time() and
(end_at + timedelta(hours=1)).time() >= now_time.time() and (end_at + timedelta(hours=1)).time() >= now_time.time() and
school_schedule.current_live_lesson() school_schedule.current_live_lesson
) )
school_schedules = SchoolSchedule.objects.all() school_schedules = SchoolSchedule.objects.all()
try:
school_schedules = sorted(school_schedules, key=lambda ss: ss.current_live_lesson and ss.current_live_lesson.date)
except Exception:
pass
school_schedules_dict = {ss.weekday: ss for ss in school_schedules} school_schedules_dict = {ss.weekday: ss for ss in school_schedules}
school_schedules_dict[0] = school_schedules_dict.get(7) school_schedules_dict[0] = school_schedules_dict.get(7)
all_schedules_purchased = [] all_schedules_purchased = []
@ -250,7 +191,7 @@ class SummerSchoolView(TemplateView):
school_schedules_purchased = [] school_schedules_purchased = []
if all_schedules_purchased and is_previous: if all_schedules_purchased and is_previous:
live_lessons = LiveLesson.objects.filter( live_lessons = LiveLesson.objects.filter(
date__range=[month_start, yesterday], date__range=[yesterday - timedelta(days=7), yesterday],
deactivated_at__isnull=True, deactivated_at__isnull=True,
date__week_day__in=all_schedules_purchased, date__week_day__in=all_schedules_purchased,
).order_by('-date') ).order_by('-date')

@ -18,6 +18,7 @@ class UserEditForm(forms.ModelForm):
# gender = forms.ChoiceField(choices=User.GENDER_CHOICES, required=False) # gender = forms.ChoiceField(choices=User.GENDER_CHOICES, required=False)
gender = forms.CharField(required=False) gender = forms.CharField(required=False)
# about = forms.CharField() # about = forms.CharField()
trial_lesson = forms.URLField(required=False)
old_password = forms.CharField(required=False) old_password = forms.CharField(required=False)
new_password1 = forms.CharField(required=False) new_password1 = forms.CharField(required=False)
new_password2 = forms.CharField(required=False) new_password2 = forms.CharField(required=False)
@ -41,6 +42,7 @@ class UserEditForm(forms.ModelForm):
'birthday', 'birthday',
'gender', 'gender',
'about', 'about',
'trial_lesson',
'old_password', 'old_password',
'new_password1', 'new_password1',
'new_password2', 'new_password2',

@ -0,0 +1,18 @@
# Generated by Django 2.0.6 on 2018-08-22 12:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('user', '0022_user_instagram_hashtag'),
]
operations = [
migrations.AddField(
model_name='user',
name='trial_lesson',
field=models.URLField(blank=True, default='', null=True),
),
]

@ -75,6 +75,7 @@ class User(AbstractUser):
) )
photo = models.ImageField('Фото', null=True, blank=True, upload_to='users') photo = models.ImageField('Фото', null=True, blank=True, upload_to='users')
show_in_mainpage = models.BooleanField('Показывать на главной странице', default=False) show_in_mainpage = models.BooleanField('Показывать на главной странице', default=False)
trial_lesson = models.URLField(default='', null=True, blank=True)
objects = UserManager() objects = UserManager()

@ -150,7 +150,18 @@
{% for error in form.about.errors %} {% for error in form.about.errors %}
<div class="field__error">{{ error }}</div> <div class="field__error">{{ error }}</div>
{% endfor %} {% endfor %}
</div> </div>
{% if is_teacher %}
<div class="form__field field{% if form.trial_lesson.errors %} error{% endif %}">
<div class="field__label">Пробный урок</div>
<div class="field__wrap">
<input name='trial_lesson' class="field__input" type="url" value="{{ user.trial_lesson }}">
</div>
{% for error in form.trial_lesson.errors %}
<div class="field__error">{{ error }}</div>
{% endfor %}
</div>
{% endif %}
</div> </div>
<div class="form__group"> <div class="form__group">
<div class="form__title">Пароль</div> <div class="form__title">Пароль</div>

@ -64,7 +64,7 @@
<div class="section__center center"> <div class="section__center center">
<div class="tabs js-tabs"> <div class="tabs js-tabs">
<div class="tabs__nav"> <div class="tabs__nav">
{# <button class="tabs__btn js-tabs-btn active">ЛАГЕРЬ</button> #} <button class="tabs__btn js-tabs-btn active">ОНЛАЙН-ШКОЛА</button>
<button class="tabs__btn js-tabs-btn">ПРИОБРЕТЕННЫЕ <button class="tabs__btn js-tabs-btn">ПРИОБРЕТЕННЫЕ
<span class="mobile-hide">КУРСЫ</span> <span class="mobile-hide">КУРСЫ</span>
</button> </button>
@ -75,7 +75,6 @@
{% endif %} {% endif %}
</div> </div>
<div class="tabs__container"> <div class="tabs__container">
{% comment %}
<div class="tabs__item js-tabs-item" style="display: block;"> <div class="tabs__item js-tabs-item" style="display: block;">
{% if is_purchased_future %} {% if is_purchased_future %}
<div class="center center_xs"> <div class="center center_xs">
@ -89,7 +88,7 @@
{% else %} {% else %}
<div class="center center_xs"> <div class="center center_xs">
<div class="done"> <div class="done">
<div class="done__title title">Вы не подписаны на лагерь!</div> <div class="done__title title">Вы не подписаны на онлайн-школу!</div>
<div class="done__foot"> <div class="done__foot">
<a <a
{% if not user.is_authenticated %} {% if not user.is_authenticated %}
@ -106,8 +105,7 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
</div> </div>
{% endcomment %} <div class="tabs__item js-tabs-item">
<div class="tabs__item js-tabs-item" style="display: block;">
<div class="courses courses_scroll"> <div class="courses courses_scroll">
<div class="courses__list"> <div class="courses__list">
{% if paid.exists %} {% if paid.exists %}

@ -210,6 +210,11 @@ class ProfileEditView(UpdateView):
self.object = self.get_object() self.object = self.get_object()
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['is_teacher'] = self.object.role == User.TEACHER_ROLE
return context
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
# it's magic *-*-*-*-* # it's magic *-*-*-*-*
if 'photo' in request.FILES: if 'photo' in request.FILES:

@ -56,6 +56,7 @@ INSTALLED_APPS = [
'sorl.thumbnail', 'sorl.thumbnail',
'raven.contrib.django.raven_compat', 'raven.contrib.django.raven_compat',
'django_user_agents', 'django_user_agents',
'imagekit',
] + [ ] + [
'apps.auth.apps', 'apps.auth.apps',
'apps.user', 'apps.user',

@ -12,8 +12,8 @@
<use xlink:href="{% static 'img/sprite.svg' %}#icon-online"></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-online"></use>
</svg> </svg>
</div> </div>
<div class="school__title">Прямой эфир</div> <div class="school__title">Видеоуроки</div>
<div class="school__text">Понедельник, среда, пятница</div> <div class="school__text">Каждый день с 1 сентября</div>
</div> </div>
<div class="school__col"> <div class="school__col">
<div class="school__preview"> <div class="school__preview">
@ -43,22 +43,6 @@
<div class="school__text">Хранится 7 дней</div> <div class="school__text">Хранится 7 дней</div>
</div> </div>
</div> </div>
<div class="letsgo"> <div class="letsgo"></div>
{% comment %}
{% if not is_purchased and not is_purchased_future %}
<a
{% if not user.is_authenticated %}
data-popup=".js-popup-auth"
{% else %}
data-popup=".js-popup-buy"
{% endif %}
class="main__btn btn"
href="#"
>
купить доступ от {{ min_school_price }} руб./месяц
</a>
{% endif %}
{% endcomment %}
</div>
</div> </div>
</div> </div>

@ -19,7 +19,6 @@
<div class="footer__col"> <div class="footer__col">
<div class="footer__title">Программы</div> <div class="footer__title">Программы</div>
<nav class="footer__nav"> <nav class="footer__nav">
<a class="footer__link" href="{% url 'school:summer-school' %}">Лагерь</a>
<a class="footer__link" href="{% url 'school:school' %}">Онлайн-школа</a> <a class="footer__link" href="{% url 'school:school' %}">Онлайн-школа</a>
<a class="footer__link" href="{% url 'courses' %}">Онлайн-курсы</a> <a class="footer__link" href="{% url 'courses' %}">Онлайн-курсы</a>
<a class="footer__link" href="{% url 'author_request' %}">Стать автором</a> <a class="footer__link" href="{% url 'author_request' %}">Стать автором</a>

@ -25,19 +25,10 @@
</form> </form>
</div> </div>
<nav class="header__nav"> <nav class="header__nav">
{% if is_summer_school_purchased %}
<div class="header__group">
<a class="header__section {% active_link 'school:summer-school' %}" href="{% url 'school:summer-school' %}?is_previous=true">
ЛАГЕРЬ {% if online or livelesson.is_online %}
<div class="header__dot"></div>
{% endif %}
</a>
</div>
{% endif %}
<div class="header__group"> <div class="header__group">
<a class="header__section {% active_link 'school:school' %}" href="{% url 'school:school' %}"> <a class="header__section {% active_link 'school:school' %}" href="{% url 'school:school' %}">
ОНЛАЙН-ШКОЛА {% if online or livelesson.is_online %} ОНЛАЙН-ШКОЛА {% if online or livelesson.is_online %}
<!--<div class="header__dot"></div>--> <div class="header__dot"></div>
{% endif %} {% endif %}
</a> </a>
</div> </div>

@ -2,7 +2,7 @@
<div class="section section_courses"> <div class="section section_courses">
<div class="section__center center"> <div class="section__center center">
<div class="title title_center">Видео-курсы без расписания</div> <div class="title title_center">Видео-курсы без расписания</div>
<div class="text text_courses">Если вам не совсем удобно заниматься с нами в прямом эфире каждый день как в нашей онлайн-школе, специально для вас мы <div class="text text_courses">Если вам не совсем удобно заниматься с нами каждый день в нашей онлайн-школе, специально для вас мы
делаем отдельные уроки в записи, которые вы можете проходить когда вам будем удобно.</div> делаем отдельные уроки в записи, которые вы можете проходить когда вам будем удобно.</div>
<div class="head"> <div class="head">
<div class="head__text">Учите и развивайте креативное мышление когда и где угодно</div> <div class="head__text">Учите и развивайте креативное мышление когда и где угодно</div>

@ -1,9 +1,9 @@
{% load static %} {% load static %}
<a class="online" target="_blank" href="https://www.youtube.com/watch?v=PhZ8qQbIej0" style="background-image: url({% static 'img/video-1.jpg' %});"> <a class="online" target="_blank" href="https://www.youtube.com/watch?v=PhZ8qQbIej0" style="background-image: url({% static 'img/video-1.jpg' %});">
<div class="online__center center"> <div class="online__center center">
<div class="online__type">ПРЯМОЙ ЭФИР</div> <div class="online__type">ВИДЕОУРОКИ</div>
<div class="online__title">В 17.00 (по Мск) </div> <div class="online__title">В 17.00 (по Мск) </div>
<div class="online__text text">Понедельник, среда, пятница.</div> <div class="online__text text">Каждый день с 1 сентября</div>
<div class="online__action"> <div class="online__action">
<svg class="icon icon-play"> <svg class="icon icon-play">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-play"></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-play"></use>

@ -4,16 +4,30 @@
<a name="partners"> <a name="partners">
<div class="title title_center">Наши партнеры</div> <div class="title title_center">Наши партнеры</div>
</a> </a>
<div class="text">
Скидка 15% по промокоду у наших партнеров
</div>
<div class="partners"> <div class="partners">
<a target="_blank" class="partners__item" href="https://artkvartal.ru">
<img class="partners__pic" src="{% static 'img/artkvartal.png' %}">
</a>
<a target="_blank" class="partners__item" href="https://www.mann-ivanov-ferber.ru/tag/sasha-kru/"> <a target="_blank" class="partners__item" href="https://www.mann-ivanov-ferber.ru/tag/sasha-kru/">
<img class="partners__pic" src="{% static 'img/mif.jpg' %}"> <img class="partners__pic" src="{% static 'img/mif.jpg' %}">
</a> </a>
<a target="_blank" class="partners__item" href="https://artkvartal.ru">
<img class="partners__pic" src="{% static 'img/artkvartal.png' %}">
</a>
<a target="_blank" class="partners__item" href="http://www.pinkbus.ru/"> <a target="_blank" class="partners__item" href="http://www.pinkbus.ru/">
<img class="partners__pic" src="{% static 'img/pinkbus.jpg' %}"> <img class="partners__pic" src="{% static 'img/pinkbus.jpg' %}">
</a> </a>
</div> </div>
<div class="partners partners_promocodes">
<div class="partners__item">
<div class="partners__item-promocode">LIL</div>
</div>
<div class="partners__item">
<div class="partners__item-promocode">LILCITY</div>
</div>
<div class="partners__item">
<div class="partners__item-promocode">LILCITY</div>
</div>
</div>
</div> </div>
</div> </div>

@ -37,10 +37,10 @@
<div class="field__password-show"> <div class="field__password-show">
<button class="password-toggle" type="button"> <button class="password-toggle" type="button">
<svg class="icon icon-password-eye"> <svg class="icon icon-password-eye">
<use xlink:href={% static "img/sprite.svg" %}#icon-password-eye></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-password-eye"></use>
</svg> </svg>
<svg class="icon icon-password-hidden-eye"> <svg class="icon icon-password-hidden-eye">
<use xlink:href={% static "img/sprite.svg" %}#icon-password-hidden-eye></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-password-hidden-eye"></use>
</svg> </svg>
</button> </button>
</div> </div>
@ -53,7 +53,7 @@
<div class="auth__or">или</div> <div class="auth__or">или</div>
<button type="button" class="auth__btn btn btn_fb"> <button type="button" class="auth__btn btn btn_fb">
<svg class="icon icon-facebook"> <svg class="icon icon-facebook">
<use xlink:href={% static "img/sprite.svg" %}#icon-facebook></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-facebook"></use>
</svg> </svg>
<span class="btn__title">ЧЕРЕЗ FACEBOOK</span> <span class="btn__title">ЧЕРЕЗ FACEBOOK</span>
</button> </button>
@ -96,10 +96,10 @@
<div class="field__password-show"> <div class="field__password-show">
<button class="password-toggle" type="button"> <button class="password-toggle" type="button">
<svg class="icon icon-password-eye"> <svg class="icon icon-password-eye">
<use xlink:href={% static "img/sprite.svg" %}#icon-password-eye></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-password-eye"></use>
</svg> </svg>
<svg class="icon icon-password-hidden-eye"> <svg class="icon icon-password-hidden-eye">
<use xlink:href={% static "img/sprite.svg" %}#icon-password-hidden-eye></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-password-hidden-eye"></use>
</svg> </svg>
</button> </button>
</div> </div>
@ -122,7 +122,7 @@
<div class="auth__or">или</div> <div class="auth__or">или</div>
<button type="button" class="auth__btn btn btn_fb"> <button type="button" class="auth__btn btn btn_fb">
<svg class="icon icon-facebook"> <svg class="icon icon-facebook">
<use xlink:href={% static "img/sprite.svg" %}#icon-facebook></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-facebook"></use>
</svg> </svg>
<span class="btn__title">ЧЕРЕЗ FACEBOOK</span> <span class="btn__title">ЧЕРЕЗ FACEBOOK</span>
</button> </button>

@ -89,7 +89,7 @@
</div> </div>
</div> </div>
<div class="buy__foot"> <div class="buy__foot">
<a class="buy__btn btn btn_md but_btn_popup" data-link="{% url 'school-checkout' %}" href="{% url 'school-checkout' %}?weekdays=1&weekdays=2">ПЕРЕЙТИ К ОПЛАТЕ</a> <a class="buy__btn btn btn_md but_btn_popup" data-link="{% url 'school-checkout' %}">ПЕРЕЙТИ К ОПЛАТЕ</a>
</div> </div>
</div> </div>
</div> </div>

@ -46,29 +46,20 @@
</div> </div>
{% else %} {% else %}
<div class="main__subtitle"> <div class="main__subtitle">
{# Присоединяйтесь в Рисовальный лагерь #} Приглашаем вас присоединиться к онлайн-школе с 1 сентября!
Приглашаем вас на месяц открытых дверей в Lil School
</div> </div>
<div class="main__actions"> <div class="main__actions">
{% comment %}
{% if not is_purchased and not is_purchased_future %} {% if not is_purchased and not is_purchased_future %}
<a <a
{% if not is_purchased_future %}
{% if not user.is_authenticated %}
data-popup=".js-popup-auth"
{% else %}
data-popup=".js-popup-buy" data-popup=".js-popup-buy"
{% endif %}
{% endif %}
class="main__btn btn" class="main__btn btn"
href="#" href="#"
> >
Получить доступ купить доступ от {{ min_school_price }} руб./месяц
</a> </a>
{% else %}
<a class="main__btn btn btn_white" href="{% url 'school:school' %}">Подробнее</a>
{% endif %} {% endif %}
{% endcomment %}
{# <a class="main__btn btn btn_white" href="{% url 'school:summer-school' %}">О лагере</a> #}
<a class="main__btn btn btn_white" href="{% url 'course' pk=50 %}">Подробнее</a>
</div> </div>
{% endif %} {% endif %}
</div> </div>

@ -1,27 +1,14 @@
{% load static %} {% load static %}
<div class="share"> <div class="share">
<div class="share__title">Поделиться {% if share_object_name %}{{ share_object_name }}{% else %}{% if livelesson or lesson %}уроком{% else %}курсом{% endif %}{% endif %}</div> <div class="share__title">Поделиться {% if share_object_name %}{{ share_object_name }}{% else %}{% if livelesson or lesson %}уроком{% else %}курсом{% endif %}{% endif %}</div>
<div class="share__list likely"> <div class="share__list likely likely-big" data-url="http://{{request.META.HTTP_HOST}}{{object.get_absolute_url}}">
<a class="share__item facebook" href="#" data-url="http://{{request.META.HTTP_HOST}}{{object.get_absolute_url}}"> <div class="twitter"></div>
<svg class="icon icon-share-facebook"> <div class="facebook"></div>
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-facebook"></use> <div class="gplus"></div>
</svg> <div class="vkontakte"></div>
</a> <div class="telegram"></div>
<a class="share__item twitter" href="#" data-url="http://{{request.META.HTTP_HOST}}{{object.get_absolute_url}}"> <div class="pinterest"></div>
<svg class="icon icon-share-twitter">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-twitter"></use>
</svg>
</a>
<a class="share__item gplus" href="#" data-url="http://{{request.META.HTTP_HOST}}{{object.get_absolute_url}}">
<svg class="icon icon-share-google">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-google"></use>
</svg>
</a>
<a class="share__item pinterest" href="#" data-url="http://{{request.META.HTTP_HOST}}{{object.get_absolute_url}}">
<svg class="icon icon-share-pinterest">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-pinterest"></use>
</svg>
</a>
</div> </div>
</div> </div>

@ -17,10 +17,15 @@
</div> </div>
<div class="teachers__wrap"> <div class="teachers__wrap">
<div class="teachers__title"> <div class="teachers__title">
<a href="{% url 'user' teacher.id %}">{{ teacher.get_full_name }}</a>{% if teacher.instagram_hashtag %}, <div class="teachers__title-name">
<a href='https://www.instagram.com/explore/tags/{{ teacher.instagram_hashtag }}/' target="_blank"> <a href="{% url 'user' teacher.id %}">{{ teacher.get_full_name }}</a>{% if teacher.instagram_hashtag %},
{{ teacher.instagram_hashtag }} <a href='https://www.instagram.com/explore/tags/{{ teacher.instagram_hashtag }}/' target="_blank">
</a> {{ teacher.instagram_hashtag }}
</a>
{% endif %}
</div>
{% if teacher.trial_lesson %}
<a target="_blank" href="{{ teacher.trial_lesson }}" class="btn btn_light">ПРОБНЫЙ УРОК</a>
{% endif %} {% endif %}
</div> </div>
<div class="teachers__social"> <div class="teachers__social">
@ -30,13 +35,13 @@
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-facebook"></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-share-facebook"></use>
</svg> </svg>
</a> </a>
{% endif %} {% if teacher.instagram %} {% endif %} {# if teacher.instagram #}
<a class="social__item" href="{{ teacher.instagram }}" target="_blank"> <a class="social__item" href="{{ teacher.instagram }}" target="_blank">
<svg class="icon icon-share-instagram"> <svg class="icon icon-share-instagram">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-instagram"></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-share-instagram"></use>
</svg> </svg>
</a> </a>
{% endif %} {% if teacher.twitter %} {# endif #} {% if teacher.twitter %}
<a class="social__item" href="{{ teacher.twitter }}" target="_blank"> <a class="social__item" href="{{ teacher.twitter }}" target="_blank">
<svg class="icon icon-share-twitter"> <svg class="icon icon-share-twitter">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-share-twitter"></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-share-twitter"></use>

@ -115,6 +115,7 @@
<noscript><div><img src="https://mc.yandex.ru/watch/49354039" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <noscript><div><img src="https://mc.yandex.ru/watch/49354039" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter --> <!-- /Yandex.Metrika counter -->
{% include "templates/blocks/mixpanel.html" %} {% include "templates/blocks/mixpanel.html" %}
{% block head %}{% endblock head %}
</head> </head>
<body> <body>
{% include "templates/blocks/social.html" %} {% include "templates/blocks/social.html" %}

@ -34,14 +34,14 @@ class IndexView(TemplateView):
online = ( online = (
school_schedule.start_at <= now_time.time() and school_schedule.start_at <= now_time.time() and
(end_at + timedelta(hours=1)).time() >= now_time.time() and (end_at + timedelta(hours=1)).time() >= now_time.time() and
school_schedule.current_live_lesson() school_schedule.current_live_lesson
) )
online_coming_soon = ( online_coming_soon = (
school_schedule.start_at > now_time.time() and school_schedule.start_at > now_time.time() and
( (
datetime.combine(datetime.today(), school_schedule.start_at) - timedelta(hours=12) datetime.combine(datetime.today(), school_schedule.start_at) - timedelta(hours=12)
).time() <= now_time.time() and ).time() <= now_time.time() and
school_schedule.current_live_lesson() school_schedule.current_live_lesson
) )
date_now = now_time.date() date_now = now_time.date()

@ -28,4 +28,6 @@ git+https://github.com/ivlevdenis/python-instagram.git
django-user-agents==0.3.2 django-user-agents==0.3.2
user-agents==1.1.0 user-agents==1.1.0
ua-parser==0.8.0 ua-parser==0.8.0
django-ipware
django-imagekit

@ -1,7 +1,15 @@
<template> <template>
<div class="contest-works"> <div class="contest-works">
<div class="contest-works__works"> <div class="contest-works__works">
<contest-work v-for="contestWork in contestWorks" :key="contestWork.id" :contest-work="contestWork"></contest-work> <div class="contest-works__column">
<contest-work v-for="contestWork in columns[0]" :key="contestWork.id" :contest-work="contestWork"></contest-work>
</div>
<div class="contest-works__column">
<contest-work v-for="contestWork in columns[1]" :key="contestWork.id" :contest-work="contestWork"></contest-work>
</div>
<div class="contest-works__column">
<contest-work v-for="contestWork in columns[2]" :key="contestWork.id" :contest-work="contestWork"></contest-work>
</div>
</div> </div>
<div v-show="loading" class="contest-works__loader"><div class="loading-loader"></div></div> <div v-show="loading" class="contest-works__loader"><div class="loading-loader"></div></div>
<div v-if="loaded && !contestWorks.length" class="contest-works__no-works">Здесь вы сможете увидеть работы участников после их добавления</div> <div v-if="loaded && !contestWorks.length" class="contest-works__no-works">Здесь вы сможете увидеть работы участников после их добавления</div>
@ -38,6 +46,18 @@
}); });
} }
}, },
computed: {
columns() {
const first = [];
const second = [];
const third = [];
for(let i=0; i < this.contestWorks.length; i++) {
const work = this.contestWorks[i];
[first, second, third][i % 3].push(work);
}
return [first, second, third];
}
},
methods: { methods: {
load() { load() {
this.loading = true; this.loading = true;
@ -70,9 +90,13 @@
width: 100%; width: 100%;
} }
.contest-works__works { .contest-works__works {
column-width: 300px;
column-gap: 20px;
text-align: left; text-align: left;
display: flex;
}
.contest-works__column {
display: flex;
flex-direction: column;
margin-right: 20px;
} }
.contest-works__loader { .contest-works__loader {
width: 100%; width: 100%;

@ -1,7 +1,7 @@
<template> <template>
<div class="contest-work-item"> <div class="contest-work-item">
<a :href="`/contest-work/${contestWork.id}/`"> <a :href="`/contest-work/${contestWork.id}/`">
<img class="contest-work-item__img" :src="contestWork.image.image" /> <img class="contest-work-item__img" :src="contestWork.image.image_thumbnail" />
</a> </a>
<div class="contest-work-item__info"> <div class="contest-work-item__info">
<div class="contest-work-item__bio"> <div class="contest-work-item__bio">

@ -14,7 +14,7 @@
export default { export default {
name: "lil-image", name: "lil-image",
props: ["imageId", "imageUrl", "accessToken"], props: ["imageId", "imageUrl", "accessToken", "longSide"],
data() { data() {
return { return {
loading: false, loading: false,
@ -23,7 +23,7 @@
methods: { methods: {
onImageAdded(event) { onImageAdded(event) {
this.loading = true; this.loading = true;
const maxSize = 1600; const longSide = +this.longSide || 1600;
let file = event.target.files[0]; let file = event.target.files[0];
const reader = new FileReader(); const reader = new FileReader();
reader.onload = () => { reader.onload = () => {
@ -32,12 +32,12 @@
let w = 0; let w = 0;
let h = 0; let h = 0;
if(img.width > img.height) { if(img.width > img.height) {
w = maxSize; w = longSide;
h = 0; h = 0;
} }
else { else {
w = 0; w = 0;
h = maxSize; h = longSide;
} }
downscale(img.src, w, h).then((dataURL) => { downscale(img.src, w, h).then((dataURL) => {
img = null; img = null;

@ -1,6 +1,8 @@
/** /**
* Входная точка клиентского приложения. * Входная точка клиентского приложения.
*/ */
import 'ilyabirman-likely/release/likely.js';
import 'ilyabirman-likely/release/likely.css';
import "./modules/common"; import "./modules/common";
import "./modules/header"; import "./modules/header";
import "./modules/search"; import "./modules/search";

@ -5,6 +5,7 @@ import isLength from 'validator/lib/isLength';
$(document).ready(function () { $(document).ready(function () {
let auth = $('.js-auth'), let auth = $('.js-auth'),
popup = $('.js-popup-auth'),
type = auth.find('.js-auth-type'), type = auth.find('.js-auth-type'),
tab = auth.find('.js-auth-tab'), tab = auth.find('.js-auth-tab'),
login = auth.find('.js-auth-login'), login = auth.find('.js-auth-login'),
@ -153,7 +154,13 @@ $(document).ready(function () {
}) })
.done(function (data) { .done(function (data) {
if (data.success === true) { if (data.success === true) {
location.reload(); const nextUrl = popup.data('next-url');
if(nextUrl){
window.location.href = nextUrl;
}
else{
window.location.reload();
}
} else { } else {
authButton.removeClass('loading'); authButton.removeClass('loading');
} }
@ -234,7 +241,13 @@ $(document).ready(function () {
}) })
.done(function (data) { .done(function (data) {
if (data.success === true) { if (data.success === true) {
location.reload(); const nextUrl = popup.data('next-url');
if(nextUrl){
window.location.href = nextUrl;
}
else{
window.location.reload();
}
} else { } else {
registrationButton.removeClass('loading'); registrationButton.removeClass('loading');
} }
@ -275,7 +288,7 @@ $(document).ready(function () {
if (facebookResponse) { if (facebookResponse) {
if (facebookResponse.status === 'connected') { if (facebookResponse.status === 'connected') {
login_with_facebook(facebookResponse.authResponse.accessToken); login_with_facebook(facebookResponse.authResponse.accessToken, popup.data('next-url'));
return; return;
} }
} }
@ -305,14 +318,19 @@ function load_facebook() {
}); });
} }
function login_with_facebook(accessToken) { function login_with_facebook(accessToken, nextUrl) {
$.ajax('/auth/facebook_login/', { $.ajax('/auth/facebook_login/', {
method: 'POST', method: 'POST',
data: {'access_token': accessToken}, data: {'access_token': accessToken},
}) })
.done(function (data) { .done(function (data) {
if (data.success === true) { if (data.success === true) {
location.reload(); if(nextUrl){
window.location.href = nextUrl;
}
else{
window.location.reload();
}
} }
}) })
.fail(function (xhr) { .fail(function (xhr) {

@ -31,6 +31,24 @@ $(document).ready(function () {
}); });
is_extend = true; is_extend = true;
} }
if(! window.LIL_STORE.user.id) {
const $btn = popup.find('.buy__btn');
$btn.click(function(event) {
event.preventDefault();
hidePopup().then(() => {
popup = $('.js-popup-auth');
popup.data('next-url', $btn.attr('href'));
showPopup();
});
});
}
}
if( data === '.js-popup-auth') {
let nextUrl = $(this).data('auth-next-url');
if(nextUrl === 'href') {
nextUrl = $(this).attr('href');
}
popup.data('next-url', nextUrl);
} }
if($(this).data('day')) { if($(this).data('day')) {
@ -70,21 +88,28 @@ $(document).ready(function () {
function showPopup(){ function showPopup(){
body.addClass('no-scroll'); body.addClass('no-scroll');
popup.addClass('open'); popup.addClass('open');
setTimeout(function(){ return new Promise((resolve) => {
popup.addClass('visible'); setTimeout(function(){
}, 100); popup.addClass('visible');
resolve();
}, 100);
});
} }
function hidePopup(){ function hidePopup(){
body.removeClass('no-scroll'); body.removeClass('no-scroll');
popup.removeClass('visible'); popup.removeClass('visible');
setTimeout(function(){ popup.data('next-url', null);
popup.removeClass('open');
}, 300);
if($('#password-reset__sent').is(':visible')) { if($('#password-reset__sent').is(':visible')) {
window.location.reload(); window.location.reload();
} }
return new Promise((resolve) => {
setTimeout(function(){
popup.removeClass('open');
resolve();
}, 300);
});
} }
$(document).on('change', '[data-day]', function(){ $(document).on('change', '[data-day]', function(){

@ -815,7 +815,7 @@ a[name]
&:not(:last-child) &:not(:last-child)
margin-bottom: 35px margin-bottom: 35px
+t +t
margin: 5px margin: 5px 5px 15px 5px
&__curve &__curve
position: absolute position: absolute
pointer-events: none pointer-events: none
@ -1519,12 +1519,17 @@ a.grey-link
flex: 0 0 95px flex: 0 0 95px
&__title &__title
margin-bottom: 5px margin-bottom: 5px
display: flex
+fb +fb
font-size: 20px font-size: 20px
letter-spacing: 2px letter-spacing: 2px
+t +t
font-size: 12px font-size: 12px
letter-spacing: 2px letter-spacing: 2px
+m
display: block
&-name
flex: 1
&__social &__social
.social__item .social__item
margin-right: 3px margin-right: 3px
@ -1533,6 +1538,8 @@ a.grey-link
&__content &__content
font-size: 16px font-size: 16px
line-height: (22/16) line-height: (22/16)
&__wrap
flex: 1
.toggle .toggle
font-size: 14px font-size: 14px
@ -1777,6 +1784,16 @@ a.grey-link
+m +m
margin: 0 5px 10px margin: 0 5px 10px
flex: 0 0 calc(33.33% - 10px) flex: 0 0 calc(33.33% - 10px)
&_promocodes &__item
text-align: center;
&__item-promocode
border: 1px solid #333;
display: inline-block;
padding: 7px 10px;
border-radius: 3px;
font-weight: bold;
letter-spacing: 2px;
text-transform: uppercase;
&__pic &__pic
display: block display: block
width: 100% width: 100%

Loading…
Cancel
Save