remotes/origin/hotfix/LIL-661
gzbender 8 years ago
parent 0ad60238a9
commit 876cefab66
  1. 21
      apps/content/templates/content/contest.html
  2. 8
      apps/content/views.py
  3. 2
      project/templates/blocks/lil_store_js.html
  4. 2
      project/templates/blocks/popup_auth.html
  5. 3
      project/urls.py
  6. 183
      web/src/components/UploadContestWork.vue
  7. 0
      web/src/components/blocks/ContestWork.vue
  8. 4
      web/src/components/blocks/Image.vue
  9. 23
      web/src/js/app.js
  10. 5
      web/webpack.config.js

@ -2,19 +2,21 @@
{% block content %}
<div class="main main_default">
<upload-contest-work contest-id="{{ contest.id }}"></upload-contest-work>
<div class="main main_default" {% if contest.cover %}style="background-image: url({{ contest.cover.image.url }});"{% endif %}>
<div class="main__center center">
<div class="main__title">
<span class="main__bold">Lil School</span> — первая образовательная онлайн-платформа креативного мышления для детей
{{ contest.title }}
</div>
<div class="main__subtitle">
Приглашаем вас на месяц открытых дверей в Lil School
{{ contest.description }}
</div>
<div class="main__actions">
<a class="main__btn btn btn_white" href="#">Загрузить свою работу</a>
<a class="main__btn btn btn_white" href="#" data-show-upload-contest-work>Загрузить свою работу</a>
</div>
</div>
</div>
<div style="text-align: center;">
{% for content in contest.content.all %}
{% with template="content/blocks/"|add:content.ctype|add:".html" %}
@ -25,20 +27,21 @@
<div class="section">
<div class="section__center center">
<a id="gallery" name="gallery">
<div class="title title_center">Галерея</div>
<div class="title title_center">Галлерея</div>
</a>
<div class="text">
<p>Тысячи шедевров уже созданы благодаря Lil School. Более 10000 работ можно
<a target="_blank" href='{{ config.SERVICE_INSTAGRAM_URL }}'>увидеть</a> в Инстаграм</p>
<img class="text__curve text__curve_three" src="{% static 'img/curve-3.svg' %}">
</div>
<div class="gallery">
<div class="gallery__grid">
{% for contest_work in contest_works %}
{% include '' %}
{% include 'content/blocks/contest_work.html' %}
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endblock content %}
{% block foot %}
{% endblock foot %}

@ -1,7 +1,7 @@
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView
from django.views.generic import TemplateView, DetailView
from apps.content.models import Contest
@ -22,3 +22,9 @@ class ContestEditView(TemplateView):
context = super().get_context_data()
context['object'] = self.object
return context
class ContestView(DetailView):
model = Contest
context_object_name = 'contest'
template_name = 'content/contest.html'

