слайдер из баннеров

remotes/origin/feature/banners-slider-24-06-19
gzbender 7 years ago
parent f4bed336b7
commit d85926213d
  1. 3
      api/v1/serializers/content.py
  2. 4
      apps/content/admin.py
  3. 29
      apps/content/migrations/0027_auto_20190621_1107.py
  4. 12
      apps/content/models.py
  5. 1
      apps/course/templates/course/courses.html
  6. 2
      apps/course/views.py
  7. 38
      project/templates/blocks/banners.html
  8. 0
      project/templates/lilcity/home.html
  9. 1
      project/templates/lilcity/index.html
  10. 6
      project/views.py
  11. 1
      web/package.json
  12. 15
      web/src/js/app.js
  13. 4
      web/src/js/modules/common.js
  14. 125
      web/src/sass/_common.sass

@ -37,8 +37,11 @@ class BannerSerializer(serializers.ModelSerializer):
'image', 'image',
'use', 'use',
'color', 'color',
'color2',
'stretch_image', 'stretch_image',
'future_date', 'future_date',
'pages',
'main_banner',
'created_at', 'created_at',
'update_at', 'update_at',
) )

@ -19,6 +19,10 @@ class BannerAdmin(admin.ModelAdmin):
'button_text', 'button_text',
'url', 'url',
'image', 'image',
'color',
'color2',
'pages',
'main_banner',
) )

@ -0,0 +1,29 @@
# Generated by Django 2.0.7 on 2019-06-21 11:07
import django.contrib.postgres.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('content', '0026_banner_stretch_image'),
]
operations = [
migrations.AddField(
model_name='banner',
name='color2',
field=models.CharField(blank=True, default='', max_length=7),
),
migrations.AddField(
model_name='banner',
name='main_banner',
field=django.contrib.postgres.fields.ArrayField(base_field=models.IntegerField(), blank=True, default=[], size=None),
),
migrations.AddField(
model_name='banner',
name='pages',
field=django.contrib.postgres.fields.ArrayField(base_field=models.IntegerField(), blank=True, default=[], size=None),
),
]

@ -5,6 +5,7 @@ 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 django.utils import timezone from django.utils import timezone
from django.contrib.postgres.fields import ArrayField
from imagekit.models import ImageSpecField from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToCover from imagekit.processors import ResizeToCover
@ -141,27 +142,28 @@ class GalleryImage(models.Model):
class Banner(models.Model): class Banner(models.Model):
PAGE_INDEX = 1
PAGE_COURSES = 2
text = models.TextField() text = models.TextField()
button_text = models.CharField(max_length=50) button_text = models.CharField(max_length=50)
url = models.URLField() url = models.URLField()
image = models.ImageField() image = models.ImageField()
use = models.BooleanField(default=False) use = models.BooleanField(default=False)
color = models.CharField(max_length=7, blank=True, default='') color = models.CharField(max_length=7, blank=True, default='')
color2 = models.CharField(max_length=7, blank=True, default='')
stretch_image = models.BooleanField(default=True) stretch_image = models.BooleanField(default=True)
future_date = models.DateTimeField(blank=True, null=True) future_date = models.DateTimeField(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)
pages = ArrayField(models.IntegerField(), default=[], blank=True)
main_banner = ArrayField(models.IntegerField(), default=[], blank=True)
class Meta: class Meta:
verbose_name = 'Банер' verbose_name = 'Банер'
verbose_name_plural = 'Банеры' verbose_name_plural = 'Банеры'
ordering = ('-created_at',) ordering = ('-created_at',)
def save(self, *args, **kwargs):
if self.use:
Banner.objects.filter(use=True).update(use=False)
return super().save(*args, **kwargs)
class Contest(models.Model): class Contest(models.Model):
title = models.CharField(max_length=255) title = models.CharField(max_length=255)

