Merge branch 'master' of https://gitlab.com/lilcity/backend into feature/lil-583

remotes/origin/hotfix/LIL-691
gzbender 7 years ago
commit 0cc3d0781e
  1. 14
      apps/course/migrations/0045_merge_20180926_0200.py
  2. 4
      apps/course/templates/course/_items.html
  3. 4
      apps/course/templates/course/course.html
  4. 2
      apps/course/templates/course/course_only_lessons.html
  5. 2
      apps/course/templates/course/lesson.html
  6. 3
      apps/user/forms.py
  7. 18
      apps/user/migrations/0024_user_slug.py
  8. 9
      apps/user/models.py
  9. 4
      apps/user/templates/blocks/profile-menu.html
  10. 4
      apps/user/templates/user/payment-history.html
  11. 36
      apps/user/templates/user/profile-settings.html
  12. 1
      apps/user/views.py
  13. 5
      project/templates/blocks/lil_store_js.html
  14. 2
      project/templates/blocks/teachers.html
  15. 6
      project/templates/blocks/user_menu.html
  16. 1
      project/urls.py
  17. 12
      web/src/js/app.js
  18. 58
      web/src/js/modules/profile.js
  19. 4
      web/src/sass/_common.sass

@ -0,0 +1,14 @@
# Generated by Django 2.0.6 on 2018-09-26 02:00
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('course', '0044_course_age'),
('course', '0044_livelessoncomment'),
]
operations = [
]

@ -57,7 +57,7 @@
<div class="courses__content">{{ course.short_description | safe | linebreaks | truncatechars_html:300 }} <div class="courses__content">{{ course.short_description | safe | linebreaks | truncatechars_html:300 }}
</div> </div>
<div class="courses__user user"> <div class="courses__user user">
<a href="{% if course.author %}{% url 'user' course.author.id %}{% endif %}"> <a href="{% if course.author %}{{ course.author.url }}{% endif %}">
{% if course.author.photo %} {% if course.author.photo %}
<div class="user__ava ava"> <div class="user__ava ava">
<img class="ava__pic" src="{{ course.author.photo.url }}"/> <img class="ava__pic" src="{{ course.author.photo.url }}"/>
@ -69,7 +69,7 @@
{% endif %} {% endif %}
</a> </a>
<div class="user__info"> <div class="user__info">
<a href="{% if course.author %}{% url 'user' course.author.id %}{% endif %}" class="link--black"> <a href="{% if course.author %}{{ course.author.url }}{% endif %}" class="link--black">
<div class="user__name">{{ course.author.get_full_name }}</div> <div class="user__name">{{ course.author.get_full_name }}</div>
</a> </a>
<div class="user__meta"> <div class="user__meta">

@ -74,7 +74,7 @@
</div> </div>
<div class="course__title title">{{ course.title }}</div> <div class="course__title title">{{ course.title }}</div>
<div class="course__content">{{ course.short_description | safe | linebreaks }}</div> <div class="course__content">{{ course.short_description | safe | linebreaks }}</div>
<a href="{% url 'user' course.author.id %}"> <a href="{{ course.author.url }}">
<div class="course__user user"> <div class="course__user user">
{% if course.author.photo %} {% if course.author.photo %}
<div class="user__ava ava"> <div class="user__ava ava">
@ -274,7 +274,7 @@
</div> </div>
<div class="course__title title">{{ course.title }}</div> <div class="course__title title">{{ course.title }}</div>
<div class="course__content">{{ course.short_description | safe | linebreaks }}</div> <div class="course__content">{{ course.short_description | safe | linebreaks }}</div>
<a href="{% url 'user' course.author.id %}"> <a href="{{ course.author.url }}">
<div class="course__user user user_white"> <div class="course__user user user_white">
{% if course.author.photo %} {% if course.author.photo %}
<div class="user__ava ava"> <div class="user__ava ava">