@ -1,5 +1,7 @@
{% load static %}
<script>
window.LIL_STORE = {
staticUrl: '{% static "" %}',
accessToken: '{{ request.user.auth_token }}',
user: {
id: '{{ request.user.id }}',

@ -3,7 +3,7 @@
<div class="popup__wrap js-popup-wrap">
<button class="popup__close js-popup-close">
<svg class="icon icon-close">
<use xlink:href={% static "img/sprite.svg" %}#icon-close></use>
<use xlink:href="{% static 'img/sprite.svg' %}#icon-close"></use>
</svg>
</button>
<div class="popup__body">

@ -18,7 +18,7 @@ from django.contrib import admin
from django.views.generic import TemplateView
from django.urls import path, include
from apps.content.views import ContestEditView
from apps.content.views import ContestEditView, ContestView
from apps.course.views import (
CoursesView, likes, coursecomment,
CourseView, LessonView, SearchView,
@ -85,6 +85,7 @@ urlpatterns = [
path('test', TemplateView.as_view(template_name='templates/lilcity/test.html'), name='test'),
path('contest/create', ContestEditView.as_view(), name='contest_create'),
path('contest/<int:pk>/edit', ContestEditView.as_view(), name='contest_edit'),
path('contest/<int:pk>/', ContestView.as_view(), name='contest'),
]

@ -0,0 +1,183 @@
<template>
<div ref="popup" class="upload-contest-work popup">
<div class="popup__wrap popup__wrap_md">
<button class="popup__close" @click.prevent="hide">
<svg class="icon icon-close">
<use v-bind="{'xlink:href': $root.store.staticUrl + 'img/sprite.svg' + '#icon-close' }"></use>
</svg>
</button>
<div class="popup__body">
<form class="form">
<div class="title">
Чтобы принять участие<br>в конкурсе, заполните поля<br>и прикрепите изображение
</div>
<div class="field"
v-bind:class="{ error: $v.contestWork.child_full_name.$dirty && $v.contestWork.child_full_name.$invalid }">
<div class="field__label">ИМЯ И ФАМИЛИЯ РЕБЕНКА</div>
<div class="field__wrap">
<input class="field__input" type="text" v-model="contestWork.child_full_name">
</div>
<div class="field__error"></div>
</div>
<div class="field"
v-bind:class="{ error: $v.contestWork.age.$dirty && $v.contestWork.age.$invalid }">
<div class="field__label">ВОЗРАСТ</div>
<div class="field__wrap">
<input class="field__input" type="number" v-model="contestWork.age" style="width: 100px;">
</div>
<div class="field__error"></div>
</div>
<div class="field">
<lil-image :image-id.sync="contestWork.imageId" :image-url.sync="contestWork.imageUrl"
v-on:update:imageId="onUpdateImageId" :access-token="$root.store.accessToken" />
</div>
<div class="field" style="text-align: center;">
<button class="btn btn_light" tabindex="3" @click="save">Отправить на конкурс</button>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
import {api} from "../js/modules/api";
import LilImage from './blocks/Image';
import {showNotification} from "../js/modules/notification";
import {required, minValue, numeric, url } from 'vuelidate/lib/validators';
import $ from 'jquery';
export default {
name: 'upload-contest-work',
props: ['contestId'],
data() {
return {
fields: {
image: "Изображение",
child_full_name: "Имя и фамилия ребенка",
age: 'Возраст',
},
contestWork: {
contest: this.contestId,
image: null,
imageId: null,
imageUrl: '',
child_full_name: '',
age: '',
}
}
},
validations() {
return {
contestWork: {
image: {
required
},
child_full_name: {
required
},
age: {
required, numeric
},
},
};
},
mounted() {
$('[data-show-upload-contest-work]').click(() => {
this.clear();
this.show();
});
},
methods: {
clear() {
Object.assign(this.$data, this.$options.data.apply(this))
},
onUpdateImageId(imageId) {
this.contestWork.image = imageId;
},
show() {
const $popup = $(this.$refs.popup)
$('body').addClass('no-scroll');
$popup.addClass('visible');
setTimeout(() => {
$popup.addClass('open');
}, 300);
},
hide() {
const $popup = $(this.$refs.popup)
$('body').removeClass('no-scroll');
$popup.removeClass('visible');
setTimeout(() => {
$popup.removeClass('open');
}, 300);
},
validate() {
if (this.$v.contestWork.$invalid) {
for(let i in this.$v.contestWork) {
if(this.$v.contestWork[i].$invalid) {
showNotification("error", "Ошибка валидации поля " + this.fields[i]);
}
}
return false;
}
return true;
},
save() {
if(! this.validate()) {
return;
}
let data = this.contestWork;
data.contest = this.contestId;
data.user = this.$root.store.user.id;
const request = api.post(`/api/v1/contest_works/`, data, {
headers: {
'Authorization': `Token ${this.$root.store.accessToken}`,
}
});
request.then((response) => {
if(response.data.id){
this.$emit('add:contestWork', response.data);
this.hide();
}
});
}
},
components: {
'lil-image': LilImage,
}
}
</script>
<style lang="scss">
.upload-contest-work {
.popup__wrap {
padding: 35px 35px 0;
}
.title {
text-align: center; font-size: 24px;
}
.kit__photo {
height: 400px;
}
.kit__photo.has-image {
border: none;
}
.kit__photo-image {
max-height: 400px;
height: auto;
width: auto;
}
.kit__file {
bottom: 0;
}
}
</style>

@ -1,5 +1,5 @@
<template>
<div class="kit__photo">
<div class="kit__photo" :class="{ 'has-image': !! imageUrl }">
<svg class="icon icon-add-plus" v-if="!imageUrl">
<use xlink:href="/static/img/sprite.svg#icon-add-plus"></use>
</svg>
@ -51,4 +51,4 @@
display: block;
object-fit: contain;
}
</style>
</style>

@ -17,3 +17,26 @@ import "./modules/notification";
import "./modules/mixpanel";
import "../sass/app.sass";
import Vue from 'vue';
import Vuelidate from 'vuelidate';
import UploadContestWork from '../components/UploadContestWork.vue';
Vue.use(Vuelidate);
if (process.env.NODE_ENV === 'development') {
// Enable vue-devtools
Vue.config.devtools = true;
}
const app = new Vue({
el: '#lilcity-vue-app',
data() {
return {
store: window.LIL_STORE,
}
},
components: {
'upload-contest-work': UploadContestWork,
}
});

@ -9,6 +9,7 @@ module.exports = {
entry: {
app: "./src/js/app.js",
courseRedactor: "./src/js/course-redactor.js",
contestRedactor: "./src/js/contest-redactor.js",
mixpanel: "./src/js/third_party/mixpanel-2-latest.js",
sprite: glob('./src/icons/*.svg'),
images: glob('./src/img/*'),
@ -116,6 +117,10 @@ module.exports = {
},
watch: NODE_ENV === 'development',
watchOptions: {
ignored: 'node_modules',
poll: 2000,
},
devtool: NODE_ENV === 'development' ? 'source-map' : false
};

Loading…
Cancel
Save