@ -4,6 +4,7 @@
{% block ogimage %}http://{{request.META.HTTP_HOST}}{% static 'img/og_courses.jpg' %}{% endblock ogimage %} {% block ogimage %}http://{{request.META.HTTP_HOST}}{% static 'img/og_courses.jpg' %}{% endblock ogimage %}
{% block content %} {% block content %}
{% include "templates/blocks/banners.html" %}
<div class="main" style="background-image: url({% static 'img/bg-1.jpg' %});"> <div class="main" style="background-image: url({% static 'img/bg-1.jpg' %});">
<div class="main__center center"> <div class="main__center center">
<div class="main__title">Онлайн-курсы LilCity</div> <div class="main__title">Онлайн-курсы LilCity</div>

@ -15,6 +15,7 @@ from django.views.decorators.http import require_http_methods
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.utils.timezone import now from django.utils.timezone import now
from apps.content.models import Banner
from apps.payment.models import AuthorBalance, CoursePayment from apps.payment.models import AuthorBalance, CoursePayment
from .models import Course, Like, Lesson, CourseComment, LessonComment, Category from .models import Course, Like, Lesson, CourseComment, LessonComment, Category
from .filters import CourseFilter from .filters import CourseFilter
@ -318,6 +319,7 @@ class CoursesView(ListView):
context = super().get_context_data() context = super().get_context_data()
filtered = CourseFilter(self.request.GET) filtered = CourseFilter(self.request.GET)
context.update(filtered.data) context.update(filtered.data)
context['banners'] = Banner.objects.filter(use=True)
context['course_items'] = Course.shuffle(context.get('course_items')) context['course_items'] = Course.shuffle(context.get('course_items'))
context['ages'] = Course.AGE_CHOICES[1:] context['ages'] = Course.AGE_CHOICES[1:]
age = context.get('age') age = context.get('age')

@ -0,0 +1,38 @@
<swiper class="banners" :options="{effect: 'slide', speed: 700, loop: true, autoplay: {delay: 5000} }">
{% for banner in banners %}
<swiper-slide>
<div class="banner"
data-banner="{{banner.id}}" style="display: none;
background: {{ banner.color|default:'white' }};
{% if banner.color2 %}
background: -moz-linear-gradient(top, {{ banner.color }} 0%, {{ banner.color2 }} 100%);
background: -webkit-gradient(left top, left bottom, color-stop(0%, {{ banner.color }}), color-stop(100%, {{ banner.color2 }}));
background: -webkit-linear-gradient(top, {{ banner.color }} 0%, {{ banner.color2 }} 100%);
background: -o-linear-gradient(top, {{ banner.color }} 0%, {{ banner.color2 }} 100%);
background: -ms-linear-gradient(top, {{ banner.color }} 0%, {{ banner.color2 }} 100%);
background: linear-gradient(to bottom, {{ banner.color }} 0%, {{ banner.color2 }} 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='{{ banner.color }}', endColorstr='{{ banner.color2 }}', GradientType=0 );
{% endif %}">
<div class="banner__content">
<div class="banner__text-column">
<div class="banner__text">{{ banner.text }}</div>
{% if banner.url %}
<a href="{{ banner.url }}" class="banner__link">{{ banner.button_text }}</a>
{% endif %}
</div>
<div class="banner__image-column">
<img src="{{ banner.image.url }}"/>
{% if banner.future_date %}
<div class="banner__countdown-wrap">
<div class="banner__countdown-title">До конца акции осталось</div>
<countdown date="{{ banner.future_date|date:'Y-m-d H:i:s' }}"></countdown>
</div>
{% endif %}
</div>
</div>
</div>
</swiper-slide>
{% endfor %}
<div class="swiper-pagination" slot="pagination"></div>
</swiper>

@ -32,7 +32,6 @@
{% block layer_body %} {% block layer_body %}
{% include "templates/blocks/social.html" %} {% include "templates/blocks/social.html" %}
{% include "templates/blocks/banner.html" %}
<div class="outer js-outer"> <div class="outer js-outer">
{% include "templates/blocks/header.html" %} {% include "templates/blocks/header.html" %}
<div id="lilcity-vue-app" class="container"> <div id="lilcity-vue-app" class="container">