@ -72,7 +72,7 @@
</div> </div>
<div class="course__title title">{{ course.title }}</div> <div class="course__title title">{{ course.title }}</div>
<div class="course__content">{{ course.short_description | safe | linebreaks }}</div> <div class="course__content">{{ course.short_description | safe | linebreaks }}</div>
<a href="{% url 'user' course.author.id %}"> <a href="{{ course.author.url }}">
<div class="course__user user"> <div class="course__user user">
{% if course.author.photo %} {% if course.author.photo %}
<div class="user__ava ava"> <div class="user__ava ava">

@ -34,7 +34,7 @@
<div> <div>
<div class="lesson__subtitle subtitle">{{ lesson.title }}</div> <div class="lesson__subtitle subtitle">{{ lesson.title }}</div>
<div class="lesson__content">{{ lesson.short_description | safe | linebreaks }}</div> <div class="lesson__content">{{ lesson.short_description | safe | linebreaks }}</div>
<a href="{% url 'user' lesson.author.id %}"> <a href="{{ lesson.author.url }}">
<div class="lesson__user user"> <div class="lesson__user user">
{% if lesson.author.photo %} {% if lesson.author.photo %}
<div class="user__ava ava"> <div class="user__ava ava">

@ -36,6 +36,7 @@ class UserEditForm(forms.ModelForm):
'first_name', 'first_name',
'last_name', 'last_name',
'email', 'email',
'slug',
'phone', 'phone',
'city', 'city',
'country', 'country',
@ -57,7 +58,7 @@ class UserEditForm(forms.ModelForm):
class WithdrawalForm(forms.Form): class WithdrawalForm(forms.Form):
amount = forms.DecimalField(required=True, min_value=2000) amount = forms.DecimalField(required=True, min_value=10000)
card = CreditCardField(required=True) card = CreditCardField(required=True)

@ -0,0 +1,18 @@
# Generated by Django 2.0.6 on 2018-09-26 13:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('user', '0023_user_trial_lesson'),
]
operations = [
migrations.AddField(
model_name='user',
name='slug',
field=models.SlugField(allow_unicode=True, blank=True, max_length=100, null=True, unique=True),
),
]

@ -11,6 +11,7 @@ from django.contrib.auth.models import AbstractUser, UserManager as BaseUserMana
from django.contrib.postgres import fields as pgfields from django.contrib.postgres import fields as pgfields
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.urls import reverse
from api.v1 import serializers from api.v1 import serializers
from apps.notification.utils import send_email from apps.notification.utils import send_email
@ -77,6 +78,10 @@ class User(AbstractUser):
photo = models.ImageField('Фото', null=True, blank=True, upload_to='users') photo = models.ImageField('Фото', null=True, blank=True, upload_to='users')
show_in_mainpage = models.BooleanField('Показывать на главной странице', default=False) show_in_mainpage = models.BooleanField('Показывать на главной странице', default=False)
trial_lesson = models.URLField(default='', null=True, blank=True) trial_lesson = models.URLField(default='', null=True, blank=True)
slug = models.SlugField(
allow_unicode=True, null=True, blank=True,
max_length=100, unique=True, db_index=True,
)
objects = UserManager() objects = UserManager()
@ -86,6 +91,10 @@ class User(AbstractUser):
class Meta(AbstractUser.Meta): class Meta(AbstractUser.Meta):
ordering = ('-date_joined',) ordering = ('-date_joined',)
@property
def url(self):
return reverse('user', args=[self.slug or self.id])
def serialized(self): def serialized(self):
user_data = serializers.user.UserSerializer(instance=self).data user_data = serializers.user.UserSerializer(instance=self).data
user_data = dumps(user_data, ensure_ascii=False) user_data = dumps(user_data, ensure_ascii=False)

@ -7,8 +7,8 @@
href="{% url 'user-edit-notifications' %}">Уведомления</a> href="{% url 'user-edit-notifications' %}">Уведомления</a>
<a class="menu__link {% if active == 'payments' %}active{% endif %}" <a class="menu__link {% if active == 'payments' %}active{% endif %}"
href="{% url 'user-edit-payments' %}">Платежи</a> href="{% url 'user-edit-payments' %}">Платежи</a>
<a class="menu__link {% if active == 'bonuses' %}active{% endif %}" <!--<a class="menu__link {% if active == 'bonuses' %}active{% endif %}"-->
href="{% url 'user-bonuses' %}">Бонусы</a> <!--href="{% url 'user-bonuses' %}">Бонусы</a>-->
</div> </div>
</div> </div>
</div> </div>

