diff --git a/apps/notification/tasks.py b/apps/notification/tasks.py
index 28544d52..03f3cc9e 100644
--- a/apps/notification/tasks.py
+++ b/apps/notification/tasks.py
@@ -8,7 +8,7 @@ from django.db.models import Max
from apps.notification.models import UserNotification
from apps.notification.utils import send_email
-from apps.payment.models import SchoolPayment, CoursePayment, Payment
+from apps.payment.models import SchoolPayment, CoursePayment, Payment, UserGiftCertificate
from project.celery import app
from project.utils.db import format_sql, execute_sql
from project.sengrid import get_sendgrid_client
@@ -33,7 +33,7 @@ def send_certificates(email=None, date=None, dry_run=False):
file.close()
return
- date = datetime.strptime(date, '%d-%m-%Y') if date else now().date()
+ date = datetime.strptime(date, '%d-%m-%Y').date() if date else now().date()
today = now().date()
users = set(list(SchoolPayment.objects.filter(date_end=date, add_days=False).values_list('user_id', flat=True)))
user_notifications_qs = UserNotification.objects.filter(user_id__in=users)
@@ -42,6 +42,7 @@ def send_certificates(email=None, date=None, dry_run=False):
'user_id', flat=True).distinct()
for user_id in users:
if user_id in notified_users:
+ print('skip', user_id)
continue
un = user_notifications.get(user_id, UserNotification(user_id=user_id))
print(un.user.email)
@@ -54,7 +55,7 @@ def send_certificates(email=None, date=None, dry_run=False):
file = open(staticfiles_storage.path(path_pattern % un.certificate_number), 'rb')
try:
send_email('Грамота от Lil School', un.user.email, 'notification/email/certificate.html',
- attachments=[(file.name, file.read(), 'image/jpeg')])
+ attachments=[(file.name, file.read(), 'image/jpeg')], user_notification=un)
except:
print('Not OK')
continue
@@ -98,3 +99,11 @@ def sendgrid_update_recipients():
sg = get_sendgrid_client()
response = sg.client.contactdb.recipients.patch(request_body=data)
print(response.body)
+
+
+@app.task
+def send_gift_certificate(user_gift_certificate):
+ user_gift_certificate = UserGiftCertificate.objects.get(id=user_gift_certificate)
+ send_email('Подарочный сертификат от Lil School', user_gift_certificate.user.email, 'notification/email/gift_certificate.html',
+ inline_images=[('twitter_icon', 'img/twitter.png'), ('fb_icon', 'img/fb.png'), ('instagram_icon', 'img/instagram.png'),],
+ user_gift_certificate=user_gift_certificate, gift_certificate=user_gift_certificate.gift_certificate)
diff --git a/apps/notification/templates/notification/email/certificate.html b/apps/notification/templates/notification/email/certificate.html
index 051a2d94..0185c4c3 100644
--- a/apps/notification/templates/notification/email/certificate.html
+++ b/apps/notification/templates/notification/email/certificate.html
@@ -1,28 +1,71 @@
{% extends "notification/email/_base.html" %}
{% block content %}
-
Дорогие родители!
+
Привет!
-
Это письмо адресовано вашим детям - ученикам Lil School.
- Если они еще не умеют читать, прочитайте им наше послание, громко и с выражением.
- Спасибо!
+ {% if not user_notification or user_notification.certificate_number == 1 %}
+
+ Поздравляем! Вы прошли месяц обучения в Lil School.
+К письму прикреплена грамота. Распечатайте её и вручите вашим детям.
+Ждём вас в следующем месяце на наших творческих занятиях!
+ {% endif %}
+ {% if user_notification and user_notification.certificate_number == 2 %}
+
+ Вы помните, что каждый месяц вам приходит грамота за прекрасную учебу в нашей творческой школе?
+ Скачивайте. Распечатывайте. И соберите свою коллекцию!
+
+ {% endif %}
+ {% if user_notification and user_notification.certificate_number == 3 %}
+
+Вам понравился наш творческий месяц?
+В письме вы найдёте грамоту, она для вашей семьи.
+Как здорово, что у нас есть такие ученики!
+Ждём вас в следующем месяце.
+
+ {% endif %}
+ {% if user_notification and user_notification.certificate_number == 4 %}
+
+ Прошёл целый месяц обучения на платформе Lil School - месяц творчества, креатива и невероятных идей.
+Во вложении вас ждёт грамота.
+До встречи на занятиях!
+
+ {% endif %}
+ {% if user_notification and user_notification.certificate_number == 5 %}
+
+ Ваша грамота за успехи в учебе в Lil School ждёт вас во вложении.
+Скорее распечатайте её!
+Вам есть чем гордится!
+До встречи в следующем месяце!
+
+ {% endif %}
+ {% if user_notification and user_notification.certificate_number == 6 %}
+
+ Как здорово вы потрудились на занятиях в этом месяце!
+И наша грамота уже ждёт вас!
+Спасибо за творчество и креатив.
+Ждём вас в следующем месяце!
+
+ {% endif %}
+ {% if user_notification and user_notification.certificate_number == 7 %}
+
+ Какой классный месяц у нас был! Вместе мы очень здорово и креативно потрудились.
+Во вложении вас ждёт заслуженная грамота!
+До встречи на уроках!
+
+ {% endif %}
+ {% if user_notification and user_notification.certificate_number == 8 %}
+
+ Месяц творчества и креатива пролетел как один миг! А как много работ мы вместе сделали!
+Вы - большие молодцы.
+Во вложении ваш ждёт грамота!
+До встречи на занятиях.
+
+ {% endif %}
-
- Привет, друг!
- Вот и прошёл месяц обучения на платформе «Lil School» - месяц удивительных, творческих приключений и открытий.
- Ты так много узнал и столько всего нарисовал!
- Как же здорово у тебя все получается!
-
-
- Скорее смотри что прикреплено к письму. Да это же ГРАМОТА! Ее можно распечатать и повесить
- на видное место в твоей комнате.
- Можно показать ее друзьям вместе со всеми работами, над которыми ты так трудился.
-
-
- Поздравляем! Мы ждём тебя в новом месяце в рядах наших учеников.
-
-
- Команда «Lil School».
+
+
+ Команда «Lil School».
+
{% endblock content %}
diff --git a/apps/notification/templates/notification/email/gift_certificate.html b/apps/notification/templates/notification/email/gift_certificate.html
new file mode 100644
index 00000000..f1d8a3f9
--- /dev/null
+++ b/apps/notification/templates/notification/email/gift_certificate.html
@@ -0,0 +1,112 @@
+{% extends "notification/email/_base.html" %}
+{% load settings %}
+
+{% block content %}
+
Поздравляем с успешной
+ покупкой!
+
+
Вы получаете {{ gift_certificate.price }} лиликов на счет! 1 LIL = 1 руб.
+ Накапливайте монеты и тратьте их на оплату школы и курсов.
+
+
+
+
+
+
+
+
+ Подарочный сертификат
+
+ {{ gift_certificate.price }} р.
+
+
+
+
+
+
+
Чтобы воспользоваться сертификатом, перейдите по ссылке
+
+
+ Или воспользуйтесь сертификатом, введя уникальный код на в разделе
+ вашего профиля на сайте
lil.school
+
+
Ваш код
+
+
+
{{ user_gift_certificate.code }}
+
+
+
+ Вы так же можете отправить это письмо, ссылку или код вашему другу, чтобы подарить ему этот сертификат.
+
+
+ Присоединяйтесь к нам!
+
+
+ {% if config.SERVICE_TWITTER_URL %}
+
+
+
+ {% endif %}
+ {% if config.SERVICE_FB_URL %}
+
+
+
+ {% endif %}
+ {% if config.SERVICE_INSTAGRAM_URL %}
+
+
+
+ {% endif %}
+
+
+{% endblock content %}
diff --git a/apps/notification/utils.py b/apps/notification/utils.py
index d556bd96..07510c41 100644
--- a/apps/notification/utils.py
+++ b/apps/notification/utils.py
@@ -1,16 +1,27 @@
+from django.contrib.staticfiles.storage import staticfiles_storage
from twilio.rest import Client
-
-from django.core.mail import EmailMessage
+from django.core.mail import EmailMessage, EmailMultiAlternatives
+from anymail.message import attach_inline_image_file
from django.conf import settings
from django.template.loader import get_template
+
from project.celery import app
@app.task
-def send_email(subject, to_email, template_name, attachments=[], **kwargs):
- html = get_template(template_name).render(kwargs)
- email = EmailMessage(subject, html, to=[to_email], attachments=attachments)
- email.content_subtype = 'html'
+def send_email(subject, to_email, template_name, attachments=[], inline_images=[], **kwargs):
+ if inline_images:
+ email = EmailMultiAlternatives(subject, '', to=[to_email], attachments=attachments)
+ context = kwargs
+ for name, path in inline_images:
+ cid = attach_inline_image_file(email, staticfiles_storage.path(path))
+ context[name] = cid
+ html = get_template(template_name).render(context)
+ email.attach_alternative(html, "text/html")
+ else:
+ html = get_template(template_name).render(kwargs)
+ email = EmailMessage(subject, html, to=[to_email], attachments=attachments)
+ email.content_subtype = 'html'
email.send()
diff --git a/apps/payment/admin.py b/apps/payment/admin.py
index 19166563..b26b03a2 100644
--- a/apps/payment/admin.py
+++ b/apps/payment/admin.py
@@ -5,7 +5,7 @@ from polymorphic.admin import (
PolymorphicChildModelFilter,
)
-from .models import AuthorBalance, CoursePayment, SchoolPayment, Payment
+from .models import AuthorBalance, CoursePayment, SchoolPayment, Payment, GiftCertificate
@admin.register(AuthorBalance)
@@ -61,3 +61,8 @@ class PaymentAdmin(PolymorphicParentModelAdmin):
CoursePayment,
SchoolPayment,
)
+
+
+@admin.register(GiftCertificate)
+class GiftCertificateAdmin(admin.ModelAdmin):
+ pass
diff --git a/apps/payment/migrations/0025_giftcertificate_usergiftcertificate.py b/apps/payment/migrations/0025_giftcertificate_usergiftcertificate.py
new file mode 100644
index 00000000..3f9dcc34
--- /dev/null
+++ b/apps/payment/migrations/0025_giftcertificate_usergiftcertificate.py
@@ -0,0 +1,34 @@
+# Generated by Django 2.0.6 on 2018-10-29 14:36
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('payment', '0024_auto_20181002_0338'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='GiftCertificate',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('price', models.DecimalField(decimal_places=2, default=0, editable=False, max_digits=8)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='UserGiftCertificate',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('recipient', models.EmailField(max_length=254, blank=True, null=True,)),
+ ('bonuses_sent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='payment.UserBonus')),
+ ('gift_certificate', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='payment.GiftCertificate')),
+ ('payment', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='payment.Payment')),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='gift_certificates', to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ ]
diff --git a/apps/payment/migrations/0026_auto_20181101_1546.py b/apps/payment/migrations/0026_auto_20181101_1546.py
new file mode 100644
index 00000000..45cd9906
--- /dev/null
+++ b/apps/payment/migrations/0026_auto_20181101_1546.py
@@ -0,0 +1,39 @@
+# Generated by Django 2.0.6 on 2018-11-01 15:46
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('payment', '0025_giftcertificate_usergiftcertificate'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='GiftCertificatePayment',
+ fields=[
+ ('payment_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='payment.Payment')),
+ ],
+ options={
+ 'verbose_name': 'Платеж за подарочный сертификат',
+ 'verbose_name_plural': 'Платежи за подарочные сертификаты',
+ },
+ bases=('payment.payment',),
+ ),
+ migrations.AlterModelOptions(
+ name='giftcertificate',
+ options={'ordering': ('price',)},
+ ),
+ migrations.AlterField(
+ model_name='giftcertificate',
+ name='price',
+ field=models.DecimalField(decimal_places=2, default=0, max_digits=8),
+ ),
+ migrations.AddField(
+ model_name='giftcertificatepayment',
+ name='gift_certificate',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='payments', to='payment.GiftCertificate', verbose_name='Подарочный сертификат'),
+ ),
+ ]
diff --git a/apps/payment/migrations/0027_auto_20181109_1402.py b/apps/payment/migrations/0027_auto_20181109_1402.py
new file mode 100644
index 00000000..a228e06b
--- /dev/null
+++ b/apps/payment/migrations/0027_auto_20181109_1402.py
@@ -0,0 +1,22 @@
+# Generated by Django 2.0.6 on 2018-11-09 14:02
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('payment', '0026_auto_20181101_1546'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='usergiftcertificate',
+ name='recipient',
+ ),
+ migrations.AddField(
+ model_name='giftcertificate',
+ name='cover',
+ field=models.CharField(blank=True, default='', max_length=255),
+ ),
+ ]
diff --git a/apps/payment/migrations/0028_add_gift_certificates.py b/apps/payment/migrations/0028_add_gift_certificates.py
new file mode 100644
index 00000000..18c0ac4f
--- /dev/null
+++ b/apps/payment/migrations/0028_add_gift_certificates.py
@@ -0,0 +1,21 @@
+# Generated by Django 2.0.6 on 2018-11-09 14:03
+
+from django.db import migrations
+from django.contrib.staticfiles.storage import staticfiles_storage
+
+
+def add_gift_certificates(apps, schema_editor):
+ GiftCertificate = apps.get_model('payment', 'GiftCertificate')
+ for price in [1000, 2000, 3000, 5000, 10000]:
+ GiftCertificate.objects.create(price=price,
+ cover=staticfiles_storage.url('img/gift-certificates/%d.jpg' % price))
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('payment', '0027_auto_20181109_1402'),
+ ]
+
+ operations = [
+ migrations.RunPython(add_gift_certificates),
+ ]
diff --git a/apps/payment/models.py b/apps/payment/models.py
index a953d5e8..413e8bf8 100644
--- a/apps/payment/models.py
+++ b/apps/payment/models.py
@@ -1,5 +1,6 @@
from decimal import Decimal
import arrow
+import short_url
from django.db.models import Func, F
from paymentwall import Pingback
@@ -13,6 +14,7 @@ from django.core.validators import RegexValidator
from django.utils.timezone import now
from django.conf import settings
+from apps.content.models import ImageObject
from project.utils import weekdays_in_date_range
from apps.course.models import Course
@@ -147,6 +149,8 @@ class Payment(PolymorphicModel):
referrer_bonus = user.referral.referrer_bonus
if payment and payment.is_paid():
price = payment.amount
+ elif isinstance(payment, GiftCertificatePayment):
+ price = payment.gift_certificate.price
elif course:
price = course.price
else:
@@ -244,6 +248,12 @@ class Payment(PolymorphicModel):
else:
author_balance.amount = self.amount
author_balance.save()
+ if isinstance(self, GiftCertificatePayment) and self.is_paid():
+ ugs, created = UserGiftCertificate.objects.get_or_create(user=self.user, gift_certificate=self.gift_certificate,
+ payment=self)
+ if created:
+ from apps.notification.tasks import send_gift_certificate
+ send_gift_certificate(ugs.id)
# Если юзер реферал и нет платежа, где применялась скидка
if hasattr(self.user, 'referral') and not self.user.referral.payment and self.is_paid():
# Платеж - как сигнал, что скидка применилась
@@ -283,6 +293,15 @@ class SchoolPayment(Payment):
return arrow.get(self.date_end, settings.TIME_ZONE).humanize(locale='ru')
+class GiftCertificatePayment(Payment):
+ gift_certificate = models.ForeignKey('GiftCertificate', on_delete=models.CASCADE,
+ verbose_name='Подарочный сертификат', related_name='payments')
+
+ class Meta:
+ verbose_name = 'Платеж за подарочный сертификат'
+ verbose_name_plural = 'Платежи за подарочные сертификаты'
+
+
class UserBonus(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='bonuses')
amount = models.DecimalField(max_digits=8, decimal_places=2, default=0, editable=False)
@@ -292,3 +311,22 @@ class UserBonus(models.Model):
class Meta:
ordering = ('created_at',)
+
+
+class GiftCertificate(models.Model):
+ price = models.DecimalField(max_digits=8, decimal_places=2, default=0)
+ cover = models.CharField(max_length=255, blank=True, default='')
+
+ class Meta:
+ ordering = ('price',)
+
+
+class UserGiftCertificate(models.Model):
+ gift_certificate = models.ForeignKey(GiftCertificate, on_delete=models.CASCADE,)
+ user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='gift_certificates')
+ payment = models.ForeignKey(Payment, on_delete=models.SET_NULL, null=True)
+ bonuses_sent = models.ForeignKey(UserBonus, on_delete=models.CASCADE, blank=True, null=True)
+
+ @property
+ def code(self):
+ return short_url.encode_url(self.id) if self.id else None
diff --git a/apps/payment/templates/payment/gift_certificate.html b/apps/payment/templates/payment/gift_certificate.html
new file mode 100644
index 00000000..7d291137
--- /dev/null
+++ b/apps/payment/templates/payment/gift_certificate.html
@@ -0,0 +1,17 @@
+{% extends "templates/lilcity/index.html" %} {% load static %}
+
+{% block content %}
+
+
+
Вам подарок!
+
+ Пользователь ХХХ дарит вам сертификат на сумму ХХХ руб
+
+
+
+
+{% endblock content %}
diff --git a/apps/payment/templates/payment/gift_certificate_get.html b/apps/payment/templates/payment/gift_certificate_get.html
new file mode 100644
index 00000000..6242f060
--- /dev/null
+++ b/apps/payment/templates/payment/gift_certificate_get.html
@@ -0,0 +1,15 @@
+{% extends "templates/lilcity/index.html" %} {% load static %} {% block content %}
+
+
+
+
Бонусы зачислены на ваш счет!
+
Вы можете оплатить с их помощью курс или онлайн-школу
+
+
+
+
+{% endblock content %}
diff --git a/apps/payment/templates/payment/gift_certificate_item.html b/apps/payment/templates/payment/gift_certificate_item.html
new file mode 100644
index 00000000..5f4a318e
--- /dev/null
+++ b/apps/payment/templates/payment/gift_certificate_item.html
@@ -0,0 +1,36 @@
+{% load thumbnail %}
+{% load static %}
+{% load data_liked from data_liked %}
+
+
+
+
+
+
+
+ {% if user_gift_certificate and not user_gift_certificate.bonuses_sent %}
+ подарочный сертификат
+ {% else %}подарочный сертификат{% endif %}
+
{{ gift_certificate.price|floatformat:"-2" }}₽
+
+ {% if user_gift_certificate %}
+ {% if user_gift_certificate.bonuses_sent %}
+
+
+ Получено
+
+ {% else %}
+
+
+ Ожидает получения
+
+ {% endif %}
+ {% else %}
+
Купить сертификат
+ {% endif %}
+
diff --git a/apps/payment/templates/payment/gift_certificate_items.html b/apps/payment/templates/payment/gift_certificate_items.html
new file mode 100644
index 00000000..05730083
--- /dev/null
+++ b/apps/payment/templates/payment/gift_certificate_items.html
@@ -0,0 +1,4 @@
+{% for gift_certificate in gift_certificates %}
+ {% cycle 'theme_pink2' 'theme_cyan' 'theme_violet2' as theme_color silent %}
+ {% include "payment/gift_certificate_item.html" %}
+{% endfor %}
diff --git a/apps/payment/templates/payment/gift_certificate_payment_success.html b/apps/payment/templates/payment/gift_certificate_payment_success.html
new file mode 100644
index 00000000..793eb25e
--- /dev/null
+++ b/apps/payment/templates/payment/gift_certificate_payment_success.html
@@ -0,0 +1,13 @@
+{% extends "templates/lilcity/index.html" %} {% load static %} {% block content %}
+
+
+
+
Вы успешно приобрели подарочный сертификат!
+
Мы отправили письмо с сертификатом на вашу почту.
+
+
+
+
+{% endblock content %}
diff --git a/apps/payment/templates/payment/gift_certificates.html b/apps/payment/templates/payment/gift_certificates.html
new file mode 100644
index 00000000..5fa4bf2e
--- /dev/null
+++ b/apps/payment/templates/payment/gift_certificates.html
@@ -0,0 +1,35 @@
+{% extends "templates/lilcity/index.html" %} {% load static %}
+
+{% block content %}
+
+
+
+ Подарочные сертификаты
+
+
+
+
+
+
+
Подарочный сертификат Lil City - отличный презент на любой праздник.
+А также сертификат можно подарить без повода - развитие
творческого потенциала всегда уместно и актуально.
+При покупке подарочного сертификата мы высылаем письмо,
+где будет уникальный код и уникальная ссылка. Письмо или ссылку
+на него вы можете переслать другому. Сертификатом можно
+воспользоваться, перейдя по ссылке.
+
+
+
Сертификаты
+
+ {% include "payment/gift_certificate_items.html" %}
+
+
+
+{% endblock content %}
diff --git a/apps/payment/templates/payment/payment_success.html b/apps/payment/templates/payment/payment_success.html
index 7d174018..9d256634 100644
--- a/apps/payment/templates/payment/payment_success.html
+++ b/apps/payment/templates/payment/payment_success.html
@@ -7,10 +7,17 @@
- {% else %}
+ {% endif %}
+ {% if course %}
Вы успешно приобрели курс!
+ {% endif %}
+ {% if gift_certificate %}
+
Вы успешно приобрели подарочный сертификат!
+
{% endif %}
diff --git a/apps/payment/views.py b/apps/payment/views.py
index 6be7734f..02a2b874 100644
--- a/apps/payment/views.py
+++ b/apps/payment/views.py
@@ -1,5 +1,5 @@
from decimal import Decimal
-
+import short_url
import arrow
import json
import logging
@@ -12,9 +12,9 @@ import calendar
from django.contrib import messages
from django.contrib.auth.decorators import login_required
-from django.http import HttpResponse
+from django.http import HttpResponse, Http404
from django.shortcuts import redirect, get_object_or_404
-from django.views.generic import View, TemplateView
+from django.views.generic import View, TemplateView, DetailView
from django.views.decorators.csrf import csrf_exempt
from django.urls import reverse_lazy
from django.utils.decorators import method_decorator
@@ -27,7 +27,8 @@ from apps.course.models import Course
from apps.school.models import SchoolSchedule
from apps.payment.tasks import transaction_to_mixpanel, product_payment_to_mixpanel, transaction_to_roistat
-from .models import AuthorBalance, CoursePayment, SchoolPayment, Payment, UserBonus
+from .models import AuthorBalance, CoursePayment, SchoolPayment, Payment, UserBonus, GiftCertificate, \
+ GiftCertificatePayment, UserGiftCertificate
logger = logging.getLogger('django')
@@ -216,6 +217,8 @@ class PaymentwallCallbackView(View):
product_payment_class = CoursePayment
elif product_type_name == 'school':
product_payment_class = SchoolPayment
+ elif product_type_name == 'gift_certificate':
+ product_payment_class = GiftCertificatePayment
else:
return HttpResponse(status=403)
@@ -264,6 +267,15 @@ class PaymentwallCallbackView(View):
'created_at': payment.created_at,
'update_at': payment.update_at,
}
+ elif product_type_name == 'gift_certificate':
+ properties = {
+ 'payment_id': payment.id,
+ 'amount': payment.amount,
+ 'status': payment.status,
+ 'gift_certificate': payment.gift_certificate.id,
+ 'created_at': payment.created_at,
+ 'update_at': payment.update_at,
+ }
payment.save()
product_payment_to_mixpanel.delay(
@@ -297,3 +309,84 @@ class PaymentwallCallbackView(View):
else:
raise DisallowedPingbackHost
return HttpResponse(status=403)
+
+
+class GiftCertificatesView(TemplateView):
+ model = GiftCertificate
+ template_name = 'payment/gift_certificates.html'
+
+ def get(self, request, *args, **kwargs):
+ gift_certificates = GiftCertificate.objects.all()
+ context = self.get_context_data(**kwargs)
+ context['gift_certificates'] = gift_certificates
+ return self.render_to_response(context)
+
+
+@method_decorator(login_required, name='dispatch')
+class GiftCertificateBuyView(TemplateView):
+ model = GiftCertificate
+ template_name = 'payment/paymentwall_widget.html'
+
+ def get(self, request, pk, *args, **kwargs):
+ gift_certificate = get_object_or_404(GiftCertificate, pk=pk)
+ roistat_visit = request.COOKIES.get('roistat_visit', None)
+ gift_certificate_payment = GiftCertificatePayment.objects.create(
+ user=request.user,
+ gift_certificate=gift_certificate,
+ roistat_visit=roistat_visit,)
+ context = self.get_context_data(**kwargs)
+ product = Product(
+ f'gift_certificate_{gift_certificate_payment.id}',
+ gift_certificate_payment.amount,
+ 'RUB',
+ 'Подарочный сертификат',
+ )
+ host = urlsplit(self.request.META.get('HTTP_REFERER'))
+ host = str(host[0]) + '://' + str(host[1])
+ widget = Widget(
+ str(request.user.id),
+ 'p1_1',
+ [product],
+ extra_params={
+ 'lang': 'ru',
+ 'evaluation': 1,
+ 'demo': 1,
+ 'test_mode': 1,
+ 'success_url': host + str(reverse_lazy('gift-certificate-payment-success', args=[gift_certificate_payment.id])),
+ 'failure_url': host + str(reverse_lazy('payment-error')),
+ }
+ )
+ context['widget'] = widget.get_html_code()
+ return self.render_to_response(context)
+
+
+@method_decorator(login_required, name='dispatch')
+class GiftCertificateBuySuccessView(TemplateView):
+ template_name = 'payment/gift_certificate_payment_success.html'
+
+ def get(self, request, payment_id=None, *args, **kwargs):
+ try:
+ GiftCertificatePayment.objects.get(id=payment_id)
+ except:
+ raise Http404()
+ return self.render_to_response(context={'gift_certificate': True})
+
+
+@method_decorator(login_required, name='dispatch')
+class GiftCertificateGetView(TemplateView):
+ template_name = 'payment/gift_certificate_get.html'
+
+ def get(self, request, slug, *args, **kwargs):
+ try:
+ ugs = get_object_or_404(UserGiftCertificate, pk=short_url.decode_url(slug))
+ except:
+ raise Http404()
+ if UserBonus.objects.filter(payment=ugs.payment).exists():
+ raise Http404()
+ bonuses = UserBonus.objects.create(user=request.user, amount=ugs.gift_certificate.price,
+ payment=ugs.payment)
+ ugs.bonuses_sent = bonuses
+ ugs.save()
+ context = self.get_context_data(**kwargs)
+ return self.render_to_response(context)
+
diff --git a/apps/school/templates/school/livelesson_detail.html b/apps/school/templates/school/livelesson_detail.html
index d3e5c5af..095dbb01 100644
--- a/apps/school/templates/school/livelesson_detail.html
+++ b/apps/school/templates/school/livelesson_detail.html
@@ -5,9 +5,15 @@
{% block twurl %}{{ request.build_absolute_uri }}{% endblock twurl %}
{% block ogtitle %}{{ livelesson.title }} - {{ block.super }}{% endblock ogtitle %}
{% block ogurl %}{{ request.build_absolute_uri }}{% endblock ogurl %}
-{% if livelesson.cover and livelesson.cover.image %}
-{% block ogimage %}http://{{request.META.HTTP_HOST}}{{ livelesson.cover.image.url }}{% endblock ogimage %}
-{% endif %}
+{% block ogimage %}
+ {% if livelesson.cover and livelesson.cover.image %}http://{{request.META.HTTP_HOST}}{{ livelesson.cover.image.url }}{% else %}{{ block.super }}{% endif %}
+{% endblock ogimage %}
+{% block ogimage-width %}
+ {% if livelesson.cover and livelesson.cover.image %}{{ livelesson.cover.image.width }}{% else %}{{ block.super }}{% endif %}
+{% endblock ogimage-width %}
+{% block ogimage-height %}
+ {% if livelesson.cover and livelesson.cover.image %}{{ livelesson.cover.image.height }}{% else %}{{ block.super }}{% endif %}
+{% endblock ogimage-height %}
{% block content %}
diff --git a/apps/school/templates/school/livelesson_detail_unauth.html b/apps/school/templates/school/livelesson_detail_unauth.html
new file mode 100644
index 00000000..4493928f
--- /dev/null
+++ b/apps/school/templates/school/livelesson_detail_unauth.html
@@ -0,0 +1,27 @@
+{% extends "templates/lilcity/index.html" %}
+{% load static %}
+{% block title %}{{ livelesson.title }} - {{ block.super }}{% endblock title %}
+
+{% block twurl %}{{ request.build_absolute_uri }}{% endblock twurl %}
+{% block ogtitle %}{{ livelesson.title }} - {{ block.super }}{% endblock ogtitle %}
+{% block ogurl %}{{ request.build_absolute_uri }}{% endblock ogurl %}
+{% block ogimage %}
+ {% if livelesson.cover and livelesson.cover.image %}http://{{request.META.HTTP_HOST}}{{ livelesson.cover.image.url }}{% else %}{{ block.super }}{% endif %}
+{% endblock ogimage %}
+{% block ogimage-width %}
+ {% if livelesson.cover and livelesson.cover.image %}{{ livelesson.cover.image.width }}{% else %}{{ block.super }}{% endif %}
+{% endblock ogimage-width %}
+{% block ogimage-height %}
+ {% if livelesson.cover and livelesson.cover.image %}{{ livelesson.cover.image.height }}{% else %}{{ block.super }}{% endif %}
+{% endblock ogimage-height %}
+
+{% block content %}
+
+
+
+ Чтобы посмотреть урок необходимо авторизоваться
+
+
Войти
+
+
+{% endblock content %}
diff --git a/apps/school/templates/summer/promo.html b/apps/school/templates/summer/promo.html
index 8b1ed12e..7d12fac4 100644
--- a/apps/school/templates/summer/promo.html
+++ b/apps/school/templates/summer/promo.html
@@ -20,6 +20,9 @@
{% if is_purchased %}ваша подписка истекает {{ subscription_ends_humanize }}
перейти к оплате{% endif %}
+ {% if not is_purchased and not is_purchased_future %}
+
Подарить другу
+ {% endif %}
diff --git a/apps/school/views.py b/apps/school/views.py
index a3317ad0..a3cc379b 100644
--- a/apps/school/views.py
+++ b/apps/school/views.py
@@ -57,26 +57,28 @@ class LiveLessonsView(ListView):
return queryset
-@method_decorator(login_required, name='dispatch')
class LiveLessonsDetailView(DetailView):
model = LiveLesson
template_name = 'school/livelesson_detail.html'
def get(self, request, pk=None):
self.object = self.get_object()
- is_purchased = SchoolPayment.objects.filter(
- user=request.user,
- date_start__lte=now(),
- date_end__gte=now() - timedelta(days=7),
- status__in=[
- Pingback.PINGBACK_TYPE_REGULAR,
- Pingback.PINGBACK_TYPE_GOODWILL,
- Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,
- ],
- weekdays__contains=[self.object.date.weekday() + 1],
- ).exists()
- if not is_purchased and request.user.role not in [User.ADMIN_ROLE, User.TEACHER_ROLE]:
- raise Http404
+ if request.user.is_authenticated:
+ is_purchased = SchoolPayment.objects.filter(
+ user=request.user,
+ date_start__lte=now(),
+ date_end__gte=now() - timedelta(days=7),
+ status__in=[
+ Pingback.PINGBACK_TYPE_REGULAR,
+ Pingback.PINGBACK_TYPE_GOODWILL,
+ Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,
+ ],
+ weekdays__contains=[self.object.date.weekday() + 1],
+ ).exists()
+ if not is_purchased and request.user.role not in [User.ADMIN_ROLE, User.TEACHER_ROLE]:
+ raise Http404
+ else:
+ self.template_name = 'school/livelesson_detail_unauth.html'
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
diff --git a/apps/user/templates/user/profile.html b/apps/user/templates/user/profile.html
index 9ad4d552..b8e19a19 100644
--- a/apps/user/templates/user/profile.html
+++ b/apps/user/templates/user/profile.html
@@ -2,7 +2,10 @@
-
Редактировать
+
{% endif %}
+ {% if user_gift_certificates.exists %}
+ {% for ugs in user_gift_certificates %}
+ {% cycle 'theme_pink2' 'theme_cyan' 'theme_violet2' as theme_color silent %}
+ {% include "payment/gift_certificate_item.html" with gift_certificate=ugs.gift_certificate user_gift_certificate=ugs %}
+ {% endfor %}
+ {% endif %}
{% if paid.exists %}
{% include "course/course_items.html" with course_items=paid %}
{% endif %}
- {% if not is_school_purchased and not paid.exists %}
+ {% if not is_school_purchased and not paid.exists and not user_gift_certificates.exists %}
Вы пока ничего не приобрели...
diff --git a/apps/user/views.py b/apps/user/views.py
index f4ea0ebb..e456af1c 100644
--- a/apps/user/views.py
+++ b/apps/user/views.py
@@ -24,7 +24,7 @@ from apps.config.models import Config
from apps.course.models import Course
from apps.notification.utils import send_email
from apps.school.models import SchoolSchedule
-from apps.payment.models import AuthorBalance, CoursePayment, SchoolPayment, Payment
+from apps.payment.models import AuthorBalance, CoursePayment, SchoolPayment, Payment, UserGiftCertificate
from apps.user.models import AuthorRequest, EmailSubscription, SubscriptionCategory
from .forms import AuthorRequesForm, UserEditForm, WithdrawalForm
@@ -59,6 +59,7 @@ class ProfileView(TemplateView):
author=self.object,
)
context['is_author'] = context['published'] or self.request.user.role == User.AUTHOR_ROLE
+ context['user_gift_certificates'] = UserGiftCertificate.objects.filter(user=self.request.user)
context['paid'] = Course.objects.filter(
payments__in=CoursePayment.objects.filter(
user=self.object,
diff --git a/docker/.env.example b/docker/.env.example
index 94fdccb7..f637abb9 100644
--- a/docker/.env.example
+++ b/docker/.env.example
@@ -9,7 +9,7 @@ POSTGRES_PASSWORD=GPVs/E/{5&qe
DJANGO_SETTINGS_MODULE=project.settings
DATABASE_SERVICE_HOST=db
SECRET_KEY=jelm*91lj(_-o20+6^a+bgv!4s6e_efry^#+f#=1ak&s1xr-2j
-MAILGUN_API_KEY=key-ec6af2d43d031d59bff6b1c8fb9390cb
+MAILGUN_API_KEY=key-ec6af2d43d031d59bff6b1c8fb9390c
MAILGUN_SENDER_DOMAIN=mail.9ev.ru
DEFAULT_FROM_EMAIL=postmaster@mail.9ev.ru
TWILIO_ACCOUNT=ACdf4a96b776cc764bc3ec0f0e136ba550
diff --git a/docker/.env.review b/docker/.env.review
index 351dc795..dc0ff7ab 100644
--- a/docker/.env.review
+++ b/docker/.env.review
@@ -9,7 +9,7 @@ POSTGRES_PASSWORD=GPVs/E/{5&qe
DJANGO_SETTINGS_MODULE=project.settings
DATABASE_SERVICE_HOST=db
SECRET_KEY=jelm*91lj(_-o20+6^a+bgv!4s6e_efry^#+f#=1ak&s1xr-2j
-MAILGUN_API_KEY=key-ec6af2d43d031d59bff6b1c8fb9390cb
+MAILGUN_API_KEY=key-ec6af2d43d031d59bff6b1c8fb9390c
MAILGUN_SENDER_DOMAIN=mail.9ev.ru
DEFAULT_FROM_EMAIL=postmaster@mail.9ev.ru
TWILIO_ACCOUNT=ACdf4a96b776cc764bc3ec0f0e136ba550
diff --git a/project/settings.py b/project/settings.py
index e92ac41b..3bd90b7d 100644
--- a/project/settings.py
+++ b/project/settings.py
@@ -185,8 +185,8 @@ LOGIN_URL = '/'
# https://github.com/anymail/django-anymail
ANYMAIL = {
- 'MAILGUN_API_KEY': os.getenv('MAILGUN_API_KEY', 'key-ec6af2d43d031d59bff6b1c8fb9390cb'),
- 'MAILGUN_SENDER_DOMAIN': os.getenv('MAILGUN_SENDER_DOMAIN', 'mail.9ev.ru'),
+ 'MAILGUN_API_KEY': os.getenv('MAILGUN_API_KEY', ''),
+ 'MAILGUN_SENDER_DOMAIN': os.getenv('MAILGUN_SENDER_DOMAIN', ''),
}
EMAIL_BACKEND = 'anymail.backends.mailgun.EmailBackend'
DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL', 'postmaster@mail.9ev.ru')
diff --git a/project/templates/blocks/baner.html b/project/templates/blocks/baner.html
index df8b81e0..4f289bce 100644
--- a/project/templates/blocks/baner.html
+++ b/project/templates/blocks/baner.html
@@ -1,11 +1,13 @@
{% if baner %}
{% if request.user_agent.is_mobile %}
-
+
{% else %}
-
+
+
+
{{ baner.text }}
{{ baner.button_text }}
diff --git a/project/templates/blocks/header.html b/project/templates/blocks/header.html
index 312d06ec..5ad39c12 100644
--- a/project/templates/blocks/header.html
+++ b/project/templates/blocks/header.html
@@ -41,6 +41,10 @@
+
{% include 'templates/blocks/user_menu.html' %}
diff --git a/project/templates/blocks/lil_store_js.html b/project/templates/blocks/lil_store_js.html
index 7df6d16d..244eb875 100644
--- a/project/templates/blocks/lil_store_js.html
+++ b/project/templates/blocks/lil_store_js.html
@@ -28,6 +28,7 @@
referrer: '{{ referrer.id|default:'' }}',
referrerName: '{% if referrer %}{{ referrer.get_full_name }}{% endif %}',
isReferralUrl: {{ is_referral_url|yesno:"true,false" }},
+ isGiftCertificateUrl: {{ is_gift_certificate_url|yesno:"true,false" }},
},
};
diff --git a/project/templates/blocks/popup_enter_gift_code.html b/project/templates/blocks/popup_enter_gift_code.html
new file mode 100644
index 00000000..7ad5c256
--- /dev/null
+++ b/project/templates/blocks/popup_enter_gift_code.html
@@ -0,0 +1,24 @@
+{% load static %}
+
diff --git a/project/templates/blocks/popup_gift_certificate.html b/project/templates/blocks/popup_gift_certificate.html
new file mode 100644
index 00000000..f1d551a8
--- /dev/null
+++ b/project/templates/blocks/popup_gift_certificate.html
@@ -0,0 +1,31 @@
+{% load static %}
+
diff --git a/project/templates/blocks/promo.html b/project/templates/blocks/promo.html
index 18ad35d2..1dcb87d2 100644
--- a/project/templates/blocks/promo.html
+++ b/project/templates/blocks/promo.html
@@ -26,6 +26,10 @@
{% endif %}
class="main__btn btn"
>{% if not school_schedule.weekday in school_schedules_purchased %}Получить доступ{% else %}Смотреть урок{% endif %}
+
+ {% if not is_purchased and not is_purchased_future %}
+
Подарить другу
+ {% endif %}
{% elif user.is_authenticated and online_coming_soon and school_schedule and school_schedule.start_at_humanize %}
@@ -45,6 +49,10 @@
{% endif %}
class="main__btn btn"
>{% if not school_schedule.weekday in school_schedules_purchased %}Получить доступ{% else %}Смотреть урок{% endif %}
+
+ {% if not is_purchased and not is_purchased_future %}
+
Подарить другу
+ {% endif %}
{% else %}
@@ -59,6 +67,7 @@
>
купить доступ от {{ min_school_price }} руб./месяц
+
Подарить другу
{% else %}
Подробнее
{% endif %}
diff --git a/project/templates/lilcity/index.html b/project/templates/lilcity/index.html
index 60d189f9..fb789f50 100644
--- a/project/templates/lilcity/index.html
+++ b/project/templates/lilcity/index.html
@@ -18,9 +18,9 @@
{% comment %}
{% endcomment %}
-
-
-
+
+
+
@@ -145,6 +145,10 @@
{% if course %}
{% include "templates/blocks/popup_course_buy.html" %}
{% endif %}
+ {% if is_gift_certificate_url %}
+ {% include "templates/blocks/popup_gift_certificate.html" %}
+ {% endif %}
+ {% include "templates/blocks/popup_enter_gift_code.html" %}
{% include "templates/blocks/popup_course_lock.html" %}
{% include "templates/blocks/popup_subscribe.html" %}
{% include "templates/blocks/popup_capture_email.html" %}
diff --git a/project/urls.py b/project/urls.py
index 38773131..4946c577 100644
--- a/project/urls.py
+++ b/project/urls.py
@@ -34,8 +34,8 @@ from apps.user.views import (
from apps.payment.views import (
CourseBuySuccessView, CourseBuyView,
PaymentwallCallbackView, SchoolBuySuccessView,
- SchoolBuyView,
-)
+ SchoolBuyView, GiftCertificatesView, GiftCertificateBuyView,
+ GiftCertificateBuySuccessView, GiftCertificateGetView)
from .views import AboutView, IndexView, SchoolSchedulesView
@@ -91,6 +91,11 @@ urlpatterns = [
path('contest/
/', ContestView.as_view(), name='contest'),
path('contest-work//', ContestWorkView.as_view(), name='contest_work'),
path('contest-work//comment', contest_work_comment, name='contest_work_comment'),
+ path('gift-certificates', GiftCertificatesView.as_view(), name='gift-certificates'),
+ path('gift-certificate//checkout', GiftCertificateBuyView.as_view(), name='gift-certificate-checkout'),
+ path('payments/gift-certificate//success', GiftCertificateBuySuccessView.as_view(),
+ name='gift-certificate-payment-success'),
+ path('gift-certificate//get', GiftCertificateGetView.as_view(), name='gift-certificate-get'),
]
diff --git a/project/views.py b/project/views.py
index 29189994..d563f0c6 100644
--- a/project/views.py
+++ b/project/views.py
@@ -9,7 +9,7 @@ from paymentwall.pingback import Pingback
from apps.course.models import Course
from apps.school.models import SchoolSchedule
-from apps.payment.models import SchoolPayment
+from apps.payment.models import SchoolPayment, UserGiftCertificate
User = get_user_model()
@@ -23,6 +23,7 @@ class IndexView(TemplateView):
def get_context_data(self):
referrer = self.request.GET.get('referrer')
+ user_gift_certificate = self.request.GET.get('gift-certificate')
is_referral_url = bool(referrer)
context = super().get_context_data()
@@ -77,7 +78,17 @@ class IndexView(TemplateView):
else:
referrer = None
+ if user_gift_certificate:
+ try:
+ user_gift_certificate = short_url.decode_url(user_gift_certificate)
+ user_gift_certificate = UserGiftCertificate.objects.get(pk=user_gift_certificate, bonuses_sent__isnull=True)
+ except:
+ user_gift_certificate = None
+
context.update({
+ 'gift_certificate': user_gift_certificate.gift_certificate if user_gift_certificate else None,
+ 'user_gift_certificate': user_gift_certificate,
+ 'is_gift_certificate_url': bool(user_gift_certificate),
'referrer': referrer,
'is_referral_url': is_referral_url,
'online': online,
diff --git a/requirements.txt b/requirements.txt
index 052bb32e..27daa65a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -33,3 +33,4 @@ django-imagekit
pusher==2.0.1
short_url
sendgrid
+drf_dynamic_fields
diff --git a/web/src/img/clock.png b/web/src/img/clock.png
new file mode 100644
index 00000000..dd49d20c
Binary files /dev/null and b/web/src/img/clock.png differ
diff --git a/web/src/img/done.png b/web/src/img/done.png
new file mode 100644
index 00000000..28a2934a
Binary files /dev/null and b/web/src/img/done.png differ
diff --git a/web/src/img/fb.png b/web/src/img/fb.png
new file mode 100644
index 00000000..a31cdcd3
Binary files /dev/null and b/web/src/img/fb.png differ
diff --git a/web/src/img/gift-certificates/1000.jpg b/web/src/img/gift-certificates/1000.jpg
new file mode 100644
index 00000000..9d682d7f
Binary files /dev/null and b/web/src/img/gift-certificates/1000.jpg differ
diff --git a/web/src/img/gift-certificates/10000.jpg b/web/src/img/gift-certificates/10000.jpg
new file mode 100644
index 00000000..9695841d
Binary files /dev/null and b/web/src/img/gift-certificates/10000.jpg differ
diff --git a/web/src/img/gift-certificates/2000.jpg b/web/src/img/gift-certificates/2000.jpg
new file mode 100644
index 00000000..ec0483ac
Binary files /dev/null and b/web/src/img/gift-certificates/2000.jpg differ
diff --git a/web/src/img/gift-certificates/3000.jpg b/web/src/img/gift-certificates/3000.jpg
new file mode 100644
index 00000000..bb6f3970
Binary files /dev/null and b/web/src/img/gift-certificates/3000.jpg differ
diff --git a/web/src/img/gift-certificates/5000.jpg b/web/src/img/gift-certificates/5000.jpg
new file mode 100644
index 00000000..5bb83064
Binary files /dev/null and b/web/src/img/gift-certificates/5000.jpg differ
diff --git a/web/src/img/instagram.png b/web/src/img/instagram.png
new file mode 100644
index 00000000..da7043cc
Binary files /dev/null and b/web/src/img/instagram.png differ
diff --git a/web/src/img/twitter.png b/web/src/img/twitter.png
new file mode 100644
index 00000000..9ce49587
Binary files /dev/null and b/web/src/img/twitter.png differ
diff --git a/web/src/js/modules/popup.js b/web/src/js/modules/popup.js
index 22f27ffb..22505dc8 100644
--- a/web/src/js/modules/popup.js
+++ b/web/src/js/modules/popup.js
@@ -245,6 +245,21 @@ $(document).ready(function () {
}
popup.data('next-url', nextUrl);
}
+
+ if( data === '.js-popup-enter-gift-code') {
+ const $giftCode = popup.find('.enter-gift-code__code');
+ const $giftError = popup.find('.enter-gift-code__error');
+ $giftCode.val('');
+ $giftError.text('');
+ popup.find('.enter-gift-code__btn').one('click', () => {
+ const code = $giftCode.val();
+ if(! code){
+ $giftError.text('Укажите код');
+ return false;
+ }
+ window.location.href = `/gift-certificate/${code}/get`;
+ });
+ }
});
$('.js-popup-close').on('click', function(e){
@@ -271,7 +286,13 @@ $(document).ready(function () {
}
});
- function showPopup(popupName){
+
+ if(window.LIL_STORE.flags.isGiftCertificateUrl){
+ popup = $('.js-popup-gift-certificate');
+ showPopup();
+ }
+
+ function showPopup(){
if(! popup && popupName){
popup = $(popupName);
}
diff --git a/web/src/sass/_common.sass b/web/src/sass/_common.sass
index feb8e121..657907f5 100755
--- a/web/src/sass/_common.sass
+++ b/web/src/sass/_common.sass
@@ -26,12 +26,15 @@
$pink: #FF9393
$pink-light: #FDF8F9
+$pink2: #FEB9B9
$purple: #B995D9
$green: #8ECFC0
$green-light: #5BD700
+$cyan: #B6DFD6
$gray: #A7A7A7
$blue: #4A90E2
$viol: #B995D9
+$viol2: #A186BD
$bg: #f8f8f8
$border: #E6E6E6
$cl: #191919
@@ -206,6 +209,10 @@ button
&_pink
background: #ff9393
color: white
+ &_stroke-black
+ background: none
+ border: 1px solid $cl
+ color: $cl
&_md
padding: 18px 24px 17px
+m
@@ -1063,6 +1070,7 @@ a[name]
flex: 0 0 40px
&__info
flex: 0 0 calc(100% - 50px)
+ display: flex
&__name,
&__date
+fb
@@ -1070,9 +1078,8 @@ a[name]
text-transform: uppercase
letter-spacing: 0.5px
line-height: 1.1
- &__name
- margin-bottom: 5px
&__meta
+ flex: 1
display: flex
align-items: center
&__date
@@ -1635,6 +1642,12 @@ a.grey-link
color: $green
&_violet
color: $viol
+ &_violet2
+ color: $viol2
+ &_pink2
+ color: $pink2
+ &_cyan
+ color: $cyan
&_lg
font-size: 20px
letter-spacing: 4px
@@ -2546,6 +2559,7 @@ a.grey-link
&__item
display: flex
align-items: center
+ color: inherit
&__item
//&:not(:last-child)
margin-right: 40px
@@ -3202,12 +3216,16 @@ a.grey-link
background: transparent
border: 1px solid $gray
color: $gray
- &_edit
- position: absolute
- top: 0
- right: 0
- +m
- display: none !important
+ margin-bottom: 10px
+ width: 100%
+ &__btns
+ position: absolute
+ top: 0
+ right: 0
+ display: flex
+ flex-direction: column
+ +m
+ display: none !important
&__row
display: flex
margin-bottom: 25px
@@ -3987,7 +4005,7 @@ a.grey-link
padding-right: 20px
flex: 0 0 90px
&--content
- flex: 0 0 calc(100% - 254px)
+ flex: 1
+m
flex: 0 0 calc(100% - 114px)
&--toggle
@@ -4306,6 +4324,13 @@ a
background: white
+m
height: auto
+ &__image-wrap
+ background: -moz-linear-gradient(top, rgba(0,0,0,0) 0%, rgba(159,159,159,0) 72%, rgba(221,221,221,0.65) 100%)
+ background: -webkit-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(159,159,159,0) 72%,rgba(221,221,221,0.65) 100%)
+ background: linear-gradient(to bottom, rgba(0,0,0,0) 0%,rgba(159,159,159,0) 72%,rgba(221,221,221,0.65) 100%)
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00000000', endColorstr='#a6dddddd',GradientType=0 )
+ width: 100%
+ height: 100%
&__image
height: 100%
+m
@@ -4410,3 +4435,64 @@ a
&__lil-coin-img
margin-bottom: -5px
margin-right: 4px
+
+
+.gift-certificates
+ display: flex
+ margin: 0 -10px
+ flex-wrap: wrap
+ +m
+ display: block
+ margin: 0
+ &__item
+ display: block
+ margin: 0 10px 60px
+ color: $cl
+ flex: 0 0 calc(33.33% - 20px)
+ +t
+ margin-bottom: 50px !important
+ +m
+ margin: 0 0 30px
+ &__preview
+ display: block
+ position: relative
+ margin-bottom: 15px
+ border-radius: 2px
+ color: $cl
+ overflow: hidden
+ width: 300px
+ height: 200px
+ +t
+ margin-bottom: 10px
+ &__cover
+ object-fit: cover;
+ width: 100%;
+ &__details
+ display: flex
+ margin-bottom: 10px
+ &__price
+ margin-left: auto
+ +fb
+ font-size: 12px
+ letter-spacing: 2px
+ color: $cl
+ &__title
+ text-transform: uppercase
+ &__status
+ font-family: 'ProximaNova-Bold', serif
+ font-size: 12px
+ letter-spacing: 2px
+ text-transform: uppercase
+ & .icon
+ width: 16px
+ display: inline-block
+ height: 16px
+ margin-bottom: -4px
+ &__buy-btn
+ width: 100%
+ &__preview.theme_pink2
+ background: $pink2
+ &__preview.theme_cyan
+ background: $cyan
+ &__preview.theme_violet2
+ background: $viol2
diff --git a/web/webpack.config.js b/web/webpack.config.js
index 7455fec9..8156ab03 100644
--- a/web/webpack.config.js
+++ b/web/webpack.config.js
@@ -14,6 +14,7 @@ module.exports = {
sprite: glob('./src/icons/*.svg'),
images: glob('./src/img/*.*'),
imagesCertificates: glob('./src/img/user-certificates/*'),
+ imagesGiftCertificates: glob('./src/img/gift-certificates/*'),
fonts: glob('./src/fonts/*')
},
output: {
@@ -85,7 +86,8 @@ module.exports = {
},
{
test: /\.(png|gif|jpg|svg)$/,
- exclude: [path.resolve(__dirname, 'src/icons'), path.resolve(__dirname, 'src/img/user-certificates')],
+ exclude: [path.resolve(__dirname, 'src/icons'), path.resolve(__dirname, 'src/img/user-certificates'),
+ path.resolve(__dirname, 'src/img/gift-certificates')],
loader: 'file-loader?name=[name].[ext]&outputPath=./img/'
},
{
@@ -93,6 +95,11 @@ module.exports = {
include: path.resolve(__dirname, 'src/img/user-certificates'),
loader: 'file-loader?name=[name].[ext]&outputPath=./img/user-certificates/'
},
+ {
+ test: /\.(png|jpg)$/,
+ include: path.resolve(__dirname, 'src/img/gift-certificates'),
+ loader: 'file-loader?name=[name].[ext]&outputPath=./img/gift-certificates/'
+ },
{
test: /\.(ttf|otf|eot|woff(2)?)(\?[a-z0-9]+)?$/,
loader: 'file-loader?name=[name].[ext]'