LIL-626 Добавить возможность задать  линк на профиль

remotes/origin/hotfix/LIL-691
gzbender 7 years ago
parent c86302d4c6
commit f1bf09cd0d
  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. 1
      apps/user/forms.py
  7. 18
      apps/user/migrations/0024_user_slug.py
  8. 10
      apps/user/models.py
  9. 36
      apps/user/templates/user/profile-settings.html
  10. 1
      apps/user/views.py
  11. 1
      project/settings.py
  12. 5
      project/templates/blocks/lil_store_js.html
  13. 2
      project/templates/blocks/teachers.html
  14. 1
      project/urls.py
  15. 12
      web/src/js/app.js
  16. 54
      web/src/js/modules/profile.js
  17. 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',

@ -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),
),
]

@ -1,4 +1,5 @@
from json import dumps from json import dumps
from rest_framework.authtoken.models import Token from rest_framework.authtoken.models import Token
from phonenumber_field.modelfields import PhoneNumberField from phonenumber_field.modelfields import PhoneNumberField
@ -9,6 +10,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
@ -76,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()
@ -85,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)

@ -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 %}
<div class="section section_gray section_menu"> <div class="section section_gray section_menu">
<div class="section__center center center_xs"> <div class="section__center center center_xs">
<div class="menu"> <div class="menu">
@ -44,7 +48,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>
@ -55,7 +59,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>
@ -64,7 +68,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>
@ -89,6 +93,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>
@ -257,19 +272,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 %}

@ -99,6 +99,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()

@ -31,6 +31,7 @@ SECRET_KEY = os.getenv('SECRET_KEY', 'jelm*91lj(_-o20+6^a+bgv!4s6e_efry^#+f#=1ak
DEBUG = os.getenv('DEBUG', False) DEBUG = os.getenv('DEBUG', False)
ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', '*').split(',') ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', '*').split(',')
MAIN_HOST = os.getenv('MAIN_HOST', 'lil.school')
# Application definition # Application definition

@ -20,7 +20,8 @@
}, },
components: {}, components: {},
urls: { urls: {
courses: "{% url 'courses' %}" courses: "{% url 'courses' %}",
}, userProfileEdit: "{% url 'user-edit-profile' %}",
}
}; };
</script> </script>

@ -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>

@ -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/<int:pk>/notifications', NotificationEditView.as_view(), name='user-edit-notifications'), path('user/<int:pk>/notifications', NotificationEditView.as_view(), name='user-edit-notifications'),
path('user/<int:pk>/payments', PaymentHistoryView.as_view(), name='user-edit-payments'), path('user/<int:pk>/payments', PaymentHistoryView.as_view(), name='user-edit-payments'),
path('user/resend-email-verify', resend_email_verify, name='resend-email-verify'), path('user/resend-email-verify', resend_email_verify, name='resend-email-verify'),

@ -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,14 +1,44 @@
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)
}); });
})
$('#user-photo-upload').change(file => {
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();
}
}

@ -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