Merge branch 'master' into feature/created_courses

# Conflicts:
#	.gitignore
#	project/templates/lilcity/index.html
remotes/origin/hasaccess
nikita 8 years ago
commit 854f102ada
  1. 3
      .gitignore
  2. 2
      docs/overview.md
  3. 642
      project/templates/lilcity/index.html
  4. 14631
      web/build/js/app.js
  5. 1495
      web/package-lock.json
  6. 11
      web/package.json
  7. 260
      web/src/js/app.js
  8. 248
      web/src/js/app_def.js
  9. 1
      web/src/js/constants.js
  10. 241
      web/src/js/modules/auth.js
  11. 10
      web/src/js/modules/common.js
  12. 13
      web/src/js/modules/datepicker.js
  13. 36
      web/src/js/modules/header.js
  14. 50
      web/src/js/modules/popup.js
  15. 29
      web/src/js/modules/search.js
  16. 44
      web/src/js/modules/select.js
  17. 24
      web/src/js/modules/tabs.js
  18. 10
      web/src/js/modules/toggle.js
  19. 58
      web/webpack.config.js

3
.gitignore vendored

@ -107,4 +107,7 @@ venv.bak/
# PyCharm
.idea/
# JavaScript
.map
node_modules
db.sqlite3

@ -2,7 +2,7 @@
### Backend
Представляет из себя веб-приложение на Python с использованием
Представляет из себя веб-приложение на Python 3.6 с использованием
следующих фреймворков и технологий: Django-2.0.1
Сервер проекта предоставляет для клиентской части API на основе REST, реализуя методы