@ -33,9 +33,9 @@
<div class="form__field field{% if form.amount.errors %} error{% endif %}"> <div class="form__field field{% if form.amount.errors %} error{% endif %}">
<div class="field__label">СУММА</div> <div class="field__label">СУММА</div>
<div class="field__wrap"> <div class="field__wrap">
<input class="field__input" name="amount" required="" id="id_amount" type="number" min="2000" pattern="\d+(,\d{2})?" placeholder="{{ request.user.balance }}"> <input class="field__input" name="amount" required="" id="id_amount" type="number" min="10000" pattern="\d+(,\d{2})?" placeholder="{{ request.user.balance }}">
</div> </div>
<div class="field__error">Размер выводимой суммы не должно быть менее 2000 рублей.</div> <div class="field__error">Размер выводимой суммы не должен быть менее 10&nbsp;000 рублей.</div>
{% if form.amount.errors %} {% if form.amount.errors %}
<div class="field__error">{{ form.amount.errors }}</div> <div class="field__error">{{ form.amount.errors }}</div>
{% endif %} {% endif %}

@ -1,4 +1,8 @@
{% extends "templates/lilcity/index.html" %} {% load static %} {% load thumbnail %} {% block content %} {% extends "templates/lilcity/index.html" %}
{% load static %}
{% load settings %}
{% load thumbnail %}
{% block content %}
{% include "../blocks/profile-menu.html" with active="profile" %} {% include "../blocks/profile-menu.html" with active="profile" %}
{% if not user.is_email_proved %} {% if not user.is_email_proved %}
<div class="section section_confirm"> <div class="section section_confirm">
@ -36,7 +40,7 @@
{% empty %} {% empty %}
<img id="photo" class="ava__pic" src="{% static 'img/user_default.jpg' %}" width="120px" height="120px" /> <img id="photo" class="ava__pic" src="{% static 'img/user_default.jpg' %}" width="120px" height="120px" />
{% endthumbnail %} {% endthumbnail %}
<input name="photo" class="ava__input" type="file" accept='image/*' onchange='openFile(event)'> <input id="user-photo-upload" name="photo" class="ava__input" type="file" accept='image/*'>
<div class="ava__icon"> <div class="ava__icon">
<svg class="icon icon-photo"> <svg class="icon icon-photo">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-photo"></use> <use xlink:href="{% static 'img/sprite.svg' %}#icon-photo"></use>
@ -47,7 +51,7 @@
<div class="form__field field{% if form.first_name.errors %} error{% endif %}"> <div class="form__field field{% if form.first_name.errors %} error{% endif %}">
<div class="field__label">ИМЯ</div> <div class="field__label">ИМЯ</div>
<div class="field__wrap"> <div class="field__wrap">
<input name='first_name' class="field__input" type="text" placeholder="Имя" value="{{ user.first_name }}"> <input name='first_name' id="user-first-name" class="field__input" type="text" placeholder="Имя" value="{{ user.first_name }}">
</div> </div>
{% for error in form.first_name.errors %} {% for error in form.first_name.errors %}
<div class="field__error">{{ error }}</div> <div class="field__error">{{ error }}</div>
@ -56,7 +60,7 @@
<div class="form__field field{% if form.last_name.errors %} error{% endif %}"> <div class="form__field field{% if form.last_name.errors %} error{% endif %}">
<div class="field__label">ФАМИЛИЯ</div> <div class="field__label">ФАМИЛИЯ</div>
<div class="field__wrap"> <div class="field__wrap">
<input name='last_name' class="field__input" type="text" placeholder="Фамилия" value="{{ user.last_name }}"> <input name='last_name' id="user-last-name" class="field__input" type="text" placeholder="Фамилия" value="{{ user.last_name }}">
</div> </div>
{% for error in form.last_name.errors %} {% for error in form.last_name.errors %}
<div class="field__error">{{ error }}</div> <div class="field__error">{{ error }}</div>
@ -81,6 +85,17 @@
<div class="field__error">{{ error }}</div> <div class="field__error">{{ error }}</div>
{% endfor %} {% endfor %}
</div> </div>
<div class="form__field field{% if form.slug.errors %} error{% endif %}">
<div class="field__label">Ссылка</div>
<div class="field__wrap field__wrap__appended">
<div class="field__text">{% setting 'MAIN_HOST' %}/user/</div>
<input name='slug' id="user-slug" class="field__input field__input__appended" type="text"
value="{{ user.slug|default:'' }}" data-current-slug="{{ user.slug|default:'' }}">
</div>
{% for error in form.slug.errors %}
<div class="field__error">{{ error }}</div>
{% endfor %}
</div>
<div class="form__fieldset"> <div class="form__fieldset">
<div class="form__field field{% if form.city.errors %} error{% endif %}"> <div class="form__field field{% if form.city.errors %} error{% endif %}">
<div class="field__label">ГОРОД</div> <div class="field__label">ГОРОД</div>
@ -249,19 +264,6 @@
</div> </div>
</div> </div>
</div> </div>
<script>
var openFile = function(file) {
var input = file.target;
var reader = new FileReader();
reader.onload = function(){
var dataURL = reader.result;
var output = document.getElementById('photo');
output.src = dataURL;
};
reader.readAsDataURL(input.files[0]);
};
</script>
{% endblock content %} {% endblock content %}

