remotes/origin/editis_13-01-19
gzbender 7 years ago
parent 4ccf8fe558
commit e87d5efe37
  1. 2
      apps/user/templates/user/edit-gallery.html
  2. 10
      apps/user/templates/user/profile.html
  3. 162
      web/src/components/CourseRedactor.vue
  4. 2
      web/src/components/blocks/BlockImages.vue
  5. 2
      web/src/js/app.js
  6. 29
      web/src/sass/_common.sass

@ -13,7 +13,7 @@
{% block pre_app_js %} {% block pre_app_js %}
<script> <script>
window.LIL_STORE._user_gallery_images = [{% for img in user.gallery.gallery_images.all %}{ window.LIL_STORE._user_gallery_images = [{% for img in user.gallery.gallery_images.reverse %}{
id: {{ img.id }}, id: {{ img.id }},
image_thumbnail_url: '{{ img.img.image_thumbnail.url }}', image_thumbnail_url: '{{ img.img.image_thumbnail.url }}',
image_id: {{ img.img.id }}, image_id: {{ img.img.id }},

@ -67,13 +67,13 @@
<div class="section__center center"> <div class="section__center center">
<div class="tabs js-tabs"> <div class="tabs js-tabs">
<div class="tabs__nav"> <div class="tabs__nav">
<button class="tabs__btn js-tabs-btn active" data-anchor="purchases">МОИ ПОКУПКИ</button> <a href="#purchases" class="tabs__btn js-tabs-btn active">МОИ ПОКУПКИ</a>
{% if is_author %} {% if is_author %}
<button class="tabs__btn js-tabs-btn" data-anchor="courses">ОПУБЛИКОВАННЫЕ <a href="#courses" class="tabs__btn js-tabs-btn">ОПУБЛИКОВАННЫЕ
<span class="mobile-hide">КУРСЫ</span> <span class="mobile-hide">КУРСЫ</span>
</button> </a>
{% endif %} {% endif %}
<button class="tabs__btn js-tabs-btn" data-anchor="works">МОИ РАБОТЫ</button> <a href="#works" class="tabs__btn js-tabs-btn">МОИ РАБОТЫ</a>
</div> </div>
<div class="tabs__container"> <div class="tabs__container">
<div class="tabs__item js-tabs-item" style="display: block;"> <div class="tabs__item js-tabs-item" style="display: block;">
@ -146,7 +146,7 @@
</div> </div>
<div class="examples gallery"> <div class="examples gallery">
{% for image in user.gallery.gallery_images.all %} {% for image in user.gallery.gallery_images.reverse %}
<div class="examples__item"> <div class="examples__item">
<a href="{{ image.img.image.url }}"> <a href="{{ image.img.image.url }}">
{% thumbnail image.img.image "165x165" crop="center" as im %} {% thumbnail image.img.image "165x165" crop="center" as im %}

@ -3,63 +3,38 @@
<div v-if="!courseLoading && !mounting"> <div v-if="!courseLoading && !mounting">
<form v-if="viewSection !== 'lessons-edit'" @submit.prevent="onSubmit"> <form v-if="viewSection !== 'lessons-edit'" @submit.prevent="onSubmit">
<div class="info"> <div class="info">
<div class="info__section" :style="coverBackgroundStyle"> <div class="info__section">
<div class="info__main"> <div class="courses__item">
<div class="info__head"> <div class="courses__preview">
<div class="info__user"> <img class="courses__pic" :src="course.coverImage || defaultCover" width="300px" />
<div class="info__ava ava"> <div class="upload" v-if="! course.coverImage">
<img :src="authorPicture" alt="Аватар" class="ava__pic"> <div class="upload__title">Загрузить превью</div>
</div>
<div v-if="me" class="info__group info__field--light">
<div class="info__label">АВТОР</div>
<div class="info__value">{{ authorName }}</div>
</div>
</div>
<div class="info__upload upload">
Загрузить фон
<input type="file" class="upload__file" @change="onCoverImageSelected"> <input type="file" class="upload__file" @change="onCoverImageSelected">
</div> </div>
<a href="#" title="Удалить превью" class="course-delete-cover" v-if="course.coverImage" @click="removeCover">
<svg class="icon icon-delete">
<use xlink:href="/static/img/sprite.svg#icon-delete"></use>
</svg>
</a>
</div> </div>
<div class="info__title"> <div class="courses__details">
<div class="info__field field field_info" <div class="courses__theme theme field info__field--light" v-if="!live" v-bind:class="{ error: (!$v.live && $v.course.category.$dirty || showErrors) && $v.course.category.$invalid }">
v-bind:class="{ error: ($v.course.title.$dirty || showErrors) && $v.course.title.$invalid }"> <lil-select :value.sync="course.category" :options="categoryOptions"
<div class="field__label">{{titles.courseTitle}}</div>
<div class="field__wrap">
<textarea class="field__textarea"
rows="1"
:title="titles.courseTitle"
v-autosize="course.title"
@change="onCourseNameInput"
v-model="course.title"></textarea>
</div>
</div>
<div class="info__field field field_info field_short_description"
v-bind:class="{ error: ($v.course.short_description.$dirty || showErrors) && $v.course.short_description.$invalid }">
<div class="field__label">{{titles.shortDescription}}</div>
<div class="field__wrap">
<vue-redactor :value="course.short_description"
v-on:update:value="(value) => { this.course.short_description = value; }" />
</div>
</div>
</div>
<div class="info__foot" v-if="!live">
<div class="info__field field field_info info__field--light"
v-bind:class="{ error: ($v.course.category.$dirty || showErrors) && $v.course.category.$invalid }">
<div class="field__label field__label_gray">КАТЕГОРИЯ</div>
<div class="field__wrap">
<lil-select :value.sync="course.category" :options="categoryOptions"
placeholder="Выберите категорию"/> placeholder="Выберите категорию"/>
</div>
</div>
<div class="info__field field field_info"
v-bind:class="{ error: ($v.course.duration.$dirty || showErrors) && $v.course.duration.$invalid }">
<div class="field__label field__label_gray">ПРОДОЛЖИТЕЛЬНОСТЬ</div>
<div class="field__wrap field__wrap__appended">
<input type="text" class="field__input field__input__appended" v-model.number="course.duration"
@input="$v.course.duration.$touch()">
<button disabled class="field__append">{{pluralize(course.duration, ['день', 'дня', 'дней'])}}</button>
</div>
</div> </div>
<div class="courses__price" v-if="course.is_paid && course.price">{{ course.price }}</div>
</div>
<div class="courses__title field field" v-bind:class="{ error: ($v.course.title.$dirty || showErrors) && $v.course.title.$invalid }">
<textarea class="field__textarea"
rows="1"
:title="titles.courseTitle"
v-autosize="course.title"
@change="onCourseNameInput"
v-model="course.title"
placeholder="Добавить заголовок"></textarea>
</div>
<div class="courses__content field" v-bind:class="{ error: ($v.course.short_description.$dirty || showErrors) && $v.course.short_description.$invalid }">
<vue-redactor :value.sync="course.short_description" placeholder="Добавить краткое описание"/>
</div> </div>
</div> </div>
</div> </div>
@ -90,6 +65,16 @@
</div> </div>
</div> --> </div> -->
<div class="info__field field field_info" v-if="!live"
v-bind:class="{ error: ($v.course.duration.$dirty || showErrors) && $v.course.duration.$invalid }">
<div class="field__label field__label_gray">ПРОДОЛЖИТЕЛЬНОСТЬ</div>
<div class="field__wrap field__wrap__appended">
<input type="text" class="field__input field__input__appended" v-model.number="course.duration"
@input="$v.course.duration.$touch()">
<button disabled class="field__append">{{pluralize(course.duration, ['день', 'дня', 'дней'])}}</button>
</div>
</div>
<div v-if="!live" class="info__field field"> <div v-if="!live" class="info__field field">
<div class="field__label field__label_gray">ДОСТУП</div> <div class="field__label field__label_gray">ДОСТУП</div>
<div class="field__wrap"> <div class="field__wrap">
@ -267,6 +252,7 @@
users: null, users: null,
ROLE_ADMIN: ROLE_ADMIN, ROLE_ADMIN: ROLE_ADMIN,
slugChanged: false, slugChanged: false,
defaultCover: '/img/no_cover.png',
course: { course: {
title: '', title: '',
status: null, status: null,
@ -444,6 +430,16 @@
} }
}, },
methods: { methods: {
removeCover() {
if(! this.course.coverImageId){
return;
}
api.removeImage(this.course.coverImageId, this.accessToken)
.then(response => {
this.course.coverImageId = null;
this.course.coverImage = null;
});
},
onCoverImageSelected(event) { onCoverImageSelected(event) {
let file = event.target.files[0]; let file = event.target.files[0];
let reader = new FileReader(); let reader = new FileReader();
@ -1005,9 +1001,6 @@
// this.updateViewSection(window.location); // this.updateViewSection(window.location);
}, },
computed: { computed: {
coverBackgroundStyle() {
return this.course.coverImage ? `background-image: url(${this.course.coverImage});` : '';
},
displayPrice: { displayPrice: {
get: function () { get: function () {
return this.course.is_paid ? (this.course.price || '') : ''; return this.course.is_paid ? (this.course.price || '') : '';
@ -1175,10 +1168,67 @@
overflow: scroll; overflow: scroll;
} }
.field_short_description .redactor-box { .courses__item {
flex: 0 0 300px;
}
.courses__item .field {
margin-bottom: 0;
}
.courses__content .redactor-box {
overflow-x: visible; overflow-x: visible;
overflow-y: auto; overflow-y: auto;
max-height: 200px; 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;
}
.select__head {
font-size: inherit;
line-height: inherit;
height: auto;
} }
</style> </style>

@ -12,7 +12,7 @@
<div class="kit__gallery"> <div class="kit__gallery">
<div class="kit__preview" v-for="(image, index) in images" v-bind:class="{ 'kit__preview--loading': image.loading }"> <div class="kit__preview" v-for="(image, index) in images" v-bind:class="{ 'kit__preview--loading': image.loading }">
<img :src="image.image_thumbnail_url" class="kit__pic"> <img :src="image.image_thumbnail_url" class="kit__pic">
<button type="button" @click="onRemoveImage(index)"> <button class="kit__delete-photo" type="button" @click="onRemoveImage(index)">
<svg class="icon icon-delete"> <svg class="icon icon-delete">
<use xlink:href="/static/img/sprite.svg#icon-delete"></use> <use xlink:href="/static/img/sprite.svg#icon-delete"></use>
</svg> </svg>

@ -61,7 +61,7 @@ const app = new Vue({
if(this.urlIs('userProfile')){ if(this.urlIs('userProfile')){
if(window.location.hash){ if(window.location.hash){
$(document).ready(() => { $(document).ready(() => {
$(`[data-anchor=${window.location.hash.slice(1)}]`).click(); $(`[href="${window.location.hash}"]`).click();
}); });
} }
} }

@ -2183,11 +2183,13 @@ a.grey-link
color: $pink color: $pink
border-bottom: 1px $pink solid border-bottom: 1px $pink solid
.error.field .redactor-box
border-bottom: 1px $pink solid
.info__field--light .info__field--light
.select .select
.select__head .select__head
color: #525252 color: #525252
font-size: 15px
&:after &:after
border-color: #525252 transparent transparent transparent border-color: #525252 transparent transparent transparent
&.selected &.selected
@ -3278,6 +3280,7 @@ a.grey-link
justify-content: center justify-content: center
&__btn &__btn
height: 56px height: 56px
line-height: 56px
border-bottom: 1px solid $border border-bottom: 1px solid $border
+fb +fb
font-size: 12px font-size: 12px
@ -3488,22 +3491,10 @@ a.grey-link
&__section &__section
display: flex display: flex
position: relative position: relative
background-position: 50% 50% flex: 0 0 50%
background-size: cover
flex: 0 0 calc(50% + 169px)
justify-content: flex-end justify-content: flex-end
z-index: 4
&:before
content: ''
position: absolute
top: 0
left: 0
width: 100%
height: 100%
background-image: linear-gradient(135deg, rgba(255, 226, 235, 0.75) 0%, rgba(216, 245, 246, 0.75) 100%)
z-index: -2
&__sidebar &__sidebar
flex: 0 0 calc(50% - 169px) flex: 0 0 50%
&__main &__main
display: flex display: flex
max-width: 675px max-width: 675px
@ -3675,6 +3666,10 @@ a.grey-link
flex: 0 0 140px flex: 0 0 140px
+m +m
flex: 0 0 110px flex: 0 0 110px
&__delete-photo
position: absolute
bottom: 2px
left: 3px
&__photo &__photo
display: flex display: flex
position: relative position: relative
@ -3720,6 +3715,7 @@ a.grey-link
flex-wrap: wrap flex-wrap: wrap
&__gallery &__photo, &__gallery &__photo,
&__preview &__preview
position: relative
margin: 0 10px 20px margin: 0 10px 20px
flex: 0 0 calc(25% - 20px) flex: 0 0 calc(25% - 20px)
&--loading &--loading
@ -3728,6 +3724,9 @@ a.grey-link
display: block display: block
width: 100% width: 100%
object-fit: contain object-fit: contain
transform: translateY(-50%)
top: 50%
position: relative
&__theme &__theme
margin-bottom: 30px margin-bottom: 30px
padding-bottom: 5px padding-bottom: 5px

Loading…
Cancel
Save