@ -4,291 +4,441 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Index Page</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="theme-color" content="#fff">
<meta name="format-detection" content="telephone=no">
<meta name="description" content="Page description">
<!--Twitter Card data-->
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@publisher_handle">
<meta name="twitter:title" content="Page Title">
<meta name="twitter:description" content="Page description less than 200 characters">
<meta name="twitter:creator" content="@author_handle">
<meta name="twitter:image" content="http://www.example.com/image.jpg">
<!--Open Graph data-->
<meta property="og:title" content="Title Here">
<meta property="og:type" content="article">
<meta property="og:url" content="http://www.example.com/">
<meta property="og:image" content="http://example.com/image.jpg">
<meta property="og:description" content="Description Here">
<meta property="og:site_name" content="Site Name, i.e. Moz">
<meta property="fb:admins" content="Facebook numeric ID">
<link rel="stylesheet" media="all" href={% static "css/app.css" %}>
<script>
<head>
<meta charset="utf-8">
<title>Index Page</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="theme-color" content="#fff">
<meta name="format-detection" content="telephone=no">
<meta name="description" content="Page description">
<!--Twitter Card data-->
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@publisher_handle">
<meta name="twitter:title" content="Page Title">
<meta name="twitter:description" content="Page description less than 200 characters">
<meta name="twitter:creator" content="@author_handle">
<meta name="twitter:image" content="http://www.example.com/image.jpg">
<!--Open Graph data-->
<meta property="og:title" content="Title Here">
<meta property="og:type" content="article">
<meta property="og:url" content="http://www.example.com/">
<meta property="og:image" content="http://example.com/image.jpg">
<meta property="og:description" content="Description Here">
<meta property="og:site_name" content="Site Name, i.e. Moz">
<meta property="fb:admins" content="Facebook numeric ID">
<meta name="csrf-token" content="{{ csrf_token }}">
<link rel="stylesheet" media="all" href={% static "css/app.css" %}>
<script>
var viewportmeta = document.querySelector('meta[name="viewport"]');
if (viewportmeta)
{
if (screen.width <= 360)
{
var newScale = screen.width / 360;
viewportmeta.content = 'width=360, minimum-scale=' + newScale + ', user-scalable=0, maximum-scale=1, initial-scale=' + newScale + '';
}
else
{
viewportmeta.content = 'width=device-width, maximum-scale=1.6, initial-scale=1.0';
}
if (viewportmeta) {
if (screen.width <= 360) {
var newScale = screen.width / 360;
viewportmeta.content = 'width=360, minimum-scale=' + newScale + ', user-scalable=0, maximum-scale=1, initial-scale=' + newScale + '';
}
else {
viewportmeta.content = 'width=device-width, maximum-scale=1.6, initial-scale=1.0';
}
}
</script>
</head>
</script>
</head>
<body>
<div class="outer js-outer">
<header class="header js-header">
<div class="header__center center">
<div class="header__container"><button class="header__menu js-header-menu"><svg class="icon icon-menu"><use xlink:href={% static "img/sprite.svg" %}#icon-menu></use></svg></button><a class="header__logo logo" href="/"></a>
<div class="header__wrap js-header-wrap">
<div class="header__top"><button class="header__close js-header-close"><svg class="icon icon-close"><use xlink:href={% static "img/sprite.svg" %}#icon-close></use></svg></button>
<form class="header__search search js-search" action=""><input class="search__input js-search-input" type="text"><button class="search__btn js-search-btn" type="submit"><svg class="icon icon-search"><use xlink:href={% static "img/sprite.svg" %}#icon-search></use></svg></button></form>
<body>
<div class="outer js-outer">
<header class="header js-header">
<div class="header__center center">
<div class="header__container">
<button class="header__menu js-header-menu">
<svg class="icon icon-menu">
<use xlink:href={% static "img/sprite.svg" %}#icon-menu></use>
</svg>
</button>
<a class="header__logo logo" href="/"></a>
<div class="header__wrap js-header-wrap">
<div class="header__top">
<button class="header__close js-header-close">
<svg class="icon icon-close">
<use xlink:href={% static "img/sprite.svg" %}#icon-close></use>
</svg>
</button>
<form class="header__search search js-search" action=""><input class="search__input js-search-input"
type="text">
<button class="search__btn js-search-btn" type="submit">
<svg class="icon icon-search">
<use xlink:href={% static "img/sprite.svg" %}#icon-search></use>
</svg>
</button>
</form>
</div>
<nav class="header__nav">
<div class="header__group"><a class="header__section header__section_sub js-header-section {% active_link 'index' %}" href="{% url 'index' %}">ОНЛАЙН-ШКОЛА</a>
<div class="header__list js-header-list">
<a class="header__link" href="#">
<div class="header__title">О школе</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Процесс</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Преимущества</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Отзывы</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Галерея</div>
</a>
<a class="header__link active" href="#">
<div class="header__title">Расписание</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Преподаватели</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Частые вопросы</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Оплата</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Контакты</div>
</a>
</div>
<nav class="header__nav">
<div class="header__group"><a class="header__section header__section_sub js-header-section {% active_link 'index' %}" href="{% url 'index' %}">ОНЛАЙН-ШКОЛА</a>
<div class="header__list js-header-list">
<a class="header__link" href="#">
<div class="header__title">О школе</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Процесс</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Преимущества</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Отзывы</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Галерея</div>
</a>
<a class="header__link active" href="#">
<div class="header__title">Расписание</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Преподаватели</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Частые вопросы</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Оплата</div>
</a>
<a class="header__link" href="#">
<div class="header__title">Контакты</div>
</a>
</div>
</div>
<div class="header__group"><a class="header__section header__section_sub js-header-section {% active_link 'courses' %}" href="{% url 'courses' %}">ВИДЕО-КУРСЫ</a>
<div class="header__list js-header-list">
<a class="header__link" href="#">
<div class="header__title">ПЕРСОНАЖ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">АКВАРЕЛЬ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">ИЛЛЮСТРАЦИЯ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">АНИМАЦИЯ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">ПАСТЕЛЬ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">ПЛАСТИЛИН</div>
</a>
<a class="header__link" href="#">
<div class="header__title">КРЕАТИВНОЕ МЫШЛЕНИЕ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">МОТОРИКА</div>
</a>
<a class="header__link" href="#">
<div class="header__title">ЖИВОПИСЬ</div>
</a>
</div>
</div>
<div class="header__group"><a class="header__section" href="#">БЛОГ</a></div>
</nav>
</div><button class="header__enter js-header-enter" data-popup=".js-popup-auth">ВХОД<svg class="icon icon-user"><use xlink:href={% static "img/sprite.svg" %}#icon-user></use></svg></button></div>
</div>
</header>
<div class="container">
{% block content %}{% endblock content %}
</div>
<footer class="footer">
<div class="footer__center center">
<div class="footer__row footer__row_first">
<div class="footer__col footer__col_md"><a class="footer__logo logo" href="/"></a>
<div class="footer__content">Первая онлайн-школа креативного мышления Lil City School</div>
</div>
<div class="footer__col">
<div class="footer__title">КОМПАНИЯ</div>
<nav class="footer__nav"><a class="footer__link" href="#">О нас</a><a class="footer__link" href="#">Преподаватели</a><a class="footer__link" href="#">Блог</a><a class="footer__link" href="#">Наши приложения</a><a class="footer__link" href="#">Медиа-кит</a></nav>
</div>
<div class="footer__col">
<div class="footer__title">Программы</div>
<nav class="footer__nav"><a class="footer__link" href="#">Онлайн-школа</a><a class="footer__link" href="#">Онлайн-курсы</a><a class="footer__link" href="#">Стать автором</a></nav>
</div>
<div class="footer__col">
<div class="footer__title">Контакты</div>
<div class="footer__contact">Общие вопросы: <a href='mailto:school@lil.city'>school@lil.city</a></div>
<div class="footer__contact">Сотрудничество: <a href='mailto:partnership@lil.city'>partnership@lil.city</a></div>
</div>
<div class="footer__col footer__col_md">
<div class="footer__title">ПОДПИСАТЬСЯ НА НОВОСТИ</div>
<div class="subscribe">
<div class="subscribe__field"><input class="subscribe__input" type="text" placeholder="Email"></div><button class="subscribe__btn btn btn_light">ПОДПИСАТЬСЯ</button>
<div class="subscribe__content">Мы сами не любим спам, поэтому вы будете подучать от только важные новости о школе, новых курсах и бонусах от Lil City. </div>
<div class="header__group"><a class="header__section header__section_sub js-header-section {% active_link 'courses' %}" href="{% url 'courses' %}">ВИДЕО-КУРСЫ</a>
<div class="header__list js-header-list">
<a class="header__link" href="#">
<div class="header__title">ПЕРСОНАЖ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">АКВАРЕЛЬ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">ИЛЛЮСТРАЦИЯ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">АНИМАЦИЯ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">ПАСТЕЛЬ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">ПЛАСТИЛИН</div>
</a>
<a class="header__link" href="#">
<div class="header__title">КРЕАТИВНОЕ МЫШЛЕНИЕ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">МОТОРИКА</div>
</a>
<a class="header__link" href="#">
<div class="header__title">ЖИВОПИСЬ</div>
</a>
</div>
</div>
<div class="header__group"><a class="header__section" href="#">БЛОГ</a></div>
</nav>
</div>
<button class="header__enter js-header-enter" data-popup=".js-popup-auth">ВХОД
<svg class="icon icon-user">
<use xlink:href={% static "img/sprite.svg" %}#icon-user></use>
</svg>
</button>
</div>
</div>
</header>
<div class="container">
{% block content %}{% endblock content %}
</div>
<footer class="footer">
<div class="footer__center center">
<div class="footer__row footer__row_first">
<div class="footer__col footer__col_md"><a class="footer__logo logo" href="/"></a>
<div class="footer__content">Первая онлайн-школа креативного мышления Lil City School</div>
</div>
<div class="footer__col">
<div class="footer__title">КОМПАНИЯ</div>
<nav class="footer__nav"><a class="footer__link" href="#">О нас</a><a class="footer__link" href="#">Преподаватели</a><a
class="footer__link" href="#">Блог</a><a class="footer__link" href="#">Наши приложения</a><a
class="footer__link" href="#">Медиа-кит</a></nav>
</div>
<div class="footer__col">
<div class="footer__title">Программы</div>
<nav class="footer__nav"><a class="footer__link" href="#">Онлайн-школа</a><a class="footer__link" href="#">Онлайн-курсы</a><a
class="footer__link" href="#">Стать автором</a></nav>
</div>
<div class="footer__col">
<div class="footer__title">Контакты</div>
<div class="footer__contact">Общие вопросы: <a href='mailto:school@lil.city'>school@lil.city</a></div>
<div class="footer__contact">Сотрудничество: <a href='mailto:partnership@lil.city'>partnership@lil.city</a>
</div>
<div class="footer__row footer__row_second">
<div class="footer__col footer__col_md">
<div class="footer__socials socials"><a class="socials__item" href="#"><svg class="icon icon-instagram"><use xlink:href={% static "img/sprite.svg" %}#icon-instagram></use></svg></a><a class="socials__item" href="#"><svg class="icon icon-twitter"><use xlink:href={% static "img/sprite.svg" %}#icon-twitter></use></svg></a>
<a
class="socials__item" href="#"><svg class="icon icon-fb"><use xlink:href={% static "img/sprite.svg" %}#icon-fb></use></svg></a><a class="socials__item" href="#"><svg class="icon icon-youtube"><use xlink:href={% static "img/sprite.svg" %}#icon-youtube></use></svg></a></div>
</div>
<div class="footer__col footer__col_lg">
<div class="footer__group">
<div class="footer__copyright">2017 © Lil City, UAB.</div>
<div class="footer__links"><a class="footer__link" href="#">Договор-оферта</a>
<div class="footer__divider">|</div><a class="footer__link" href="#">Политика обработки персональных данных</a></div>
</div>
</div>
<div class="footer__col footer__col_md">
<div class="footer__title">ПОДПИСАТЬСЯ НА НОВОСТИ</div>
<div class="subscribe">
<div class="subscribe__field"><input class="subscribe__input" type="text" placeholder="Email"></div>
<button class="subscribe__btn btn btn_light">ПОДПИСАТЬСЯ</button>
<div class="subscribe__content">Мы сами не любим спам, поэтому вы будете подучать от только важные новости о
школе, новых курсах и бонусах от Lil City.
</div>
</div>
</div>
</footer>
<div class="popup js-popup-auth">
<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></svg></button>
<div class="popup__body">
<div class="auth js-auth">
<div class="auth__login js-auth-login">
<div class="auth__nav"><a class="auth__type js-auth-type active" href="#">Войти</a><a class="auth__type js-auth-type" href="#">РЕГИСТРАЦИЯ</a></div>
<div class="auth__body">
<div class="auth__tab js-auth-tab" style="display: block;">
<div class="auth__enter js-auth-enter">
<div class="auth__field field">
<div class="field__label">ПОЧТА</div>
<div class="field__wrap"><input class="field__input" type="email" placeholder="name@website.com"></div>
</div>
<div class="auth__field field">
<div class="field__label">ПАРОЛЬ<a class="field__link js-auth-go-pass" href="#">Забыли пароль?</a></div>
<div class="field__wrap"><input class="field__input" type="password" placeholder="Минимум 5 символов"></div>
</div>
<div class="footer__row footer__row_second">
<div class="footer__col footer__col_md">
<div class="footer__socials socials"><a class="socials__item" href="#">
<svg class="icon icon-instagram">
<use xlink:href={% static "img/sprite.svg" %}#icon-instagram></use>
</svg>
</a><a class="socials__item" href="#">
<svg class="icon icon-twitter">
<use xlink:href={% static "img/sprite.svg" %}#icon-twitter></use>
</svg>
</a>
<a
class="socials__item" href="#">
<svg class="icon icon-fb">
<use xlink:href={% static "img/sprite.svg" %}#icon-fb></use>
</svg>
</a><a class="socials__item" href="#">
<svg class="icon icon-youtube">
<use xlink:href={% static "img/sprite.svg" %}#icon-youtube></use>
</svg>
</a></div>
</div>
<div class="footer__col footer__col_lg">
<div class="footer__group">
<div class="footer__copyright">2017 © Lil City, UAB.</div>
<div class="footer__links"><a class="footer__link" href="#">Договор-оферта</a>
<div class="footer__divider">|</div>
<a class="footer__link" href="#">Политика обработки персональных данных</a></div>
</div>
</div>
</div>
</div>
</footer>
<div class="popup js-popup-auth">
<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>
</svg>
</button>
<div class="popup__body">
<div class="auth js-auth">
<div class="auth__login js-auth-login">
<div class="auth__nav"><a class="auth__type js-auth-type active" href="#">Войти</a><a
class="auth__type js-auth-type" href="#">РЕГИСТРАЦИЯ</a></div>
<div class="auth__body">
<form id="learner-auth-form" method="post" action="{% url 'lilcity:login' %}">
{% csrf_token %}
<div class="auth__tab js-auth-tab" style="display: block;">
<div class="auth__enter js-auth-enter">
<div id="learner-auth-field__username" class="auth__field field learner-auth-form__field">
<div class="field__label">ПОЧТА</div>
<div class="field__wrap"><input id="learner-auth-form__email" class="field__input" type="email"
name="username"
placeholder="name@website.com" tabindex="1"></div>
<div id="learner-auth-field-error__username"
class="field__error learner-auth-form__field-error"></div>
</div>
<div id="learner-auth-field__password" class="auth__field field learner-auth-form__field">
<div class="field__label">ПАРОЛЬ<a class="field__link js-auth-go-pass" href="#" tabindex="4">Забыли
пароль?</a></div>
<div class="field__wrap"><input id="learner-auth-form__password" class="field__input"
name="password"
type="password" placeholder="Минимум 5 символов" tabindex="2">
</div>
<div class="auth__foot"><button class="auth__btn btn btn_light">ВОЙТИ</button>
<div class="auth__or">или</div><button class="auth__btn btn btn_fb"><svg class="icon icon-facebook"><use xlink:href={% static "img/sprite.svg" %}#icon-facebook></use></svg><span class="btn__title">ЧЕРЕЗ FACEBOOK</span></button></div>
<div id="learner-auth-field-error__password"
class="field__error learner-auth-form__field-error"></div>
<div id="learner-auth-field-error__all" class="learner-auth-form__field-error"></div>
</div>
<div class="auth__foot">
<button class="auth__btn btn btn_light" tabindex="3">ВОЙТИ</button>
<div class="auth__or">или</div>
<button class="auth__btn btn btn_fb">
<svg class="icon icon-facebook">
<use xlink:href={% static "img/sprite.svg" %}#icon-facebook></use>
</svg>
<span class="btn__title">ЧЕРЕЗ FACEBOOK</span></button>
</div>
</div>
<div class="auth__tab js-auth-tab">
<div class="auth__fieldset">
<div class="auth__field field">
<div class="field__label">ИМЯ</div>
<div class="field__wrap"><input class="field__input" type="text" placeholder="Sasha"></div>
</div>
<div class="auth__field field">
<div class="field__label">ФАМИЛИЯ</div>
<div class="field__wrap"><input class="field__input" type="text" placeholder="Kru"></div>
</div>
</div>
</form>
<form id="learner-registration-form" method="post" action="{% url 'lilcity:registration-learner' %}">
{% csrf_token %}
<div class="auth__tab js-auth-tab">
<div class="auth__fieldset">
<div id="learner-registration-field__first-name"
class="auth__field field learner-registration-form__field">
<div class="field__label">ИМЯ</div>
<div class="field__wrap"><input id="learner-registration-form__first-name" class="field__input"
type="text" name="first_name" placeholder="Sasha"></div>
<div id="learner-registration-field-error__first-name"
class="field__error learner-registration-form__field-error"></div>
</div>
<div class="auth__field field">
<div class="field__label">ПОЧТА</div>
<div class="field__wrap"><input class="field__input" type="email" placeholder="name@website.com"></div>
<div id="learner-registration-field__last-name"
class="auth__field field learner-registration-form__field">
<div class="field__label">ФАМИЛИЯ</div>
<div class="field__wrap"><input id="learner-registration-form__last-name" class="field__input"
type="text" name="last_name" placeholder="Kru"></div>
<div id="learner-registration-field-error__last-name"
class="field__error learner-registration-form__field-error"></div>
</div>
<div class="auth__field field">
<div class="field__label">ПАРОЛЬ</div>
<div class="field__wrap"><input class="field__input" type="password" placeholder="Минимум 5 символов"></div>
</div>
<div id="learner-registration-field__email"
class="auth__field field learner-registration-form__field">
<div class="field__label">ПОЧТА</div>
<div class="field__wrap"><input id="learner-registration-form__email" class="field__input"
type="email" name="email" placeholder="name@website.com"></div>
<div id="learner-registration-field-error__email"
class="field__error learner-registration-form__field-error"></div>
</div>
<div id="learner-registration-field__password"
class="auth__field field learner-registration-form__field">
<div class="field__label">ПАРОЛЬ</div>
<div class="field__wrap"><input id="learner-registration-form__password" class="field__input"
type="password" name="password" placeholder="Минимум 5 символов">
</div>
<div class="auth__foot"><button class="auth__btn btn btn_light">ЗАРЕГИСТРИРОВАТЬСЯ</button>
<div class="auth__or">или</div><button class="auth__btn btn btn_fb"><svg class="icon icon-facebook"><use xlink:href={% static "img/sprite.svg" %}#icon-facebook></use></svg><span class="btn__title">ЧЕРЕЗ FACEBOOK</span></button></div>
<div id="learner-registration-field-error__password"
class="field__error learner-registration-form__field-error"></div>
<div id="learner-registration-field-error__all"
class="learner-registration-form__field-error"></div>
</div>
<div class="auth__foot">
<button id="learner-registration-form__submit-button" class="auth__btn btn btn_light">
ЗАРЕГИСТРИРОВАТЬСЯ
</button>
<div class="auth__or">или</div>
<button class="auth__btn btn btn_fb">
<svg class="icon icon-facebook">
<use xlink:href={% static "img/sprite.svg" %}#icon-facebook></use>
</svg>
<span class="btn__title">ЧЕРЕЗ FACEBOOK</span></button>
</div>
</div>
</div>
<div class="auth__pass js-auth-pass">
<div class="auth__nav">
<div class="auth__type active">ВОССТАНОВЛЕНИЕ ПАРОЛЯ</div>
</div>
<div class="auth__body">
</form>
</div>
</div>
<div class="auth__pass js-auth-pass">
<div class="auth__nav">
<div class="auth__type active">ВОССТАНОВЛЕНИЕ ПАРОЛЯ</div>
</div>
<div class="auth__body">
<div id="password-reset__form-wrapper">
<form id="password-reset-form" method="post" action="{% url 'lilcity:password_reset' %}">
{% csrf_token %}
<div class="auth__enter js-auth-enter">
<div class="auth__field field">
<div id="password-reset__email-field" class="auth__field field">
<div class="field__label">ПОЧТА<a class="field__link js-auth-go-enter" href="#">Войти</a></div>
<div class="field__wrap"><input class="field__input" type="email" placeholder="name@website.com"></div>
<div class="field__wrap"><input id="password-reset__email" class="field__input" type="email"
name="email" placeholder="name@website.com">
</div>
<div id="password-reset-field-error__email"
class="field__error password-reset-form__field-error"></div>
<div id="password-reset-field-error__all"
class="password-reset-form__field-error"></div>
</div>
<div class="auth__foot">
<button class="auth__btn btn btn_light">ОТПРАВИТЬ</button>
</div>
<div class="auth__foot"><button class="auth__btn btn btn_light">ОТПРАВИТЬ</button></div>
</div>
</form>
</div>
<div id="password-reset__sent" style="display: none;">
<p>На ваш email отправлены инструкции по восстановлению пароля</p>
<div class="auth__foot">
<button id="password-reset__success-hide" class="auth__btn btn btn_light" type="button">Хорошо</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="popup js-popup-buy">
<div class="popup__wrap popup__wrap_lg 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></svg></button>
<div class="popup__body">
<div class="buy">
<div class="buy__row">
<div class="buy__col">
<div class="buy__head buy__head_main">
<div class="buy__title">Выбор урока/дня</div>
<div class="buy__content">При записи на 5 уроков скидка 10%.</div>
</div>
</div>
</div>
<div class="popup js-popup-buy">
<div class="popup__wrap popup__wrap_lg 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>
</svg>
</button>
<div class="popup__body">
<div class="buy">
<div class="buy__row">
<div class="buy__col">
<div class="buy__head buy__head_main">
<div class="buy__title">Выбор урока/дня</div>
<div class="buy__content">При записи на 5 уроков скидка 10%.</div>
</div>
</div>
<div class="buy__col">
<div class="buy__head">
<div class="buy__label">Месяц:</div>
<div class="buy__title">Январь</div>
<div class="buy__content">Если вы оплачиваете после 15 числа, доступ к урокам будет с 1-го следующего
месяца.
</div>
<div class="buy__col">
<div class="buy__head">
<div class="buy__label">Месяц:</div>
<div class="buy__title">Январь</div>
<div class="buy__content">Если вы оплачиваете после 15 числа, доступ к урокам будет с 1-го следующего месяца.</div>
</div>
</div>
<div class="buy__col">
<div class="buy__list"><label class="switch switch_lesson"><input class="switch__input"
type="checkbox"><span
class="switch__content"><span class="switch__cell">ПОНЕДЕЛЬНИК</span><span
class="switch__cell">5+</span><span class="switch__cell">Персонаж</span><span class="switch__cell">600р</span></span></label>
<label
class="switch switch_lesson"><input class="switch__input" type="checkbox" checked><span
class="switch__content"><span class="switch__cell">Вторник</span><span
class="switch__cell">5+</span><span class="switch__cell">Пластилиновая живопись</span><span
class="switch__cell">600р</span></span>
</label><label class="switch switch_lesson"><input class="switch__input" type="checkbox"><span
class="switch__content"><span class="switch__cell">Среда</span><span
class="switch__cell">5+</span><span class="switch__cell">Персонаж</span><span class="switch__cell">600р</span></span></label>
<label
class="switch switch_lesson"><input class="switch__input" type="checkbox" checked><span
class="switch__content"><span class="switch__cell">Четверг</span><span
class="switch__cell">5+</span><span class="switch__cell">Персонаж</span><span class="switch__cell">600р</span></span>
</label><label class="switch switch_lesson"><input class="switch__input" type="checkbox"><span
class="switch__content"><span class="switch__cell">Пятница</span><span
class="switch__cell">5+</span><span class="switch__cell">Развитие креативного мышления</span><span
class="switch__cell">600р</span></span></label>
<label
class="switch switch_lesson"><input class="switch__input" type="checkbox"><span
class="switch__content"><span class="switch__cell">Суббота</span><span
class="switch__cell">7+</span><span class="switch__cell">Персонаж</span><span class="switch__cell">600р</span></span>
</label><label class="switch switch_lesson"><input class="switch__input" type="checkbox" checked><span
class="switch__content"><span class="switch__cell">Воскресенье</span><span
class="switch__cell">7+</span><span class="switch__cell">Персонаж</span><span class="switch__cell">600р</span></span></label>
</div>
</div>
<div class="buy__col">
<div class="order">
<div class="order__wrap">
<div class="order__title">Ваш заказ:</div>
<div class="order__preview"><img class="order__pic" src={% static "img/order.jpg" %}></div>
<div class="order__info">
<div class="order__label">ШКОЛА</div>
<div class="order__days">Вторник, Четверг, Воскресенье</div>
</div>
</div>
<div class="buy__col">
<div class="buy__list"><label class="switch switch_lesson"><input class="switch__input" type="checkbox"><span class="switch__content"><span class="switch__cell">ПОНЕДЕЛЬНИК</span><span class="switch__cell">5+</span><span class="switch__cell">Персонаж</span><span class="switch__cell">600р</span></span></label>
<label
class="switch switch_lesson"><input class="switch__input" type="checkbox" checked><span class="switch__content"><span class="switch__cell">Вторник</span><span class="switch__cell">5+</span><span class="switch__cell">Пластилиновая живопись</span><span class="switch__cell">600р</span></span>
</label><label class="switch switch_lesson"><input class="switch__input" type="checkbox"><span class="switch__content"><span class="switch__cell">Среда</span><span class="switch__cell">5+</span><span class="switch__cell">Персонаж</span><span class="switch__cell">600р</span></span></label>
<label
class="switch switch_lesson"><input class="switch__input" type="checkbox" checked><span class="switch__content"><span class="switch__cell">Четверг</span><span class="switch__cell">5+</span><span class="switch__cell">Персонаж</span><span class="switch__cell">600р</span></span>
</label><label class="switch switch_lesson"><input class="switch__input" type="checkbox"><span class="switch__content"><span class="switch__cell">Пятница</span><span class="switch__cell">5+</span><span class="switch__cell">Развитие креативного мышления</span><span class="switch__cell">600р</span></span></label>
<label
class="switch switch_lesson"><input class="switch__input" type="checkbox"><span class="switch__content"><span class="switch__cell">Суббота</span><span class="switch__cell">7+</span><span class="switch__cell">Персонаж</span><span class="switch__cell">600р</span></span>
</label><label class="switch switch_lesson"><input class="switch__input" type="checkbox" checked><span class="switch__content"><span class="switch__cell">Воскресенье</span><span class="switch__cell">7+</span><span class="switch__cell">Персонаж</span><span class="switch__cell">600р</span></span></label></div>
</div>
<div class="buy__col">
<div class="order">
<div class="order__wrap">
<div class="order__title">Ваш заказ:</div>
<div class="order__preview"><img class="order__pic" src={% static "img/order.jpg" %}></div>
<div class="order__info">
<div class="order__label">ШКОЛА</div>
<div class="order__days">Вторник, Четверг, Воскресенье</div>
</div>
<div class="order__foot">
<div class="order__subtitle">Итого, за месяц:</div>
<div class="order__total">1800р.</div>
</div>
</div>
<div class="order__foot">
<div class="order__subtitle">Итого, за месяц:</div>
<div class="order__total">1800р.</div>
</div>
</div>
</div>
<div class="buy__foot"><a class="buy__btn btn btn_md" href="#">ПЕРЕЙТИ К ОПЛАТЕ</a></div>
</div>
</div>
<div class="buy__foot"><a class="buy__btn btn btn_md" href="#">ПЕРЕЙТИ К ОПЛАТЕ</a></div>
</div>
</div>
</div>
<script type="text/javascript" src={% static "js/app.js" %}></script>
</body>
</div>
</div>
<script type="text/javascript" src={% static "js/app.js" %}></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

1495
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -9,7 +9,10 @@
"authors": "Coderiver <html@coderiver.com.ua>",
"devDependencies": {
"autoprefixer": "^6.3.3",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-transform-runtime": "^6.4.3",
"babel-preset-env": "^1.6.1",
"babel-preset-es2015": "^6.3.13",
"browser-sync": "^2.10.0",
"css-mqpacker": "^5.0.1",
@ -37,6 +40,12 @@
"lodash": "^4.3.0",
"require-dir": "^0.3.0",
"run-sequence": "^1.1.5",
"through2": "^2.0.1"
"through2": "^2.0.1",
"webpack": "^3.10.0"
},
"dependencies": {
"jquery": "^3.3.1",
"owl.carousel": "^2.2.0",
"validator": "^9.2.0"
}
}