@ -97,6 +97,7 @@ class ProfileView(TemplateView):
class UserView(DetailView): class UserView(DetailView):
model = User model = User
template_name = 'user/author_profile.html' template_name = 'user/author_profile.html'
query_pk_and_slug = True
def get_context_data(self, object): def get_context_data(self, object):
context = super().get_context_data() context = super().get_context_data()

@ -20,8 +20,9 @@
}, },
components: {}, components: {},
urls: { urls: {
courses: "{% url 'courses' %}" courses: "{% url 'courses' %}",
}, userProfileEdit: "{% url 'user-edit-profile' %}",
}
flags: { flags: {
referrer: '{{ referrer.id|default:'' }}', referrer: '{{ referrer.id|default:'' }}',
referrerName: '{% if referrer %}{{ referrer.get_full_name }}{% endif %}', referrerName: '{% if referrer %}{{ referrer.get_full_name }}{% endif %}',

@ -18,7 +18,7 @@
<div class="teachers__wrap"> <div class="teachers__wrap">
<div class="teachers__title"> <div class="teachers__title">
<div class="teachers__title-name"> <div class="teachers__title-name">
<a href="{% url 'user' teacher.id %}">{{ teacher.get_full_name }}</a>{% if teacher.instagram_hashtag %}, <a href="{{ teacher.url }}">{{ teacher.get_full_name }}</a>{% if teacher.instagram_hashtag %},
<a href='https://www.instagram.com/explore/tags/{{ teacher.instagram_hashtag }}/' target="_blank"> <a href='https://www.instagram.com/explore/tags/{{ teacher.instagram_hashtag }}/' target="_blank">
{{ teacher.instagram_hashtag }} {{ teacher.instagram_hashtag }}
</a> </a>

@ -16,9 +16,9 @@
{{ request.user.balance }} руб. {{ request.user.balance }} руб.
</a> </a>
{% endif %} {% endif %}
<a class="header__link header__link_border" href="{% url 'user-bonuses' %}"> <!--<a class="header__link header__link_border" href="{% url 'user-bonuses' %}">-->
{{ request.user.bonus|rupluralize:"бонус,бонуса,бонусов" }} <!--{{ request.user.bonus|rupluralize:"бонус,бонуса,бонусов" }}-->
</a> <!--</a>-->
{% if request.user.auth_token %} {% if request.user.auth_token %}
{% if request.user.role >= request.user.AUTHOR_ROLE %} {% if request.user.role >= request.user.AUTHOR_ROLE %}
<a class="header__link header__link_green" href="{% url 'course_create' %}"> <a class="header__link header__link_green" href="{% url 'course_create' %}">

@ -70,6 +70,7 @@ urlpatterns = [
path('user/profile/', ProfileView.as_view(), name='user-profile'), path('user/profile/', ProfileView.as_view(), name='user-profile'),
path('user/profile/edit', ProfileEditView.as_view(), name='user-edit-profile'), path('user/profile/edit', ProfileEditView.as_view(), name='user-edit-profile'),
path('user/<int:pk>/', UserView.as_view(), name='user'), path('user/<int:pk>/', UserView.as_view(), name='user'),
path('user/<str:slug>/', UserView.as_view(), name='user'),
path('user/notifications', NotificationEditView.as_view(), name='user-edit-notifications'), path('user/notifications', NotificationEditView.as_view(), name='user-edit-notifications'),
path('user/payments', PaymentHistoryView.as_view(), name='user-edit-payments'), path('user/payments', PaymentHistoryView.as_view(), name='user-edit-payments'),
path('user/bonuses', BonusHistoryView.as_view(), name='user-bonuses'), path('user/bonuses', BonusHistoryView.as_view(), name='user-bonuses'),

@ -17,7 +17,7 @@ import "./modules/courses";
import "./modules/comments"; import "./modules/comments";
import "./modules/comments"; import "./modules/comments";
import "./modules/password-show"; import "./modules/password-show";
import "./modules/profile"; import {main as profileMain} from "./modules/profile";
import "./modules/notification"; import "./modules/notification";
import "./modules/mixpanel"; import "./modules/mixpanel";
@ -55,5 +55,15 @@ const app = new Vue({
store: window.LIL_STORE, store: window.LIL_STORE,
} }
}, },
mounted(){
if(this.urlIs('userProfileEdit')){
profileMain(this);
}
},
methods: {
urlIs(urlPatternName){
return window.location.pathname.search(this.store.urls[urlPatternName]) > -1;
},
},
components: components components: components
}); });

