diff --git a/api/v1/views.py b/api/v1/views.py
index c2b43019..1122282d 100644
--- a/api/v1/views.py
+++ b/api/v1/views.py
@@ -71,7 +71,7 @@ from apps.payment.models import (
CoursePayment, SchoolPayment, UserBonus,
)
from apps.school.models import SchoolSchedule, LiveLesson
-from apps.user.models import AuthorRequest
+from apps.user.models import AuthorRequest, EmailLog
from project.pusher import pusher
from project.sengrid import get_sendgrid_client
@@ -694,6 +694,11 @@ class CaptureEmail(views.APIView):
email = request.data.get('email')
sg = get_sendgrid_client()
+ if not email:
+ return Response({'error': 'No email'}, status=status.HTTP_400_BAD_REQUEST)
+
+ EmailLog.objects.create(email=email, source=EmailLog.SOURCE_TRIAL_LESSON)
+
# берем все списки
response = sg.client.contactdb.lists.get()
if response.status_code != 200:
diff --git a/apps/content/admin.py b/apps/content/admin.py
index c025f198..c38b753d 100644
--- a/apps/content/admin.py
+++ b/apps/content/admin.py
@@ -8,7 +8,7 @@ from polymorphic.admin import (
from apps.content.models import (
Baner, Content, Image, Text, ImageText, Video,
Gallery, GalleryImage, ImageObject,
- Contest,ContestWork,
+ Contest, ContestWork, FAQ,
)
@@ -90,3 +90,8 @@ class ContestAdmin(admin.ModelAdmin):
@admin.register(ContestWork)
class ContestWorkAdmin(admin.ModelAdmin):
base_model = ContestWork
+
+
+@admin.register(FAQ)
+class FAQAdmin(admin.ModelAdmin):
+ base_model = FAQ
diff --git a/apps/content/templates/content/contest.html b/apps/content/templates/content/contest.html
index 9edbe8ec..49a0bd19 100644
--- a/apps/content/templates/content/contest.html
+++ b/apps/content/templates/content/contest.html
@@ -45,3 +45,8 @@
{% endblock content %}
+
+{% block pre_app_js %}
+
+
+{% endblock pre_app_js %}
diff --git a/apps/content/templates/content/contest_edit.html b/apps/content/templates/content/contest_edit.html
index d1c26b62..856a6d9b 100644
--- a/apps/content/templates/content/contest_edit.html
+++ b/apps/content/templates/content/contest_edit.html
@@ -12,7 +12,8 @@
{% block content %}
{% endblock content %}
-{% block foot %}
-
-
-{% endblock foot %}
+
+{% block pre_app_js %}
+
+
+{% endblock pre_app_js %}
diff --git a/apps/course/management/__init__.py b/apps/course/management/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/apps/course/management/commands/__init__.py b/apps/course/management/commands/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/apps/course/management/commands/update_courses_slug.py b/apps/course/management/commands/update_courses_slug.py
new file mode 100644
index 00000000..24999a2e
--- /dev/null
+++ b/apps/course/management/commands/update_courses_slug.py
@@ -0,0 +1,20 @@
+from unidecode import unidecode
+
+from django.core.management.base import BaseCommand, CommandError
+from django.db.models import Q
+from django.utils.text import slugify
+from apps.course.models import Course
+
+
+class Command(BaseCommand):
+ help = 'Upload users to Roistat'
+
+ def handle(self, *args, **options):
+ courses = Course.objects.filter(Q(slug__isnull=True) | Q(slug=''))
+ for course in courses:
+ course.slug = slugify(unidecode(course.title[:90]))
+ try:
+ course.save()
+ except:
+ course.slug += str(course.id)
+ course.save()
diff --git a/apps/course/models.py b/apps/course/models.py
index 42a1dd81..553e6c7c 100644
--- a/apps/course/models.py
+++ b/apps/course/models.py
@@ -1,10 +1,13 @@
import arrow
from random import shuffle
from uuid import uuid4
+from unidecode import unidecode
+
from django.db import models
from django.core.exceptions import ValidationError
from django.utils import timezone
from django.utils.timezone import now
+from django.utils.text import slugify
from django.contrib.auth import get_user_model
from django.urls import reverse_lazy
from django.conf import settings
@@ -119,24 +122,24 @@ class Course(BaseModel, DeactivatedMixin):
def __str__(self):
return str(self.id) + ' ' + self.title
- # def save(self, *args, **kwargs):
- # if not self.slug:
- # self.slug = slugify(
- # self.title[:90],
- # allow_unicode=True
- # )
-
- # if Course.objects.filter(slug=self.slug).exclude(id=self.id).exists():
- # self.slug += '_' + str(uuid4())[:6]
+ def save(self, *args, **kwargs):
+ if not self.slug:
+ self.slug = slugify(unidecode(self.title[:90]))
+ if self.slug:
+ if self.slug.isdigit():
+ self.slug = 'course%s' % self.slug
+ slug = self.slug
+ while Course.objects.filter(slug__iexact=self.slug).exclude(id=self.id).exists():
+ self.slug = '%s_%s' % (slug, str(uuid4())[-4:])
- # return super().save()
+ return super().save()
@property
def url(self):
return self.get_absolute_url()
def get_absolute_url(self):
- return reverse_lazy('course', args=[self.slug or self.id])
+ return reverse_lazy('course', args=[self.slug.lower() if self.slug else self.id])
@property
def is_free(self):
diff --git a/apps/course/templates/course/_items.html b/apps/course/templates/course/_items.html
index a5bfa123..acbccf69 100644
--- a/apps/course/templates/course/_items.html
+++ b/apps/course/templates/course/_items.html
@@ -53,7 +53,8 @@
{% if course.old_price %}
{{ course.old_price|floatformat:"-2" }}₽
{% endif %}
- {{ course.price|floatformat:"-2" }}₽
+ {{ course.price|floatformat:"-2" }}₽
{% endif %}
{{ course.title }}
diff --git a/apps/course/templates/course/course.html b/apps/course/templates/course/course.html
index 94fd1938..bf57e971 100644
--- a/apps/course/templates/course/course.html
+++ b/apps/course/templates/course/course.html
@@ -335,8 +335,7 @@
-
-
Задавайте вопросы:
+
{% if request.user.is_authenticated %}Задавайте вопросы:{% else %}Комментарии:{% endif %}
diff --git a/apps/course/templates/course/course_edit.html b/apps/course/templates/course/course_edit.html
index ee3143dd..83990c00 100644
--- a/apps/course/templates/course/course_edit.html
+++ b/apps/course/templates/course/course_edit.html
@@ -7,13 +7,22 @@
Создание {% if live == 'true' %}стрима{% else %}курса{% endif %}
{% endif %}
{% endblock title%}
+
+{% block header_buttons %}
+ {% if live == 'true' %}
+
+ {% else %}
+
+ {% endif %}
+{% endblock header_buttons %}
+
{% block content %}
{% endblock content %}
-{% block foot %}
-
-
-{% endblock foot %}
+{% block pre_app_js %}
+
+
+{% endblock pre_app_js %}
diff --git a/apps/course/templates/course/course_only_lessons.html b/apps/course/templates/course/course_only_lessons.html
index d56e641e..3a9aeae7 100644
--- a/apps/course/templates/course/course_only_lessons.html
+++ b/apps/course/templates/course/course_only_lessons.html
@@ -192,7 +192,7 @@
{% endif %}
-
Задавайте вопросы:
+
{% if request.user.is_authenticated %}Задавайте вопросы:{% else %}Комментарии:{% endif %}
diff --git a/apps/course/templates/course/lesson.html b/apps/course/templates/course/lesson.html
index e4f083f0..0c33cf6b 100644
--- a/apps/course/templates/course/lesson.html
+++ b/apps/course/templates/course/lesson.html
@@ -113,7 +113,7 @@
{% endcomment %}
-
Задавайте вопросы:
+
{% if request.user.is_authenticated %}Задавайте вопросы:{% else %}Комментарии:{% endif %}
diff --git a/apps/course/views.py b/apps/course/views.py
index 07ca6bad..5e625c42 100644
--- a/apps/course/views.py
+++ b/apps/course/views.py
@@ -200,6 +200,32 @@ class CourseView(DetailView):
# ((self.object.status != Course.PUBLISHED and request.user.role != User.ADMIN_ROLE) or
# (self.object.status != Course.PUBLISHED and request.user.role != User.AUTHOR_ROLE and self.object.author != request.user)):
+ def get_object(self, queryset=None):
+ if queryset is None:
+ queryset = self.get_queryset()
+
+ pk = self.kwargs.get(self.pk_url_kwarg)
+ slug = self.kwargs.get(self.slug_url_kwarg)
+ if pk is not None:
+ queryset = queryset.filter(pk=pk)
+
+ if slug is not None and (pk is None or self.query_pk_and_slug):
+ slug_field = self.get_slug_field()
+ queryset = queryset.filter(**{'%s__iexact' % slug_field: slug})
+
+ if pk is None and slug is None:
+ raise AttributeError("Generic detail view %s must be called with "
+ "either an object pk or a slug."
+ % self.__class__.__name__)
+
+ try:
+ # Get the single item from the filtered queryset
+ obj = queryset.get()
+ except queryset.model.DoesNotExist:
+ raise Http404(_("No %(verbose_name)s found matching the query") %
+ {'verbose_name': queryset.model._meta.verbose_name})
+ return obj
+
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.request.user.is_authenticated:
diff --git a/apps/school/models.py b/apps/school/models.py
index 4ba85193..38889f44 100644
--- a/apps/school/models.py
+++ b/apps/school/models.py
@@ -147,7 +147,7 @@ class LiveLesson(BaseModel, DeactivatedMixin):
return self.get_absolute_url()
def get_absolute_url(self):
- return reverse_lazy('school:lesson-detail', args=[self.date.strftime('%d-%m-%y')])
+ return reverse_lazy('school:lesson-detail', kwargs={'lesson_date': self.date.strftime('%d-%m-%y')})
def stream_index(self):
return self.stream.split('/')[-1]
diff --git a/apps/school/templates/school/livelessons_list.html b/apps/school/templates/school/livelessons_list.html
index 2f435dcc..161a6629 100644
--- a/apps/school/templates/school/livelessons_list.html
+++ b/apps/school/templates/school/livelessons_list.html
@@ -11,7 +11,7 @@
{% for livelesson in livelesson_list %}
-
+
diff --git a/apps/school/urls.py b/apps/school/urls.py
index c36664f0..9ac1d078 100644
--- a/apps/school/urls.py
+++ b/apps/school/urls.py
@@ -1,4 +1,4 @@
-from django.urls import path, include
+from django.urls import path, re_path
from .views import (
LiveLessonsView, LiveLessonEditView,
@@ -12,6 +12,6 @@ urlpatterns = [
path('lessons/', LiveLessonsView.as_view(), name='lessons'),
path('lessons/create', LiveLessonEditView.as_view(), name='lessons-create'),
path('lessons//edit', LiveLessonEditView.as_view(), name='lessons-edit'),
- path('lessons//', LiveLessonsDetailView.as_view(), name='lesson-detail'),
- path('', LiveLessonsDetailView.as_view(), name='lesson-detail'),
+ path('lessons//', LiveLessonsDetailView.as_view(), name='lesson-detail-id'),
+ re_path(r'(?P\d+\-\d+\-\d+)', LiveLessonsDetailView.as_view(), name='lesson-detail'),
]
diff --git a/apps/user/admin.py b/apps/user/admin.py
index df3e01d9..63398df0 100644
--- a/apps/user/admin.py
+++ b/apps/user/admin.py
@@ -3,7 +3,7 @@ from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.utils.translation import gettext_lazy as _
-from .models import AuthorRequest, EmailSubscription, SubscriptionCategory
+from .models import AuthorRequest, EmailSubscription, SubscriptionCategory, EmailLog
User = get_user_model()
@@ -47,3 +47,8 @@ class EmailSubscriptionAdmin(admin.ModelAdmin):
'user',
'email',
)
+
+
+@admin.register(EmailLog)
+class EmailLogAdmin(admin.ModelAdmin):
+ pass
diff --git a/apps/user/migrations/0029_emaillog.py b/apps/user/migrations/0029_emaillog.py
new file mode 100644
index 00000000..ed154689
--- /dev/null
+++ b/apps/user/migrations/0029_emaillog.py
@@ -0,0 +1,22 @@
+# Generated by Django 2.0.7 on 2019-01-25 08:18
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('user', '0028_auto_20181214_0107'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='EmailLog',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('email', models.EmailField(max_length=254, verbose_name='email address')),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ('source', models.PositiveSmallIntegerField(choices=[(1, 'Пробный урок')])),
+ ],
+ ),
+ ]
diff --git a/apps/user/models.py b/apps/user/models.py
index 9ab545e7..5a7337bd 100644
--- a/apps/user/models.py
+++ b/apps/user/models.py
@@ -304,3 +304,14 @@ class Referral(models.Model):
from apps.payment.models import UserBonus
UserBonus.objects.create(user=self.referral, amount=referral_bonus, payment=self.payment, referral=self)
UserBonus.objects.create(user=self.referrer, amount=referrer_bonus, payment=self.payment, referral=self)
+
+
+class EmailLog(models.Model):
+ SOURCE_TRIAL_LESSON = 1
+ SOURCE_CHOICES = (
+ (SOURCE_TRIAL_LESSON, 'Пробный урок'),
+ )
+
+ email = models.EmailField(_('email address'))
+ created_at = models.DateTimeField(auto_now_add=True)
+ source = models.PositiveSmallIntegerField(choices=SOURCE_CHOICES)
diff --git a/apps/user/templates/user/bonus-history.html b/apps/user/templates/user/bonus-history.html
index 105592a5..ef3bf9d8 100644
--- a/apps/user/templates/user/bonus-history.html
+++ b/apps/user/templates/user/bonus-history.html
@@ -79,3 +79,7 @@
{% endblock content %}
+
+{% block pre_app_js %}
+
+{% endblock pre_app_js %}
diff --git a/apps/user/templates/user/profile-settings.html b/apps/user/templates/user/profile-settings.html
index 04eecdec..7de0e74c 100644
--- a/apps/user/templates/user/profile-settings.html
+++ b/apps/user/templates/user/profile-settings.html
@@ -323,3 +323,7 @@
// (new Inputmask('+7 (999) 999-99-99')).mask(document.querySelector('[name=phone]'));
{% endblock foot %}
+
+{% block pre_app_js %}
+
+{% endblock pre_app_js %}
diff --git a/project/templates/blocks/lil_store_js.html b/project/templates/blocks/lil_store_js.html
index b2eeb14c..cc334c94 100644
--- a/project/templates/blocks/lil_store_js.html
+++ b/project/templates/blocks/lil_store_js.html
@@ -21,10 +21,14 @@
components: {},
urls: {
courses: "{% url 'courses' %}",
+ courseEdit: /\/course\/\d+\/edit/,
+ courseCreate: "{% url 'course_create' %}",
userProfileEdit: "{% url 'user-edit-profile' %}",
userProfile: "{% url 'user-profile' %}",
userBonuses: "{% url 'user-bonuses' %}",
faq: "{% url 'faq' %}",
+ contestEdit: /contest\/\w+\/edit/,
+ userGalleryEdit: "{% url 'user-gallery-edit' %}",
},
flags: {
referrer: '{{ referrer.id|default:'' }}',
@@ -33,8 +37,12 @@
isGiftCertificateUrl: {{ is_gift_certificate_url|yesno:"true,false" }},
},
data: {},
- urlIs: (urlPatternName) => {
- return window.location.pathname.search(window.LIL_STORE.urls[urlPatternName]) > -1;
+ urlIs: (urlPatternNames) => {
+ if(! Array.isArray(urlPatternNames)){
+ urlPatternNames = [urlPatternNames];
+ }
+ return urlPatternNames.filter(
+ urlPatternName => window.location.pathname.search(window.LIL_STORE.urls[urlPatternName]) > -1).length > 0;
},
isIndexPage: window.location.pathname == '/',
};
diff --git a/project/templates/lilcity/edit_index.html b/project/templates/lilcity/edit_index.html
index a88a7e84..90d99fea 100644
--- a/project/templates/lilcity/edit_index.html
+++ b/project/templates/lilcity/edit_index.html
@@ -53,11 +53,8 @@
- {% if live == 'true' %}
-
- {% else %}
-
- {% endif %}
+ {% block header_buttons %}
+ {% endblock header_buttons %}
{% include 'templates/blocks/user_menu.html' %}
@@ -316,6 +313,7 @@
{% include 'templates/blocks/lil_store_js.html' %}
+{% block pre_app_js %}{% endblock pre_app_js %}
-
-
diff --git a/web/src/components/ContestWorks.vue b/web/src/components/ContestWorks.vue
index b0d6f493..156acf93 100644
--- a/web/src/components/ContestWorks.vue
+++ b/web/src/components/ContestWorks.vue
@@ -74,8 +74,8 @@
}
}
}
-
- heights[column] += workHeight;
+
+ heights[column] += workHeight;
[first, second, third][column].push(work);
index++;
}
@@ -112,28 +112,3 @@
components: {ContestWork},
}
-
-
diff --git a/web/src/components/CourseRedactor.vue b/web/src/components/CourseRedactor.vue
index eaec96d4..073e9f49 100644
--- a/web/src/components/CourseRedactor.vue
+++ b/web/src/components/CourseRedactor.vue
@@ -34,7 +34,8 @@
v-model="course.title"
placeholder="Добавить заголовок">
-
@@ -45,7 +46,7 @@
@@ -273,6 +274,7 @@
price: null,
old_price: null,
age: 0,
+ slug: '',
url: '',
coverImage: '',
kit__body: null,
@@ -473,8 +475,8 @@
},
onCourseNameInput() {
this.$v.course.title.$touch();
- if (!this.slugChanged) {
- this.course.url = slugify(this.course.title);
+ if (!this.slugChanged && !this.$v.course.status) {
+ this.course.slug = (slugify(this.course.title) || '').toLowerCase();
}
},
removeLesson(lessonIndex) {
@@ -662,7 +664,7 @@
if(this.live) {
window.location = '/school/lessons';
} else {
- api.publishCourse(this.course.id, this.accessToken)
+ api.publishCourse(this.course, this.accessToken)
.then((response) => {
window.location = '/course/on-moderation';
})
@@ -741,24 +743,6 @@
}
},
saveCourseDraft: function (newValue, oldValue) {
- //console.log('saveCourseDraft');
- // if (!oldValue.id) {
- // return;
- // }
-
-
- // if(this.live) {
- // if(!this.course.date || this.course.short_description == '' || this.course.title == '') {
- // //console.log('live valiedation error');
- // return;
- // }
- // } else {
- // if(this.course.short_description == '' || this.course.title == '') {
- // //console.log('course validation error');
- // return;
- // }
- // }
-
if (this.savingDebounceTimeout) {
clearTimeout(this.savingDebounceTimeout);
}
@@ -771,13 +755,14 @@
this.courseSaving = true;
this.changeSavingStatus();
const courseObject = this.course;
- courseObject.url = (courseObject.url) ? slugify(courseObject.url):courseObject.url;
+ courseObject.slug = courseObject.slug && slugify(courseObject.slug);
api.saveCourse(courseObject, this.accessToken)
.then((response) => {
this.courseSaving = false;
this.changeSavingStatus(true);
this.courseSyncHook = true;
const courseData = api.convertCourseJson(response.data);
+ this.course.slug = courseData.slug;
if (this.course.coverImage) {
courseData.coverImage = this.course.coverImage;
}
@@ -804,19 +789,11 @@
})
}
});
- if (courseData.url) {
- this.slugChanged = true;
- }
if(courseData.id) {
this.course.id = courseData.id;
}
- /*if(this.live && courseData.date) {
- this.course.date = _.find(this.scheduleOptions, function(item){
- return item.value == courseData.date;
- });
- }*/
this.$nextTick(() => {
this.courseSyncHook = false;
});
@@ -1029,11 +1006,8 @@
}
},
courseFullUrl() {
- if (!this.course.url) {
- return `https://lil.city/course/${this.course.id}`;
- }
- let suffix = this.course.url ? this.course.url : 'ваша_ссылка';
- return `https://lil.city/course/${suffix}`;
+ let suffix = this.course.slug || this.course.id || 'ваша_ссылка';
+ return `https://lil.school/course/${suffix}`;
},
},
beforeDestroy() {
@@ -1074,168 +1048,4 @@
}
-
diff --git a/web/src/components/UploadContestWork.vue b/web/src/components/UploadContestWork.vue
index 326c05c4..60d5f657 100644
--- a/web/src/components/UploadContestWork.vue
+++ b/web/src/components/UploadContestWork.vue
@@ -153,41 +153,3 @@
}
}
-
-
diff --git a/web/src/components/blocks/ContestWork.vue b/web/src/components/blocks/ContestWork.vue
index 617b9fab..2cb1def9 100644
--- a/web/src/components/blocks/ContestWork.vue
+++ b/web/src/components/blocks/ContestWork.vue
@@ -25,38 +25,3 @@
components: {Likes},
}
-
-
diff --git a/web/src/js/app.js b/web/src/js/app.js
index 1588467f..8b6be846 100644
--- a/web/src/js/app.js
+++ b/web/src/js/app.js
@@ -13,7 +13,6 @@ import "./modules/tabs";
import "./modules/popup";
import "./modules/courses";
import "./modules/comments";
-import "./modules/comments";
import "./modules/password-show";
import "./modules/notification";
import "./modules/mixpanel";
@@ -25,9 +24,8 @@ import Vue from 'vue';
import Vuelidate from 'vuelidate';
import VueAutosize from '../components/directives/autosize'
import Comments from '../components/Comments';
-import UploadContestWork from '../components/UploadContestWork.vue';
-import ContestWorks from '../components/ContestWorks.vue';
import Likes from '../components/blocks/Likes.vue';
+import FAQ from '../components/FAQ.vue';
Vue.use(Vuelidate);
Vue.use(VueAutosize);
@@ -38,23 +36,13 @@ if (process.env.NODE_ENV === 'development') {
}
const components = {
- UploadContestWork,
- ContestWorks,
- Likes,
- Comments,
+ 'likes': Likes,
+ 'comments': Comments,
+ 'faq': FAQ,
};
Object.assign(components, window.LIL_STORE.components);
-if(window.LIL_STORE.urlIs('faq')){
- const FAQ = require('../components/FAQ.vue');
- components['faq'] = FAQ.default;
-}
-if(window.LIL_STORE.urlIs('userProfileEdit') || window.LIL_STORE.urlIs('userBonuses')){
- const profile = require("./modules/profile");
- profile.main();
-}
-
const app = new Vue({
el: '#lilcity-vue-app',
data() {
diff --git a/web/src/js/contest-redactor.js b/web/src/js/contest-redactor.js
deleted file mode 100644
index afbbb193..00000000
--- a/web/src/js/contest-redactor.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import ContestRedactor from '../components/ContestRedactor.vue'
-
-window.LIL_STORE.components['contest-redactor'] = ContestRedactor;
-
diff --git a/web/src/js/modules/api.js b/web/src/js/modules/api.js
index ed60c229..93b3281c 100644
--- a/web/src/js/modules/api.js
+++ b/web/src/js/modules/api.js
@@ -113,7 +113,7 @@ export const api = {
deferred_start_at: deferredStart,
duration: courseObject.duration || 0,
is_featured: courseObject.is_featured,
- slug: courseObject.url,
+ slug: (courseObject.slug || '').toLowerCase(),
date: (courseObject.date) ? courseObject.date.value:null,
stream: courseObject.stream,
cover: courseObject.coverImageId ? courseObject.coverImageId : null,
@@ -194,7 +194,7 @@ export const api = {
time: deferredTime,
duration: courseJSON.duration,
is_featured: courseJSON.is_featured,
- url: courseJSON.slug,
+ slug: courseJSON.slug,
stream: courseJSON.stream,
coverImageId: courseJSON.cover && courseJSON.cover.id ? courseJSON.cover.id : null,
coverImage: courseJSON.cover && courseJSON.cover.image ? courseJSON.cover.image : null,
@@ -437,8 +437,9 @@ export const api = {
}
});
},
- publishCourse: (courseId, accessToken) => {
- return api.patch(`/api/v1/courses/${courseId}/`, {status: 1}, {
+ publishCourse: (course, accessToken) => {
+ course.status = 1;
+ return api.patch(`/api/v1/courses/${course.id}/`, course, {
headers: {
'Authorization': `Token ${accessToken}`,
}
diff --git a/web/src/js/pages/contest-edit.js b/web/src/js/pages/contest-edit.js
new file mode 100644
index 00000000..95b05559
--- /dev/null
+++ b/web/src/js/pages/contest-edit.js
@@ -0,0 +1,5 @@
+import '../../sass/components/contest-edit.scss';
+
+import ContestRedactor from '../../components/ContestRedactor.vue';
+
+window.LIL_STORE.components['contest-redactor'] = ContestRedactor;
diff --git a/web/src/js/pages/contest.js b/web/src/js/pages/contest.js
new file mode 100644
index 00000000..84902ebb
--- /dev/null
+++ b/web/src/js/pages/contest.js
@@ -0,0 +1,7 @@
+import '../../sass/components/contest.scss';
+
+import UploadContestWork from '../../components/UploadContestWork.vue';
+import ContestWorks from '../../components/ContestWorks.vue';
+
+window.LIL_STORE.components['upload-contest-work'] = UploadContestWork;
+window.LIL_STORE.components['contest-works'] = ContestWorks;
diff --git a/web/src/js/course-redactor.js b/web/src/js/pages/course-edit.js
similarity index 79%
rename from web/src/js/course-redactor.js
rename to web/src/js/pages/course-edit.js
index 45b3c970..25b1545b 100644
--- a/web/src/js/course-redactor.js
+++ b/web/src/js/pages/course-edit.js
@@ -1,5 +1,7 @@
-import 'babel-polyfill'
-import CourseRedactor from '../components/CourseRedactor.vue'
+import '../../sass/components/course-edit.scss';
+
+import 'babel-polyfill';
+import CourseRedactor from '../../components/CourseRedactor.vue';
import $ from 'jquery';
window.LIL_STORE.components['course-redactor'] = CourseRedactor;
diff --git a/web/src/js/modules/profile.js b/web/src/js/pages/profile.js
similarity index 94%
rename from web/src/js/modules/profile.js
rename to web/src/js/pages/profile.js
index 11f60b76..9ac8120a 100644
--- a/web/src/js/modules/profile.js
+++ b/web/src/js/pages/profile.js
@@ -1,9 +1,9 @@
import $ from 'jquery';
import slugify from 'slugify';
import ClipboardJS from 'clipboard';
-import {showNotification} from './notification';
+import {showNotification} from '../modules/notification';
-export const main = () => {
+$(document).ready(function () {
if(window.LIL_STORE.urlIs('userBonuses')){
$('#referrer-url').select().click(function(){
$(this).select();
@@ -53,4 +53,4 @@ export const main = () => {
});
changeSlug();
}
-}
+});
diff --git a/web/src/js/user-gallery-edit.js b/web/src/js/pages/user-gallery-edit.js
similarity index 77%
rename from web/src/js/user-gallery-edit.js
rename to web/src/js/pages/user-gallery-edit.js
index 8c957d11..c7ce4449 100644
--- a/web/src/js/user-gallery-edit.js
+++ b/web/src/js/pages/user-gallery-edit.js
@@ -1,6 +1,7 @@
-import BlockImages from '../components/blocks/BlockImages.vue';
+import BlockImages from '../../components/blocks/BlockImages.vue';
import $ from 'jquery';
-import {api} from "./modules/api";
+import {api} from "../modules/api";
+
window.LIL_STORE.components['block-images'] = BlockImages;
diff --git a/web/src/sass/app.sass b/web/src/sass/app.sass
index 82cdc94a..38c37335 100755
--- a/web/src/sass/app.sass
+++ b/web/src/sass/app.sass
@@ -2,4 +2,4 @@
@import helpers/all
@import generated/sprite-svg
@import common
-@import '~baguettebox.js/dist/baguetteBox.min.css';
\ No newline at end of file
+@import '~baguettebox.js/dist/baguetteBox.min.css';
diff --git a/web/src/sass/components/contest-edit.scss b/web/src/sass/components/contest-edit.scss
new file mode 100644
index 00000000..574739d4
--- /dev/null
+++ b/web/src/sass/components/contest-edit.scss
@@ -0,0 +1,35 @@
+.upload-contest-work {
+
+ .popup__wrap {
+ padding: 35px 35px 0;
+ }
+
+ .title {
+ text-align: center; font-size: 24px;
+
+ .text__curve {
+ right: 55px;
+ width: 170px;
+ bottom: -40px;
+ }
+ }
+
+ .kit__photo {
+ height: 400px;
+ }
+
+ .kit__photo.has-image {
+ border: none;
+ }
+
+ .kit__photo-image {
+ max-height: 400px;
+ height: auto;
+ width: auto;
+ }
+
+ .kit__file {
+ bottom: 0;
+ }
+
+}
diff --git a/web/src/sass/components/contest.scss b/web/src/sass/components/contest.scss
new file mode 100644
index 00000000..bc243ebf
--- /dev/null
+++ b/web/src/sass/components/contest.scss
@@ -0,0 +1,55 @@
+.contest-works {
+ width: 100%;
+}
+.contest-works__works {
+ text-align: left;
+ display: flex;
+}
+.contest-works__column {
+ display: flex;
+ flex-direction: column;
+ margin-right: 20px;
+ width: 300px;
+}
+.contest-works__loader {
+ width: 100%;
+ height: 30px;
+ position: relative;
+}
+.contest-works__no-works {
+ text-align: center;
+ width: 100%;
+}
+
+.contest-work-item {
+ break-inside: avoid;
+ border-radius: 8px;
+ overflow: hidden;
+ margin-bottom: 20px;
+ transition: opacity .4s ease-in-out;
+ text-transform: uppercase;
+ font-weight: bold;
+ color: black;
+ border: 1px solid #ececec;
+ display: block;
+}
+.contest-work-item__img {
+ width: 100%;
+ height: auto;
+}
+.contest-work-item__info {
+ display: flex;
+ padding: 5px 10px;
+}
+.contest-work-item__age {
+ color: #919191;
+}
+.contest-work-item__bio {
+ flex: calc(100% - 70px);
+}
+
+@media only screen and (min-width: 1023px) {
+ .contest-works:hover .contest-work-item:not(:hover) {
+ opacity: 0.4;
+ }
+}
diff --git a/web/src/sass/components/course-edit.scss b/web/src/sass/components/course-edit.scss
new file mode 100644
index 00000000..ad1d219e
--- /dev/null
+++ b/web/src/sass/components/course-edit.scss
@@ -0,0 +1,166 @@
+.vdp-datepicker__calendar {
+ width: 240px;
+ margin-top: 10px;
+ padding: 5px;
+ background: white;
+ box-shadow: 0 2px 20px 0 rgba(0, 0, 0, 0.1);
+ z-index: 99 !important;
+
+ header {
+ display: flex;
+ margin-bottom: 5px;
+ -ms-flex-align: center;
+ align-items: center;
+ }
+
+ .prev, .next {
+ font-size: 0;
+ cursor: pointer;
+ order: 1;
+ width: auto !important;
+ padding: 10px;
+ }
+
+ .prev {
+ order: 1;
+ }
+
+ .next {
+ order: 3;
+ }
+
+ .prev:before, .next:before {
+ content: '';
+ display: block;
+ width: 10px;
+ height: 10px;
+ border: solid #E6E6E6;
+ border-width: 2px 2px 0 0;
+ }
+
+ .prev:after, .next:after {
+ content: none !important;
+ }
+
+ .prev:before {
+ transform: rotate(-135deg);
+ }
+
+ .next:before {
+ transform: rotate(45deg);
+ }
+}
+
+.kit__preview {
+ img {
+ width: 140px;
+ height: 140px;
+ }
+}
+
+.kit__photo {
+ width: 140px;
+ height: 140px;
+}
+
+.kit__section-remove {
+ button.sortable__handle {
+ margin-right: 10px;
+ cursor: -webkit-grab;
+ cursor: grab;
+
+ svg.icon-hamburger {
+ width: 1em;
+ height: 1em;
+ }
+ }
+}
+
+.sortable-ghost, .sortable-chosen {
+ background: white;
+ border-radius: 10px;
+}
+
+.course-redactor__preview-button-bg-save {
+ background-color: #58fffb;
+}
+.course-redactor__preview-button {
+ transition: backgroundColor 0.5s ease-in-out;
+}
+
+.field_text {
+ height: 270px;
+ overflow: scroll;
+}
+
+.courses__item {
+ flex: 0 0 300px;
+}
+
+.courses__item .field {
+ margin-bottom: 0;
+}
+
+.courses__content .redactor-box {
+ overflow-x: visible;
+ overflow-y: auto;
+ max-height: 200px;
+ background: none;
+ margin-top: 10px;
+}
+
+.courses__content .redactor-layer{
+ background: none;
+}
+
+.courses__theme {
+ flex: 1;
+}
+
+.courses__price {
+ margin-left: 20px;
+}
+
+.courses__preview {
+ .upload {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ }
+
+ .upload__title {
+ color: #888888;
+ font-size: 16px;
+ margin-top: 100px;
+ width: 100%;
+ text-align: center;
+ }
+
+ .upload__file {
+ width: 100%;
+ height: 100%;
+ }
+}
+
+.course-delete-cover {
+ left: 5px;
+ position: absolute;
+ bottom: 3px;
+}
+
+.field-category .select__head {
+ font-size: inherit;
+ line-height: inherit;
+ height: auto;
+}
+
+.datetime-fields {
+ display: flex;
+}
+
+.field-time {
+ margin-left: 10px;
+ flex: 50%;
+}
diff --git a/web/src/sass/pages/course-edit.scss b/web/src/sass/pages/course-edit.scss
new file mode 100644
index 00000000..ad1d219e
--- /dev/null
+++ b/web/src/sass/pages/course-edit.scss
@@ -0,0 +1,166 @@
+.vdp-datepicker__calendar {
+ width: 240px;
+ margin-top: 10px;
+ padding: 5px;
+ background: white;
+ box-shadow: 0 2px 20px 0 rgba(0, 0, 0, 0.1);
+ z-index: 99 !important;
+
+ header {
+ display: flex;
+ margin-bottom: 5px;
+ -ms-flex-align: center;
+ align-items: center;
+ }
+
+ .prev, .next {
+ font-size: 0;
+ cursor: pointer;
+ order: 1;
+ width: auto !important;
+ padding: 10px;
+ }
+
+ .prev {
+ order: 1;
+ }
+
+ .next {
+ order: 3;
+ }
+
+ .prev:before, .next:before {
+ content: '';
+ display: block;
+ width: 10px;
+ height: 10px;
+ border: solid #E6E6E6;
+ border-width: 2px 2px 0 0;
+ }
+
+ .prev:after, .next:after {
+ content: none !important;
+ }
+
+ .prev:before {
+ transform: rotate(-135deg);
+ }
+
+ .next:before {
+ transform: rotate(45deg);
+ }
+}
+
+.kit__preview {
+ img {
+ width: 140px;
+ height: 140px;
+ }
+}
+
+.kit__photo {
+ width: 140px;
+ height: 140px;
+}
+
+.kit__section-remove {
+ button.sortable__handle {
+ margin-right: 10px;
+ cursor: -webkit-grab;
+ cursor: grab;
+
+ svg.icon-hamburger {
+ width: 1em;
+ height: 1em;
+ }
+ }
+}
+
+.sortable-ghost, .sortable-chosen {
+ background: white;
+ border-radius: 10px;
+}
+
+.course-redactor__preview-button-bg-save {
+ background-color: #58fffb;
+}
+.course-redactor__preview-button {
+ transition: backgroundColor 0.5s ease-in-out;
+}
+
+.field_text {
+ height: 270px;
+ overflow: scroll;
+}
+
+.courses__item {
+ flex: 0 0 300px;
+}
+
+.courses__item .field {
+ margin-bottom: 0;
+}
+
+.courses__content .redactor-box {
+ overflow-x: visible;
+ overflow-y: auto;
+ max-height: 200px;
+ background: none;
+ margin-top: 10px;
+}
+
+.courses__content .redactor-layer{
+ background: none;
+}
+
+.courses__theme {
+ flex: 1;
+}
+
+.courses__price {
+ margin-left: 20px;
+}
+
+.courses__preview {
+ .upload {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ }
+
+ .upload__title {
+ color: #888888;
+ font-size: 16px;
+ margin-top: 100px;
+ width: 100%;
+ text-align: center;
+ }
+
+ .upload__file {
+ width: 100%;
+ height: 100%;
+ }
+}
+
+.course-delete-cover {
+ left: 5px;
+ position: absolute;
+ bottom: 3px;
+}
+
+.field-category .select__head {
+ font-size: inherit;
+ line-height: inherit;
+ height: auto;
+}
+
+.datetime-fields {
+ display: flex;
+}
+
+.field-time {
+ margin-left: 10px;
+ flex: 50%;
+}
diff --git a/web/webpack.config.js b/web/webpack.config.js
index c2182909..21ead790 100644
--- a/web/webpack.config.js
+++ b/web/webpack.config.js
@@ -5,26 +5,27 @@ const NODE_ENV = process.env.NODE_ENV || 'development';
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');
+
module.exports = {
entry: {
app: "./src/js/app.js",
- courseRedactor: "./src/js/course-redactor.js",
- contestRedactor: "./src/js/contest-redactor.js",
- userGalleryEdit: "./src/js/user-gallery-edit.js",
+ courseEdit: "./src/js/pages/course-edit.js",
+ contest: "./src/js/pages/contest.js",
+ contestEdit: "./src/js/pages/contest-edit.js",
+ profile: "./src/js/pages/profile.js",
+ userGalleryEdit: "./src/js/pages/user-gallery-edit.js",
mixpanel: "./src/js/third_party/mixpanel-2-latest.js",
sprite: glob('./src/icons/*.svg'),
images: glob('./src/img/*.*'),
imagesCertificates: glob('./src/img/user-certificates/*'),
imagesGiftCertificates: glob('./src/img/gift-certificates/*'),
imagesReviews: glob('./src/img/reviews/*'),
- fonts: glob('./src/fonts/*')
+ fonts: glob('./src/fonts/*'),
},
output: {
path: path.join(__dirname, "build"),
filename: NODE_ENV === 'development' ? '[name].js' : '[name].js',
library: '[name]',
- //filename: NODE_ENV === 'development' ? '[name].js' : '[name].[id].[chunkhash].js',
- //library: '[name]',
publicPath: '/static/',
},
module: {