@ -1,248 +1,12 @@
// example of simple includes for js
//=include lib/jquery.min.js
//=include lib/owl.carousel.min.js
//=include lib/jquery-ui.min.js
//=include lib/datepicker-ru.js
// global
var mobileWidth = 600;
// header
(function(){
var header = $('.js-header'),
menu = header.find('.js-header-menu'),
wrap = header.find('.js-header-wrap'),
close = header.find('.js-header-close'),
section = header.find('.js-header-section'),
list = header.find('.js-header-list');
menu.on('click', function(e){
if ($(window).width() < mobileWidth) {
e.preventDefault();
wrap.addClass('visible');
}
});
close.on('click', function(e){
if ($(window).width() < mobileWidth) {
e.preventDefault();
wrap.removeClass('visible');
$(window).scrollTop(0);
}
});
section.on('click', function(e){
if ($(window).width() < mobileWidth) {
e.preventDefault();
var _this = $(this);
_this.toggleClass('open');
_this.next().slideToggle();
}
});
}());
// search
(function(){
var search = $('.js-search'),
input = search.find('.js-search-input'),
btn = search.find('.js-search-btn');
btn.on('click', function(e){
if ($(window).width() >= mobileWidth) {
if (!search.hasClass('open')) {
e.preventDefault();
}
search.addClass('open');
setTimeout(function(){
input.focus();
}, 200);
}
});
search.on('click', function(e){
e.stopPropagation();
});
$(document).on('click', function(){
search.removeClass('open');
input.val('');
});
}());
// toggle
(function(){
$('.js-toggle-head').on('click', function(e){
e.preventDefault();
var _this = $(this);
_this.toggleClass('active');
_this.next().slideToggle();
});
}());
// auth
(function(){
var auth = $('.js-auth'),
type = auth.find('.js-auth-type'),
tab = auth.find('.js-auth-tab'),
login = auth.find('.js-auth-login'),
pass = auth.find('.js-auth-pass'),
goPass = auth.find('.js-auth-go-pass'),
goEnter = auth.find('.js-auth-go-enter');
type.on('click', function(e){
e.preventDefault();
var _this = $(this),
index = _this.index();
type.removeClass('active');
_this.addClass('active');
tab.hide();
tab.eq(index).fadeIn();
});
goPass.on('click', function(e){
e.preventDefault();
login.hide();
pass.fadeIn();
});
goEnter.on('click', function(e){
e.preventDefault();
pass.hide();
login.fadeIn();
});
}());
// select
(function(){
var select = $('.js-select');
if (select.length) {
select.each(function(){
var _this = $(this),
head = _this.find('.js-select-head'),
option = _this.find('.js-select-option'),
input = _this.find('.js-select-input');
head.on('click', function(e){
e.preventDefault();
e.stopPropagation();
if (_this.hasClass('active')) {
_this.removeClass('active');
} else {
select.removeClass('active');
_this.addClass('active');
}
});
option.on('click', function(e){
e.preventDefault();
_this.addClass('selected');
var _thisOption = $(this),
value = _thisOption.text();
head.text(value);
option.removeClass('active');
_thisOption.addClass('active');
input.val(value);
});
});
$(document).on('click', function(){
select.removeClass('active');
});
}
}());
// datepicker
(function(){
var datepicker = $('.js-datepicker');
if (datepicker.length) {
$.datepicker.setDefaults( $.datepicker.regional["ru"]);
datepicker.each(function(){
$(this).datepicker({
dateFormat: "dd/mm/yy"
});
});
}
}());
// tabs
(function(){
var tabs = $('.js-tabs');
if (tabs.length) {
tabs.each(function(){
var _this = $(this),
btn = _this.find('.js-tabs-btn'),
item = _this.find('.js-tabs-item');
btn.on('click', function(e){
e.preventDefault();
var _thisBtn = $(this),
index = _thisBtn.index();
btn.removeClass('active');
_thisBtn.addClass('active');
item.hide();
item.eq(index).fadeIn();
});
});
}
}());
// popup
(function(){
var body = $('body'),
popup;
$('body').on('click', '[data-popup]', function(e){
e.preventDefault();
e.stopPropagation();
var data = $(this).data('popup');
popup = $(data);
showPopup();
});
$('.js-popup-close').on('click', function(e){
e.preventDefault();
hidePopup();
});
$('body').on('click', '.js-outer', function(){
if (popup != undefined) {
hidePopup();
}
});
$('.js-popup-wrap').on('click', function(e){
e.stopPropagation();
});
$(document).keyup(function(e){
if (e.keyCode === 27) hidePopup();
});
function showPopup(){
body.addClass('no-scroll');
popup.addClass('open');
setTimeout(function(){
popup.addClass('visible');
}, 100);
}
function hidePopup(){
body.removeClass('no-scroll');
popup.removeClass('visible');
setTimeout(function(){
popup.removeClass('open');
}, 300);
}
}());
/**
* Входная точка клиентского приложения.
*/
import "./modules/common";
import "./modules/header";
import "./modules/search";
import "./modules/toggle";
import "./modules/auth";
import "./modules/select";
// import "./modules/datepicker";
import "./modules/tabs";
import "./modules/popup";