@ -11,6 +11,7 @@ from paymentwall.pingback import Pingback
from apps.course.models import Course from apps.course.models import Course
from apps.school.models import SchoolSchedule from apps.school.models import SchoolSchedule
from apps.payment.models import SchoolPayment, UserGiftCertificate, Payment, DrawingCampPayment from apps.payment.models import SchoolPayment, UserGiftCertificate, Payment, DrawingCampPayment
from apps.content.models import Banner
User = get_user_model() User = get_user_model()
@ -20,7 +21,7 @@ class AboutView(TemplateView):
class IndexView(TemplateView): class IndexView(TemplateView):
template_name = 'templates/lilcity/main.html' template_name = 'templates/lilcity/home.html'
def get_context_data(self): def get_context_data(self):
referrer = self.request.GET.get('referrer') referrer = self.request.GET.get('referrer')
@ -98,7 +99,10 @@ class IndexView(TemplateView):
review_images = list(map(str, range(1, 107))) review_images = list(map(str, range(1, 107)))
shuffle(review_images) shuffle(review_images)
banners = Banner.objects.filter(use=True)
context.update({ context.update({
'banners': banners,
'is_drawing_camp': True, 'is_drawing_camp': True,
'review_images': review_images, 'review_images': review_images,
'gift_certificate': user_gift_certificate.gift_certificate if user_gift_certificate else None, 'gift_certificate': user_gift_certificate.gift_certificate if user_gift_certificate else None,

@ -61,6 +61,7 @@
"validator": "^9.2.0", "validator": "^9.2.0",
"vue": "^2.5.13", "vue": "^2.5.13",
"vue-autosize": "^1.0.2", "vue-autosize": "^1.0.2",
"vue-awesome-swiper": "^3.1.3",
"vuedraggable": "^2.16.0", "vuedraggable": "^2.16.0",
"vuejs-datepicker": "^0.9.25", "vuejs-datepicker": "^0.9.25",
"vuelidate": "^0.6.1" "vuelidate": "^0.6.1"

@ -3,6 +3,7 @@
*/ */
import 'ilyabirman-likely/release/likely.js'; import 'ilyabirman-likely/release/likely.js';
import 'ilyabirman-likely/release/likely.css'; import 'ilyabirman-likely/release/likely.css';
import 'swiper/dist/css/swiper.css';
import "./modules/common"; import "./modules/common";
import "./modules/header"; import "./modules/header";
import "./modules/search"; import "./modules/search";
@ -27,6 +28,7 @@ import Comments from '../components/Comments';
import Likes from '../components/blocks/Likes.vue'; import Likes from '../components/blocks/Likes.vue';
import FAQ from '../components/FAQ.vue'; import FAQ from '../components/FAQ.vue';
import Countdown from '../components/blocks/Countdown.vue'; import Countdown from '../components/blocks/Countdown.vue';
import { swiper, swiperSlide } from 'vue-awesome-swiper';
Vue.use(Vuelidate); Vue.use(Vuelidate);
Vue.use(VueAutosize); Vue.use(VueAutosize);
@ -41,6 +43,9 @@ const components = {
'comments': Comments, 'comments': Comments,
'faq': FAQ, 'faq': FAQ,
'vue-datepicker': DatePicker, 'vue-datepicker': DatePicker,
'countdown': Countdown,
swiper,
swiperSlide,
}; };
Object.assign(components, window.LIL_STORE.components); Object.assign(components, window.LIL_STORE.components);
@ -54,13 +59,3 @@ const app = new Vue({
}, },
components: components components: components
}); });
const bannerApp = new Vue({
el: '.banner',
data() {
return {
store: window.LIL_STORE,
}
},
components: {'countdown': Countdown,}
});

@ -24,11 +24,11 @@ $(document).ready(function () {
}); });
// Инициируем начальное состояние шапки // Инициируем начальное состояние шапки
updateHeader(); /* updateHeader();
$(window).on('scroll', function () { $(window).on('scroll', function () {
updateHeader(); updateHeader();
}); }); */
//===========BANNERS=============== //===========BANNERS===============
const $banner = $('[data-banner]'); const $banner = $('[data-banner]');