@ -1,18 +1,48 @@
import $ from 'jquery'; import $ from 'jquery';
import slugify from 'slugify';
$(document).ready(function () { export const main = () => {
// Обработчик выбора пола // Обработчик выбора пола
let genderInput = $('#gender') let genderInput = $('#gender')
$('div.js-select-option[data-gender-option]').on('click', function (e) { $('div.js-select-option[data-gender-option]').on('click', function (e) {
e.preventDefault(); e.preventDefault();
const currentGender = $(this).attr('data-gender'); const currentGender = $(this).attr('data-gender');
$('[data-gender]').removeClass('active'); $('[data-gender]').removeClass('active');
$(`[data-gender=${currentGender}]`).addClass('active'); $(`[data-gender=${currentGender}]`).addClass('active');
genderInput.val(currentGender) genderInput.val(currentGender)
}); });
$('#referrer-url').select().click(function(){ $('#user-photo-upload').change(file => {
$(this).select(); const input = file.target;
});
}) const reader = new FileReader();
reader.onload = () => {
const dataURL = reader.result;
const output = document.getElementById('photo');
output.src = dataURL;
};
reader.readAsDataURL(input.files[0]);
});
const $slug = $('#user-slug');
const changeSlug = () => {
const fName = $('#user-first-name').val();
const lName = $('#user-last-name').val();
$slug.val(slugify(`${fName} ${lName}`));
}
if(! $slug.data('current-slug')){
$('#user-first-name').change(changeSlug);
$('#user-last-name').change(changeSlug);
$slug.change(() => {
$('#user-first-name').unbind('change', changeSlug);
$('#user-last-name').unbind('change', changeSlug);
});
changeSlug();
}
$('#referrer-url').select().click(function(){
$(this).select();
});
}

@ -2167,6 +2167,10 @@ a.grey-link
width: 100px width: 100px
&__append &__append
text-transform: uppercase text-transform: uppercase
&__text
height: 36px
font-size: 18px
padding-top: 6px
&__input, &__input,
&__textarea &__textarea
width: 100% width: 100%

Loading…
Cancel
Save