@ -0,0 +1,248 @@
// example of simple includes for js
//=include lib/jquery.min.js
//=include lib/owl.carousel.min.js
//=include lib/jquery-ui.min.js
//=include lib/datepicker-ru.js
// global
var mobileWidth = 600;
// header
(function(){
var header = $('.js-header'),
menu = header.find('.js-header-menu'),
wrap = header.find('.js-header-wrap'),
close = header.find('.js-header-close'),
section = header.find('.js-header-section'),
list = header.find('.js-header-list');
menu.on('click', function(e){
if ($(window).width() < mobileWidth) {
e.preventDefault();
wrap.addClass('visible');
}
});
close.on('click', function(e){
if ($(window).width() < mobileWidth) {
e.preventDefault();
wrap.removeClass('visible');
$(window).scrollTop(0);
}
});
section.on('click', function(e){
if ($(window).width() < mobileWidth) {
e.preventDefault();
var _this = $(this);
_this.toggleClass('open');
_this.next().slideToggle();
}
});
}());
// search
(function(){
var search = $('.js-search'),
input = search.find('.js-search-input'),
btn = search.find('.js-search-btn');
btn.on('click', function(e){
if ($(window).width() >= mobileWidth) {
if (!search.hasClass('open')) {
e.preventDefault();
}
search.addClass('open');
setTimeout(function(){
input.focus();
}, 200);
}
});
search.on('click', function(e){
e.stopPropagation();
});
$(document).on('click', function(){
search.removeClass('open');
input.val('');
});
}());
// toggle
(function(){
$('.js-toggle-head').on('click', function(e){
e.preventDefault();
var _this = $(this);
_this.toggleClass('active');
_this.next().slideToggle();
});
}());
// auth
(function(){
var auth = $('.js-auth'),
type = auth.find('.js-auth-type'),
tab = auth.find('.js-auth-tab'),
login = auth.find('.js-auth-login'),
pass = auth.find('.js-auth-pass'),
goPass = auth.find('.js-auth-go-pass'),
goEnter = auth.find('.js-auth-go-enter');
type.on('click', function(e){
e.preventDefault();
var _this = $(this),
index = _this.index();
type.removeClass('active');
_this.addClass('active');
tab.hide();
tab.eq(index).fadeIn();
});
goPass.on('click', function(e){
e.preventDefault();
login.hide();
pass.fadeIn();
});
goEnter.on('click', function(e){
e.preventDefault();
pass.hide();
login.fadeIn();
});
}());
// select
(function(){
var select = $('.js-select');
if (select.length) {
select.each(function(){
var _this = $(this),
head = _this.find('.js-select-head'),
option = _this.find('.js-select-option'),
input = _this.find('.js-select-input');
head.on('click', function(e){
e.preventDefault();
e.stopPropagation();
if (_this.hasClass('active')) {
_this.removeClass('active');
} else {
select.removeClass('active');
_this.addClass('active');
}
});
option.on('click', function(e){
e.preventDefault();
_this.addClass('selected');
var _thisOption = $(this),
value = _thisOption.text();
head.text(value);
option.removeClass('active');
_thisOption.addClass('active');
input.val(value);
});
});
$(document).on('click', function(){
select.removeClass('active');
});
}
}());
// datepicker
(function(){
var datepicker = $('.js-datepicker');
if (datepicker.length) {
$.datepicker.setDefaults( $.datepicker.regional["ru"]);
datepicker.each(function(){
$(this).datepicker({
dateFormat: "dd/mm/yy"
});
});
}
}());
// tabs
(function(){
var tabs = $('.js-tabs');
if (tabs.length) {
tabs.each(function(){
var _this = $(this),
btn = _this.find('.js-tabs-btn'),
item = _this.find('.js-tabs-item');
btn.on('click', function(e){
e.preventDefault();
var _thisBtn = $(this),
index = _thisBtn.index();
btn.removeClass('active');
_thisBtn.addClass('active');
item.hide();
item.eq(index).fadeIn();
});
});
}
}());
// popup
(function(){
var body = $('body'),
popup;
$('body').on('click', '[data-popup]', function(e){
e.preventDefault();
e.stopPropagation();
var data = $(this).data('popup');
popup = $(data);
showPopup();
});
$('.js-popup-close').on('click', function(e){
e.preventDefault();
hidePopup();
});
$('body').on('click', '.js-outer', function(){
if (popup != undefined) {
hidePopup();
}
});
$('.js-popup-wrap').on('click', function(e){
e.stopPropagation();
});
$(document).keyup(function(e){
if (e.keyCode === 27) hidePopup();
});
function showPopup(){
body.addClass('no-scroll');
popup.addClass('open');
setTimeout(function(){
popup.addClass('visible');
}, 100);
}
function hidePopup(){
body.removeClass('no-scroll');
popup.removeClass('visible');
setTimeout(function(){
popup.removeClass('open');
}, 300);
}
}());