@ -334,7 +334,7 @@ a.btn
width: 100% width: 100%
.header .header
position: fixed position: absolute
left: 0 left: 0
right: 0 right: 0
z-index: 100 z-index: 100
@ -664,7 +664,6 @@ a.btn
display: flex display: flex
position: relative position: relative
min-height: 500px min-height: 500px
margin-top: -100px
padding: 120px 0 50px padding: 120px 0 50px
background-position: 50% 50% background-position: 50% 50%
background-repeat: no-repeat background-repeat: no-repeat
@ -4379,142 +4378,70 @@ a
width: 640px; width: 640px;
height: 360px; height: 360px;
.banners
margin-top: -100px
.banner .banner
height: 140px padding-top: 100px
text-align: center text-align: center
color: #fff color: #fff
position: relative position: relative
+m
height: auto
&__bg
background-repeat: no-repeat
position: absolute
width: 100%
height: 100%
left: 0
top: 0
&_countdown
+m
height: 140px
&__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
+m
width: 100%
display: block
margin: 0 auto
&_colored &__image
+m
max-width: 100%
width: auto
opactiy: 0.8
&__content &__content
position: absolute
width: 100%
margin-top: 50px
+m
margin-top: 0px
top: 0
&_countdown &__content
margin-top: 15px
+m
margin-top: 5px
&__content-center
width: 1024px width: 1024px
margin: 0 auto padding: 70px 20px 0
display: flex display: flex
padding: 0 40px margin: 0 auto
height: 240px
+t +t
width: 100% width: 100%
+m +m
width: 100% width: 100%
padding: 0 10px
&_countdown &__content-center
+m
display: block
&__text &__text
font-size: 30px font-size: 30px
text-shadow: 0px 0px 3px rgba(0, 0, 0, 1)
+m
font-size: 16px
&_countdown &__text
font-size: 22px
text-shadow: none text-shadow: none
color: black color: black
width: 300px
+m +m
font-size: 16px font-size: 16px
width: auto width: auto
font-weight: bold font-weight: bold
&__link &__link
display: block
color: #fff
font-size: 20px
text-shadow: 0px 0px 3px rgba(0, 0, 0, 1)
margin-top: 20px
+m
margin-top: 0px
font-size: 16px
&_countdown &__link
font-size: 15px font-size: 15px
color: black color: black
text-shadow: none text-shadow: none
background: white background: white
font-weight: bold padding: 12px 22px
padding: 7px 20px border-radius: 25px
border-radius: 20px
border: 1px solid #ddd border: 1px solid #ddd
text-align: center text-align: center
margin-top: 10px margin-top: 50px
display: inline-block display: inline-block
text-transform: uppercase
font-family: 'ProximaNova-Bold'
box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.05), 0 9px 24px 0 rgba(33, 74, 211, 0.1)
+m +m
margin-top: 25px margin-top: 25px
&_countdown &__link:hover &__link:hover
background: #ddd background: #ddd
&__hide &__image-column
position: absolute flex: 50%
right: 5px text-align: center
top: 5px position: relative
display: block & img
color: #fff position: absolute
text-shadow: 0px 0px 3px rgba(0, 0, 0, 1) bottom: 0
text-transform: uppercase transform: translateX(-50%)
border-bottom: 1px dotted #fff left: 50%
opacity: 0.3
+m
font-size: 11px
&__text-column &__text-column
flex: 1 flex: 50%
&_countdown &__text-column
text-align: left text-align: left
+m
text-align: center
&__countdown-column
padding: 0 20px
+m
padding: 0
display: flex
& > div:nth-child(1)
+m
padding: 0 10px
border-radius: 3px
background: rgba(255, 255, 255, 0.3)
margin-right: 10px
& > div:nth-child(2)
+m
flex: 1
&__countdown-title &__countdown-title
color: black color: black
font-size: 15px font-size: 15px
margin-bottom: 5px margin-bottom: 5px
+m +m
font-size: 15px font-size: 15px
&__countdown-wrap
display: inline-block
&__countdown &__countdown
display: flex display: flex
color: black color: black

Loading…
Cancel
Save