From 262f2a4dbf7ce763d2a6b51bd08e2f67d0755b8c Mon Sep 17 00:00:00 2001 From: gzbender Date: Wed, 5 Dec 2018 02:29:21 +0300 Subject: [PATCH] =?UTF-8?q?LIL-702=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20FAQ?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/v1/serializers/content.py | 8 +++- api/v1/urls.py | 4 +- api/v1/views.py | 9 +++- apps/content/migrations/0023_faq.py | 21 ++++++++++ apps/content/models.py | 5 +++ apps/content/templates/content/faq.html | 18 ++++++++ apps/content/views.py | 16 +++++++- project/templates/blocks/lil_store_js.html | 2 + project/templates/lilcity/index.html | 2 +- project/urls.py | 3 +- web/src/components/FAQ.vue | 35 ++++++++++++++++ web/src/js/app.js | 48 +++++++++++----------- web/src/js/modules/profile.js | 4 +- web/src/sass/_common.sass | 20 +++++++++ 14 files changed, 162 insertions(+), 33 deletions(-) create mode 100644 apps/content/migrations/0023_faq.py create mode 100644 apps/content/templates/content/faq.html create mode 100644 web/src/components/FAQ.vue diff --git a/api/v1/serializers/content.py b/api/v1/serializers/content.py index 5b6d2c1d..4225bcde 100644 --- a/api/v1/serializers/content.py +++ b/api/v1/serializers/content.py @@ -4,7 +4,7 @@ from django.conf import settings from apps.content.models import ( Baner, Content, Image, Text, ImageText, Video, - Gallery, GalleryImage, ImageObject,) + Gallery, GalleryImage, ImageObject, FAQ) from . import Base64ImageField @@ -256,3 +256,9 @@ class ContentSerializer(serializers.ModelSerializer): return GallerySerializer(obj, context=self.context).to_representation(obj) return super(ContentSerializer, self).to_representation(obj) + +class FAQSerializer(serializers.ModelSerializer): + + class Meta: + model = FAQ + fields = '__all__' diff --git a/api/v1/urls.py b/api/v1/urls.py index 68a96ea2..500c51c8 100644 --- a/api/v1/urls.py +++ b/api/v1/urls.py @@ -19,7 +19,7 @@ from .views import ( SchoolScheduleViewSet, LiveLessonViewSet, PaymentViewSet, ObjectCommentsViewSet, ContestViewSet, ContestWorkViewSet, - AuthorBalanceUsersViewSet, CaptureEmail) + AuthorBalanceUsersViewSet, CaptureEmail, FAQViewSet) router = DefaultRouter() router.register(r'author-requests', AuthorRequestViewSet, base_name='author-requests') @@ -41,7 +41,7 @@ router.register(r'image-texts', ImageTextViewSet, base_name='image-texts') router.register(r'videos', VideoViewSet, base_name='videos') router.register(r'galleries', GalleryViewSet, base_name='galleries') router.register(r'gallery-images', GalleryImageViewSet, base_name='gallery-images') - +router.register(r'faq', FAQViewSet, base_name='faq') router.register(r'school-schedules', SchoolScheduleViewSet, base_name='school-schedules') router.register(r'users', UserViewSet, base_name='users') diff --git a/api/v1/views.py b/api/v1/views.py index 37127268..a567a7cc 100644 --- a/api/v1/views.py +++ b/api/v1/views.py @@ -28,7 +28,7 @@ from .serializers.content import ( VideoSerializer, VideoCreateSerializer, GallerySerializer, GalleryImageSerializer, GalleryImageCreateSerializer, - ImageObjectSerializer, + ImageObjectSerializer, FAQSerializer, ) from .serializers.school import ( SchoolScheduleSerializer, @@ -63,7 +63,7 @@ from apps.config.models import Config from apps.content.models import ( Baner, Image, Text, ImageText, Video, Gallery, GalleryImage, ImageObject, - Contest, ContestWork) + Contest, ContestWork, FAQ) from apps.payment.models import ( AuthorBalance, Payment, CoursePayment, SchoolPayment, @@ -712,3 +712,8 @@ class CaptureEmail(views.APIView): return Response({'status': 'ok'}) + + +class FAQViewSet(ExtendedModelViewSet): + queryset = FAQ.objects.all() + serializer_class = FAQSerializer diff --git a/apps/content/migrations/0023_faq.py b/apps/content/migrations/0023_faq.py new file mode 100644 index 00000000..28a2adcb --- /dev/null +++ b/apps/content/migrations/0023_faq.py @@ -0,0 +1,21 @@ +# Generated by Django 2.0.7 on 2018-12-04 11:17 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('content', '0022_auto_20180815_2129'), + ] + + operations = [ + migrations.CreateModel( + name='FAQ', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('question', models.TextField(max_length=1000)), + ('answer', models.TextField(max_length=1000)), + ], + ), + ] diff --git a/apps/content/models.py b/apps/content/models.py index 0c445958..d84b4d43 100644 --- a/apps/content/models.py +++ b/apps/content/models.py @@ -210,3 +210,8 @@ class ContestWork(models.Model): def get_absolute_url(self): return reverse_lazy('contest_work', args=[self.id]) + + +class FAQ(models.Model): + question = models.TextField(max_length=1000,) + answer = models.TextField(max_length=1000,) diff --git a/apps/content/templates/content/faq.html b/apps/content/templates/content/faq.html new file mode 100644 index 00000000..4672bab3 --- /dev/null +++ b/apps/content/templates/content/faq.html @@ -0,0 +1,18 @@ +{% extends "templates/lilcity/index.html" %} +{% load static %} +{% load jsonify_queryset %} + +{% block content %} +
+
+
Часто задаваемые вопросы
+ +
+
+{% endblock content %} + +{% block pre_app_js %} + +{% endblock pre_app_js %} diff --git a/apps/content/views.py b/apps/content/views.py index 4d350cca..4bb8e9fa 100644 --- a/apps/content/views.py +++ b/apps/content/views.py @@ -7,7 +7,7 @@ from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_http_methods from django.views.generic import TemplateView, DetailView -from apps.content.models import Contest, ContestWork +from apps.content.models import Contest, ContestWork, FAQ from apps.course.models import ContestWorkComment @@ -110,3 +110,17 @@ def contest_work_comment(request, contest_work_id): 'success': True, 'comment': html, }) + + +class FAQView(TemplateView): + template_name = 'content/faq.html' + + def get(self, request, *args, **kwargs): + context = self.get_context_data(**kwargs) + context['faqs'] = [{ + 'question': f.question, + 'answer': f.answer, + 'opened': 0, + } for f in FAQ.objects.all()] + return self.render_to_response(context) + diff --git a/project/templates/blocks/lil_store_js.html b/project/templates/blocks/lil_store_js.html index 244eb875..1cb5e329 100644 --- a/project/templates/blocks/lil_store_js.html +++ b/project/templates/blocks/lil_store_js.html @@ -23,6 +23,7 @@ courses: "{% url 'courses' %}", userProfileEdit: "{% url 'user-edit-profile' %}", userBonuses: "{% url 'user-bonuses' %}", + faq: "{% url 'faq' %}", }, flags: { referrer: '{{ referrer.id|default:'' }}', @@ -30,5 +31,6 @@ isReferralUrl: {{ is_referral_url|yesno:"true,false" }}, isGiftCertificateUrl: {{ is_gift_certificate_url|yesno:"true,false" }}, }, + data: {}, }; diff --git a/project/templates/lilcity/index.html b/project/templates/lilcity/index.html index fb789f50..6e994250 100644 --- a/project/templates/lilcity/index.html +++ b/project/templates/lilcity/index.html @@ -154,7 +154,7 @@ {% include "templates/blocks/popup_capture_email.html" %} {% include 'templates/blocks/lil_store_js.html' %} - + {% block pre_app_js %}{% endblock pre_app_js %} + + diff --git a/web/src/js/app.js b/web/src/js/app.js index 7a24f77a..3408c958 100644 --- a/web/src/js/app.js +++ b/web/src/js/app.js @@ -15,7 +15,6 @@ import "./modules/courses"; import "./modules/comments"; import "./modules/comments"; import "./modules/password-show"; -import {main as profileMain} from "./modules/profile"; import "./modules/notification"; import "./modules/mixpanel"; @@ -33,35 +32,38 @@ Vue.use(Vuelidate); Vue.use(VueAutosize); if (process.env.NODE_ENV === 'development') { - // Enable vue-devtools - Vue.config.devtools = true; + // Enable vue-devtools + Vue.config.devtools = true; } +window.urlIs = (urlPatternName) => { + return window.location.pathname.search(window.LIL_STORE.urls[urlPatternName]) > -1; +}; + const components = { - UploadContestWork, - ContestWorks, - Likes, - Comments, + UploadContestWork, + ContestWorks, + Likes, + Comments, }; Object.assign(components, window.LIL_STORE.components); +if(urlIs('faq')){ + const FAQ = require('../components/FAQ.vue'); + components['faq'] = FAQ.default; +} +if(urlIs('userProfileEdit') || urlIs('userBonuses')){ + const profile = require("./modules/profile"); + profile.main(); +} + const app = new Vue({ - el: '#lilcity-vue-app', - data() { - return { - store: window.LIL_STORE, - } - }, - mounted(){ - if(this.urlIs('userProfileEdit') || this.urlIs('userBonuses')){ - profileMain(this); - } - }, - methods: { - urlIs(urlPatternName){ - return window.location.pathname.search(this.store.urls[urlPatternName]) > -1; + el: '#lilcity-vue-app', + data() { + return { + store: window.LIL_STORE, + } }, - }, - components: components + components: components }); diff --git a/web/src/js/modules/profile.js b/web/src/js/modules/profile.js index 60933c3d..141e5e0e 100644 --- a/web/src/js/modules/profile.js +++ b/web/src/js/modules/profile.js @@ -3,8 +3,8 @@ import slugify from 'slugify'; import ClipboardJS from 'clipboard'; import {showNotification} from './notification'; -export const main = (app) => { - if(app.urlIs('userBonuses')){ +export const main = () => { + if(urlIs('userBonuses')){ $('#referrer-url').select().click(function(){ $(this).select(); }); diff --git a/web/src/sass/_common.sass b/web/src/sass/_common.sass index 32cb9bea..fa671cd4 100755 --- a/web/src/sass/_common.sass +++ b/web/src/sass/_common.sass @@ -2325,6 +2325,9 @@ a.grey-link width: 1.47em height: 1em +.icon-arrow-up + transform: rotate(180deg) + .auth padding: 0 20px 25px &__nav @@ -4499,3 +4502,20 @@ a background: $cyan &__preview.theme_violet2 background: $viol2 + + +.faq + &__item-head + display: flex + background: #f8f8f8 + padding: 7px 10px 5px + &__item-question + flex: 1 + &__item-opener + margin-left: 10px + cursor: pointer + & .icon + width: 16px + height: 16px + &__item-answer + padding: 10px 10px