@ -0,0 +1 @@
export const MOBILE_WIDTH = 600;

@ -0,0 +1,241 @@
import $ from 'jquery';
import isEmail from 'validator/lib/isEmail';
import isEmpty from 'validator/lib/isEmpty';
import isLength from 'validator/lib/isLength';
$(document).ready(function () {
let auth = $('.js-auth'),
type = auth.find('.js-auth-type'),
tab = auth.find('.js-auth-tab'),
login = auth.find('.js-auth-login'),
pass = auth.find('.js-auth-pass'),
goPass = auth.find('.js-auth-go-pass'),
goEnter = auth.find('.js-auth-go-enter');
type.on('click', function (e) {
e.preventDefault();
let _this = $(this),
index = _this.index();
type.removeClass('active');
_this.addClass('active');
tab.hide();
tab.eq(index).fadeIn();
});
goPass.on('click', function (e) {
e.preventDefault();
login.hide();
pass.fadeIn();
});
goEnter.on('click', function (e) {
e.preventDefault();
pass.hide();
login.fadeIn();
});
$('#password-reset__success-hide').on('click', function (e) {
e.preventDefault();
$('#password-reset__form-wrapper').show();
$('#password-reset__sent').hide();
});
let passwordResetForm = $('#password-reset-form');
passwordResetForm.on('submit', function (e) {
e.preventDefault();
let passwordResetAllowed = true;
$('#password-reset__email-field').removeClass('error');
$('.password-reset-form__field-error').text('');
const emailValue = $('#password-reset__email').val();
if (isEmpty(emailValue)) {
$('#password-reset__email-field').addClass('error');
$('#password-reset-field-error__email').text('Укажите почту');
passwordResetAllowed = false;
} else if (!isEmail(emailValue)) {
$('#password-reset__email-field').addClass('error');
$('#password-reset-field-error__email').text('Похоже, вы допустили ошибку в почте');
passwordResetAllowed = false;
}
if (!passwordResetAllowed) {
return;
}
$.ajax(passwordResetForm.attr('action'), {
method: 'POST',
data: passwordResetForm.serialize(),
})
.done(function (data) {
if (data.success === true) {
$('#password-reset__form-wrapper').hide();
$('#password-reset__sent').show();
}
})
.fail(function (xhr) {
console.log('error', xhr);
if (xhr.status === 400) {
if (xhr.responseJSON.errors) {
for (let errorField in xhr.responseJSON.errors) {
if (!xhr.responseJSON.errors.hasOwnProperty(errorField)) {
continue;
}
const errorMessage = xhr.responseJSON.errors[errorField][0].message;
if (errorField === '__all__') {
$('#password-reset-field-error__all').text(errorMessage);
} else {
$(`#password-reset-field-error__${errorField}`).text(errorMessage);
$(`#password-reset__${errorField}-field`).addClass('error');
}
}
return;
}
}
$('#learner-auth-field-error__all').text('Произошла незвестная ошибка');
});
});
let authForm = $('#learner-auth-form');
authForm.on('submit', function (e) {
e.preventDefault();
let authAllowed = true;
$('.learner-auth-form__field').removeClass('error');
$('.learner-auth-form__field-error').text('');
const emailValue = $('#learner-auth-form__email').val();
if (isEmpty(emailValue)) {
$('#learner-auth-field__email').addClass('error');
$('#learner-auth-field-error__username').text('Укажите почту');
authAllowed = false;
} else if (!isEmail(emailValue)) {
$('#learner-auth-field__email').addClass('error');
$('#learner-auth-field-error__username').text('Похоже, вы допустили ошибку в почте');
authAllowed = false;
}
if (!isLength($('#learner-auth-form__password').val(), {min: 5, max: undefined})) {
$('#learner-auth-field__password').addClass('error');
$('#learner-auth-field-error__password').text('Наберите ваш пароль, минимум 5 символов в длину');
authAllowed = false;
}
if (!authAllowed) {
return;
}
$.ajax(authForm.attr('action'), {
method: 'POST',
data: authForm.serialize(),
})
.done(function (data) {
if (data.success === true) {
alert("DEV - Успешный вход");
// TODO: Куда редиректить пользователя?
}
})
.fail(function (xhr) {
console.log('error', xhr);
if (xhr.status === 400) {
if (xhr.responseJSON.errors) {
for (let errorField in xhr.responseJSON.errors) {
if (!xhr.responseJSON.errors.hasOwnProperty(errorField)) {
continue;
}
const errorMessage = xhr.responseJSON.errors[errorField][0].message;
if (errorField === '__all__') {
$('#learner-auth-field-error__all').text(errorMessage);
} else {
$(`#learner-auth-field-error__${errorField}`).text(errorMessage);
$(`#learner-auth-field__${errorField}`).addClass('error');
}
}
return;
}
}
$('#learner-auth-field-error__all').text('Произошла незвестная ошибка');
});
});
let registrationForm = $('#learner-registration-form');
registrationForm.on('submit', function (e) {
e.preventDefault();
let registrationAllowed = true;
$('.learner-registration-form__field').removeClass('error');
$('.learner-registration-form__field-error').text('');
if (isEmpty($('#learner-registration-form__first-name').val())) {
$('#learner-registration-field__first-name').addClass('error');
$('#learner-registration-field-error__first-name').text('Укажите имя');
registrationAllowed = false;
}
if (isEmpty($('#learner-registration-form__last-name').val())) {
$('#learner-registration-field__last-name').addClass('error');
$('#learner-registration-field-error__last-name').text('Укажите фамилию');
registrationAllowed = false;
}
const emailValue = $('#learner-registration-form__email').val();
if (isEmpty(emailValue)) {
$('#learner-registration-field__email').addClass('error');
$('#learner-registration-field-error__email').text('Укажите почту');
registrationAllowed = false;
} else if (!isEmail(emailValue)) {
$('#learner-registration-field__email').addClass('error');
$('#learner-registration-field-error__email').text('Похоже, вы допустили ошибку в почте');
registrationAllowed = false;
}
if (!isLength($('#learner-registration-form__password').val(), {min: 5, max: undefined})) {
$('#learner-registration-field__password').addClass('error');
$('#learner-registration-field-error__password').text('Укажите пароль, минимум 5 символов в длину');
registrationAllowed = false;
}
if (!registrationAllowed) {
return;
}
$.ajax(registrationForm.attr('action'), {
method: 'POST',
data: registrationForm.serialize(),
})
.done(function (data) {
if (data.success === true) {
alert("DEV - Успешная регистрация");
// TODO: Куда редиректить пользователя?
}
})
.fail(function (xhr) {
console.log('error', xhr);
if (xhr.status === 400) {
if (xhr.responseJSON.errors) {
for (let errorField in xhr.responseJSON.errors) {
if (!xhr.responseJSON.errors.hasOwnProperty(errorField)) {
continue;
}
const errorMessage = xhr.responseJSON.errors[errorField][0].message;
if (errorField === '__all__') {
$('#learner-registration-field-error__all').text(errorMessage);
} else {
$(`#learner-registration-field-error__${errorField}`).text(errorMessage);
$(`#learner-registration-field__${errorField}`).addClass('error');
}
}
return;
}
}
$('#learner-registration-field-error__all').text('Произошла незвестная ошибка');
});
});
});

@ -0,0 +1,10 @@
import $ from 'jquery';
$(document).ready(function () {
// Добавляем заголовок X-CSRFToken для всех AJAX запросов JQuery.
$.ajaxSetup({
headers: {
'X-CSRFToken': $('meta[name="csrf-token"]').attr('content')
}
});
});

@ -0,0 +1,13 @@
import $ from 'jquery';
$(document).ready(function () {
let datepicker = $('.js-datepicker');
if (datepicker.length) {
$.datepicker.setDefaults( $.datepicker.regional["ru"]);
datepicker.each(function(){
$(this).datepicker({
dateFormat: "dd/mm/yy"
});
});
}
});

@ -0,0 +1,36 @@
import $ from 'jquery';
import {MOBILE_WIDTH} from "../constants";
$(document).ready(function () {
let header = $('.js-header'),
menu = header.find('.js-header-menu'),
wrap = header.find('.js-header-wrap'),
close = header.find('.js-header-close'),
section = header.find('.js-header-section'),
list = header.find('.js-header-list');
menu.on('click', function(e){
if ($(window).width() < MOBILE_WIDTH) {
e.preventDefault();
wrap.addClass('visible');
}
});
close.on('click', function(e){
if ($(window).width() < MOBILE_WIDTH) {
e.preventDefault();
wrap.removeClass('visible');
$(window).scrollTop(0);
}
});
section.on('click', function(e){
if ($(window).width() < MOBILE_WIDTH) {
e.preventDefault();
let _this = $(this);
_this.toggleClass('open');
_this.next().slideToggle();
}
});
});

@ -0,0 +1,50 @@
import $ from 'jquery';
$(document).ready(function () {
let body = $('body'),
popup;
body.on('click', '[data-popup]', function(e){
e.preventDefault();
e.stopPropagation();
let data = $(this).data('popup');
popup = $(data);
showPopup();
});
$('.js-popup-close').on('click', function(e){
e.preventDefault();
hidePopup();
});
body.on('click', '.js-outer', function(){
if (popup !== undefined) {
hidePopup();
}
});
$('.js-popup-wrap').on('click', function(e){
e.stopPropagation();
});
$(document).keyup(function(e){
if (e.keyCode === 27) hidePopup();
});
function showPopup(){
body.addClass('no-scroll');
popup.addClass('open');
setTimeout(function(){
popup.addClass('visible');
}, 100);
}
function hidePopup(){
body.removeClass('no-scroll');
popup.removeClass('visible');
setTimeout(function(){
popup.removeClass('open');
}, 300);
}
});

@ -0,0 +1,29 @@
import $ from 'jquery';
import {MOBILE_WIDTH} from "../constants";
$(document).ready(function () {
let search = $('.js-search'),
input = search.find('.js-search-input'),
btn = search.find('.js-search-btn');
btn.on('click', function(e){
if ($(window).width() >= MOBILE_WIDTH) {
if (!search.hasClass('open')) {
e.preventDefault();
}
search.addClass('open');
setTimeout(function(){
input.focus();
}, 200);
}
});
search.on('click', function(e){
e.stopPropagation();
});
$(document).on('click', function(){
search.removeClass('open');
input.val('');
});
});

@ -0,0 +1,44 @@
import $ from 'jquery';
$(document).ready(function () {
let select = $('.js-select');
if (select.length) {
select.each(function(){
let _this = $(this),
head = _this.find('.js-select-head'),
option = _this.find('.js-select-option'),
input = _this.find('.js-select-input');
head.on('click', function(e){
e.preventDefault();
e.stopPropagation();
if (_this.hasClass('active')) {
_this.removeClass('active');
} else {
select.removeClass('active');
_this.addClass('active');
}
});
option.on('click', function(e){
e.preventDefault();
_this.addClass('selected');
let _thisOption = $(this),
value = _thisOption.text();
head.text(value);
option.removeClass('active');
_thisOption.addClass('active');
input.val(value);
});
});
$(document).on('click', function(){
select.removeClass('active');
});
}
});

@ -0,0 +1,24 @@
import $ from 'jquery';
$(document).ready(function () {
let tabs = $('.js-tabs');
if (tabs.length) {
tabs.each(function(){
let _this = $(this),
btn = _this.find('.js-tabs-btn'),
item = _this.find('.js-tabs-item');
btn.on('click', function(e){
e.preventDefault();
let _thisBtn = $(this),
index = _thisBtn.index();
btn.removeClass('active');
_thisBtn.addClass('active');
item.hide();
item.eq(index).fadeIn();
});
});
}
});

@ -0,0 +1,10 @@
import $ from 'jquery';
$(document).ready(function () {
$('.js-toggle-head').on('click', function(e){
e.preventDefault();
let _this = $(this);
_this.toggleClass('active');
_this.next().slideToggle();
});
});

@ -0,0 +1,58 @@
const webpack = require('webpack');
const path = require('path');
const NODE_ENV = process.env.NODE_ENV || 'development';
module.exports = {
entry: {
app: "./src/js/app.js"
},
output: {
path: path.join(__dirname, "build/js"),
filename: NODE_ENV === 'development' ? '[name].js' : '[name].[id].[chunkhash].js',
library: '[name]'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: [
["env", {
"targets": {
"browsers": ["last 2 versions", "safari >= 7"]
}
}]
]
}
}
}
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify(NODE_ENV)
}
})
],
watch: NODE_ENV === 'development',
devtool: NODE_ENV === 'development' ? 'source-map' : false
};
if (NODE_ENV === 'production') {
module.exports.plugins.push(
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_console: true,
unsafe: true
}
})
);
}
Loading…
Cancel
Save