Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Level 3 #2

Merged
merged 34 commits into from
Sep 28, 2023
Merged

Level 3 #2

merged 34 commits into from
Sep 28, 2023

Conversation

maratdev
Copy link
Owner

No description provided.

maratdev added 28 commits August 28, 2023 17:15
Repository owner deleted a comment from gitguardian bot Sep 27, 2023
@irinamozes
Copy link

Резюме:

JavaScript

Критерии, влияющие на работоспособность

  • Функциональность проекта из брифа реализована полностью:
    • Общее

      • Все ссылки и кнопки в проекте работают.
      • Правильно работают оба состояния шапки: если пользователь не залогинился, в шапке должны быть кнопки «Войти» и «Регистрация»; если пользователь залогинился, кнопки исчезают — и появляются кнопки «Фильмы», «Сохранённые фильмы» и «Аккаунт», в том числе и на главной странице.
      • При поиске на странице фильмов текст запроса, найденные фильмы и состояние переключателя короткометражек сохраняются в хранилище. Если пользователь повторно переходит на страницу фильмов, то при монтировании компонента данные достаются из локального хранилища. Страница отображается в соответствии с загруженными из хранилища данными.
      • Все формы валидируются и на стороне клиента. Пользователь не может отправить запрос с невалидными данными.
    • Страницы «Регистрация» и «Авторизация»:

      • На странице «Регистрация» клик по кнопке «Зарегистрироваться» отправляет запрос на роут /signup, если данные введены корректно. Если запрос прошёл успешно, то автоматически производится вход и редирект на страницу /movies.
      • На странице «Авторизация» клик по кнопке «Войти» отправляет запрос на роут /signin, если данные введены корректно. Если запрос прошёл успешно, происходит редирект на страницу /movies.
      • Все формы валидируются и на стороне клиента.
    • Страница редактирование профиля:

      • На странице редактирования профиля клик по кнопке «Сохранить» отправляет запрос на роут /users/me, если данные введены корректно.
      • Пользователю отображается уведомление об успешном запросе к серверу при сохранении профиля.
      • Если на странице редактирования профиля введённая информация соответствует текущим данным пользователя, кнопка «Сохранить» заблокирована и нельзя отправить запрос сохранения.
        Комментарий: пользователь может сохранить текущие данные профиля, не изменяя их: хотя и выдаётся сообщение "Данные не сохранены: Вы не изменяли данные", успешный запрос на сервер всё равно происходит. А нужно сделать так, чтобы можно было отправить запрос на сохранение, только если данные изменены по сравнению с текущими данными пользователя, которые должны содержаться в текущий момент в стейте и в контексте.

      Напоминание: после каждого успешного сохранения данных профиля на сервере, нужно эти данные вносить в контекст юзера.

      Напоминание: Чтобы данные профиля считались изменёнными, пользователю должно быть достаточно изменения хотя бы одного данного. Может быть изменён один любой инпут из двух, и отправлен запрос на сервер.

    • Поиск фильмов:

      • Прелоадер крутится во время выполнения запроса фильмов.
      • Работа с фильтром настроена:
        • Поиск фильмов регистронезависимый.
        • Если запрос выполняется впервые, то работа с фильтром происходит после получения данных.
        • Если карточки уже были отображены на странице в блоке результатов, клик по чекбоксу «Короткометражки» приводит к повторной фильтрации результата.
          Комментарий: При выводе результата поиска при передвижении чекбокса, без нажатия кнопки "Поиск" на форме поиска, должен работать тот же алгоритм, который работает при сабмите формы поиска, то есть работает при нажатии кнопки "Поиск". Таким образом, при передвижении чекбокса для получения результата поиска должен производиться новый фильтр всего массива фильмов по заданной в текущий момент строке поиска в форме поиска и положению самого чекбокса. Сейчас при передвижении чекбокса для вывода результата берётся строка поиска, которая была при предыдущем поиске, а не та, которая находится в текущий момент в форме поиска, что в определённых случаях приводит к показу неверного результата (см. снимок). Сделайте в соответствии с этим замечанием и алгоритм поиска на странице «Сохранённые фильмы».
          Снимок экрана в 2023-09-27 17-07-53
      • После успешного сабмита формы поиска появляется блок с результатами.
      • Если ничего не найдено, выводится надпись «Ничего не найдено».
    • На странице всех фильмов в блоке результата отображается такое же количество карточек, как в макете. Нажатие на кнопку «Ещё» отображает следующий ряд с тем же числом карточек. При отображении всех карточек кнопка "Ещё" скрывается.
      Комментарий: Вывод карточек на экран не соответствует постановке задачи, данной в описании диплома, хотя бы потому, что на экран всегда должны выводиться одинаковые по количеству карточек ряды карточек ( возможно, кроме последнего ряда), а сейчас это не так (см. снимок при ширене экрана 840px). Нужно исправить функционал вывода, как требуется в текущем пункте чек-листа и в описании задания.
      Снимок экрана в 2023-09-27 16-59-49
      Ориентироваться нужно на описание этого функционала, которое дано в задании по диплому:

Обратите внимание, что количество карточек, которые отображаются на странице, зависит от ширины экрана устройства.
• Ширина 1280px — 4 ряда карточек. Кнопка «Ещё» загружает дополнительный ряд карточек.
• Ширина 768px — 4 ряда карточек. Кнопка «Ещё» загружает ряд карточек.
• Ширина от 320px до 480px — 5 карточек по 1 в ряд. Кнопка «Ещё» загружает по 2 карточки.
В ряду отображайте столько карточек, сколько отображается в вашем макете на соответствующей ширине экрана.

  • Карточки:
    • Карточка состоит из изображения, названия фильма и его длительности. Длительность фильма рассчитывается корректно и соответствует формату в макете. Клик по карточке ведёт на трейлер фильма.
    • Кнопка лайка имеет правильное состояние, в зависимости от того, добавлен ли фильм в сохранённые или нет.
    • При клике на иконку «Лайк» в блоке карточки выполняется запрос к /movies нашего API для установки или снятия лайка, в зависимости от текущего состояния.
  • На странице «Сохранённые фильмы»:
    • Отображается форма поиска. Она позволяет искать фильмы по уже полученным данным о сохранённых фильмах.
    • Блок карточки содержит кнопку удаления, а не лайка.
    • При нажатии на кнопку удаления выполняется запрос на удаление фильма. После успешного запроса карточка удаляется со страницы.
  • Отсутствуют серьёзные баги, которые возникают при работе с сервисом, например:
    • Удалённые или добавленные карточки фильмов появляются только после перезагрузки страницы.
    • Если осталось отобразить меньше карточек фильмов, чем в полном ряду, то нажатие кнопки «Ещё» вызывает появление ошибок в консоли.
    • При удалении сохранённых карточек на соответствующей странице «Сохранённые фильмы» их по-прежнему можно найти через поиск. Поиск начинает корректно работать только после перезагрузки страницы.
    • Другие баги, которые возникают при работе с сервисом и требуют перезагрузки страницы или «ломают» пользовательский опыт.
  • Регистрация и авторизация:
    • Роуты /saved-movies, /movies, /profile защищёны HOC-компонентом ProtectedRoute. Роуты / , /signin, /signup не являются защищёнными.
    • При попытке перейти на любой защищённый роут происходит редирект на / .
    • Если пользователь был авторизован и закрыл вкладку, он может вернуться сразу на любую страницу приложения по URL-адресу, кроме страниц авторизации и регистрации.
    • После успешного вызова обработчика onSignOut происходит редирект на /.
    • Корректно используется хук useHistory.
    • При попытке перейти на несуществующую страницу происходит редирект на страницу «404». Кнопка «Назад» работает корректно.
    • Корректно используются компоненты <Switch />, <Route /> и <Redirect />.
  • Работа с JWT выполнена корректно:
    • JWT-токен хранится в localStorage или в cookie;
    • Jwt проверяется запросом к серверу, а не только в локальном хранилище.
    • При выходе из аккаунта jwt удаляется.
  • Хуки:
    • Хуки не используются внутри условных блоков или циклов.
    • Хуки вызываются в основной функции компонента.
    • При использовании классовых компонентов эффекты описаны внутри методов жизненного цикла компонента.
    • Имена пользовательских хуков начинаются с use.
  • Контекст:
    • В корневом компоненте App создана стейт-переменная, которая хранит данные пользователя. Она используется в качестве значения для провайдера контекста.
    • В компонент App внедрён контекст через CurrentUserContext.Provider.
    • Компоненты, в которых используются данные профиля, подписаны на контекст.
  • Асинхронные запросы к API:
    • Запросы можно осуществлять через Fetch API или XMLHttpRequest, сторонние библиотеки, такие как axios или jQuery, не применяются.
    • Запросы к API вынесены в отдельные файлы: MainApi.js и MoviesApi.js.
    • Первый обработчик then возвращает res.json. res проверяется на корректность.
    • Цепочка обработки промисов завершается блоком catch.
    • Не выполняются лишние запросы к бэкенду, например: запрос всех фильмов с сервиса beatfilm-movies производится только при первом поиске; все сохранённые фильмы не запрашиваются с сервера при каждом лайке или дизлайке; данные пользователя запрашиваются один раз при запуске приложения.
  • Именование:
    • имена переменных, функций и параметров написаны в camelCase;
    • имена переменных — существительные;
    • имена переменных, функций и компонентов соответствуют содержимому;
    • имена коллекций NodeList — существительные во множественном числе;
    • имя функции начинается с глагола и отражает то, что она делает;
    • для именования запрещены: транслит и неуместные сокращения.

Хорошие практики

  • Начальное состояние стейт-переменных содержит корректный тип данных.
  • Для элементов списка используется уникальный ключ key, а не индекс массива.
  • Запросы к API описаны внутри компонента App или в корневых компонентах страниц.
  • Для внутренних ссылок в приложении используются компоненты из библиотеки react-router.
  • Не происходит утечки памяти при навешивании обработчиков. Все обработчики, добавленные через addEventListener, удаляются при размонтировании компонента.
  • Обработка ошибок API:
    • пользователь получает сообщение в случае любой ошибки;
    • поля формы заблокированы во время отправки запросов и у пользователя нет возможности отправить новый запрос до завершения предыдущего.
  • Фиксированные значения (константы) именуются заглавными буквами и вынесены в отдельный конфиг-файл.

Рекомендации

  • Сторонние JavaScript-библиотеки не применяются.
  • Используются семантически правильные блоки для компонентов. Не используются div или иные лишние HTML-тэги для компонентов, которые состоят из одноуровневых блоков.
  • Отсутствует «мусор» в коде:
    • нет беспорядка в коде;
    • нет лишнего кода: переменная объявлена, но не используется или есть какая-то лишняя логика;
    • код форматирован одинаково, соблюдается иерархия отступов.

Количество баллов: 61.

P.S.
Все исправления кода должны быть видны в коммитах в репозитории. На исправление каждой ошибки должен быть отдельный коммит. Сделайте, пожалуйста, у каждого коммита понятное название, говорящее, что коммит исправляет.

Repository owner deleted a comment from gitguardian bot Sep 27, 2023
@gitguardian

This comment was marked as spam.

@irinamozes
Copy link

Резюме:

JavaScript

Критерии, влияющие на работоспособность

  • Функциональность проекта из брифа реализована полностью:
    • Общее
      • Все ссылки и кнопки в проекте работают.
      • Правильно работают оба состояния шапки: если пользователь не залогинился, в шапке должны быть кнопки «Войти» и «Регистрация»; если пользователь залогинился, кнопки исчезают — и появляются кнопки «Фильмы», «Сохранённые фильмы» и «Аккаунт», в том числе и на главной странице.
      • При поиске на странице фильмов текст запроса, найденные фильмы и состояние переключателя короткометражек сохраняются в хранилище. Если пользователь повторно переходит на страницу фильмов, то при монтировании компонента данные достаются из локального хранилища. Страница отображается в соответствии с загруженными из хранилища данными.
      • Все формы валидируются и на стороне клиента. Пользователь не может отправить запрос с невалидными данными.
    • Страницы «Регистрация» и «Авторизация»:
      • На странице «Регистрация» клик по кнопке «Зарегистрироваться» отправляет запрос на роут /signup, если данные введены корректно. Если запрос прошёл успешно, то автоматически производится вход и редирект на страницу /movies.
      • На странице «Авторизация» клик по кнопке «Войти» отправляет запрос на роут /signin, если данные введены корректно. Если запрос прошёл успешно, происходит редирект на страницу /movies.
      • Все формы валидируются и на стороне клиента.
    • Страница редактирование профиля:
      • На странице редактирования профиля клик по кнопке «Сохранить» отправляет запрос на роут /users/me, если данные введены корректно.
      • Пользователю отображается уведомление об успешном запросе к серверу при сохранении профиля.
      • Если на странице редактирования профиля введённая информация соответствует текущим данным пользователя, кнопка «Сохранить» заблокирована и нельзя отправить запрос сохранения.
    • Поиск фильмов:
      • Прелоадер крутится во время выполнения запроса фильмов.
      • Работа с фильтром настроена:
        • Поиск фильмов регистронезависимый.
        • Если запрос выполняется впервые, то работа с фильтром происходит после получения данных.
        • Если карточки уже были отображены на странице в блоке результатов, клик по чекбоксу «Короткометражки» приводит к повторной фильтрации результата.
      • После успешного сабмита формы поиска появляется блок с результатами.
      • Если ничего не найдено, выводится надпись «Ничего не найдено».
    • На странице всех фильмов в блоке результата отображается такое же количество карточек, как в макете. Нажатие на кнопку «Ещё» отображает следующий ряд с тем же числом карточек. При отображении всех карточек кнопка "Ещё" скрывается.
    • Карточки:
      • Карточка состоит из изображения, названия фильма и его длительности. Длительность фильма рассчитывается корректно и соответствует формату в макете. Клик по карточке ведёт на трейлер фильма.
      • Кнопка лайка имеет правильное состояние, в зависимости от того, добавлен ли фильм в сохранённые или нет.
      • При клике на иконку «Лайк» в блоке карточки выполняется запрос к /movies нашего API для установки или снятия лайка, в зависимости от текущего состояния.
    • На странице «Сохранённые фильмы»:
      • Отображается форма поиска. Она позволяет искать фильмы по уже полученным данным о сохранённых фильмах.
      • Блок карточки содержит кнопку удаления, а не лайка.
      • При нажатии на кнопку удаления выполняется запрос на удаление фильма. После успешного запроса карточка удаляется со страницы.
  • Отсутствуют серьёзные баги, которые возникают при работе с сервисом, например:
    • Удалённые или добавленные карточки фильмов появляются только после перезагрузки страницы.
    • Если осталось отобразить меньше карточек фильмов, чем в полном ряду, то нажатие кнопки «Ещё» вызывает появление ошибок в консоли.
    • При удалении сохранённых карточек на соответствующей странице «Сохранённые фильмы» их по-прежнему можно найти через поиск. Поиск начинает корректно работать только после перезагрузки страницы.
    • Другие баги, которые возникают при работе с сервисом и требуют перезагрузки страницы или «ломают» пользовательский опыт.
  • Регистрация и авторизация:
    • Роуты /saved-movies, /movies, /profile защищёны HOC-компонентом ProtectedRoute. Роуты / , /signin, /signup не являются защищёнными.
    • При попытке перейти на любой защищённый роут происходит редирект на / .
    • Если пользователь был авторизован и закрыл вкладку, он может вернуться сразу на любую страницу приложения по URL-адресу, кроме страниц авторизации и регистрации.
    • После успешного вызова обработчика onSignOut происходит редирект на /.
    • Корректно используется хук useHistory.
    • При попытке перейти на несуществующую страницу происходит редирект на страницу «404». Кнопка «Назад» работает корректно.
    • Корректно используются компоненты <Switch />, <Route /> и <Redirect />.
  • Работа с JWT выполнена корректно:
    • JWT-токен хранится в localStorage или в cookie;
    • Jwt проверяется запросом к серверу, а не только в локальном хранилище.
    • При выходе из аккаунта jwt удаляется.
  • Хуки:
    • Хуки не используются внутри условных блоков или циклов.
    • Хуки вызываются в основной функции компонента.
    • При использовании классовых компонентов эффекты описаны внутри методов жизненного цикла компонента.
    • Имена пользовательских хуков начинаются с use.
  • Контекст:
    • В корневом компоненте App создана стейт-переменная, которая хранит данные пользователя. Она используется в качестве значения для провайдера контекста.
    • В компонент App внедрён контекст через CurrentUserContext.Provider.
    • Компоненты, в которых используются данные профиля, подписаны на контекст.
  • Асинхронные запросы к API:
    • Запросы можно осуществлять через Fetch API или XMLHttpRequest, сторонние библиотеки, такие как axios или jQuery, не применяются.
    • Запросы к API вынесены в отдельные файлы: MainApi.js и MoviesApi.js.
    • Первый обработчик then возвращает res.json. res проверяется на корректность.
    • Цепочка обработки промисов завершается блоком catch.
    • Не выполняются лишние запросы к бэкенду, например: запрос всех фильмов с сервиса beatfilm-movies производится только при первом поиске; все сохранённые фильмы не запрашиваются с сервера при каждом лайке или дизлайке; данные пользователя запрашиваются один раз при запуске приложения.
  • Именование:
    • имена переменных, функций и параметров написаны в camelCase;
    • имена переменных — существительные;
    • имена переменных, функций и компонентов соответствуют содержимому;
    • имена коллекций NodeList — существительные во множественном числе;
    • имя функции начинается с глагола и отражает то, что она делает;
    • для именования запрещены: транслит и неуместные сокращения.

Хорошие практики

  • Начальное состояние стейт-переменных содержит корректный тип данных.
  • Для элементов списка используется уникальный ключ key, а не индекс массива.
  • Запросы к API описаны внутри компонента App или в корневых компонентах страниц.
  • Для внутренних ссылок в приложении используются компоненты из библиотеки react-router.
  • Не происходит утечки памяти при навешивании обработчиков. Все обработчики, добавленные через addEventListener, удаляются при размонтировании компонента.
  • Обработка ошибок API:
    • пользователь получает сообщение в случае любой ошибки;
      Комментарий: нет сообщения при попытке пользователя сохранить адрес почты в ЛК, который уже зарегистрирован другим пользователем.
    • поля формы заблокированы во время отправки запросов и у пользователя нет возможности отправить новый запрос до завершения предыдущего.
  • Фиксированные значения (константы) именуются заглавными буквами и вынесены в отдельный конфиг-файл.
    Комментарий: длительность короткометражек - число 40, нужно занести в константу с понятным названием и поместить в файл констант, чтобы в коде не было "магических" значений. Смысл литеральных числовых значений (таких как 40, или любых других чисел), встречающихся в коде, не возможно понять, если их не занести в константы с "говорящим названием" и использовать вместо них эти константы в коде. Поэтому числа и называются "магическими" значениями.

Рекомендации

  • Сторонние JavaScript-библиотеки не применяются.
  • Используются семантически правильные блоки для компонентов. Не используются div или иные лишние HTML-тэги для компонентов, которые состоят из одноуровневых блоков.
  • Отсутствует «мусор» в коде:
    • нет беспорядка в коде;
    • нет лишнего кода: переменная объявлена, но не используется или есть какая-то лишняя логика;
    • код форматирован одинаково, соблюдается иерархия отступов.

Количество баллов: 98.

У Вас отличный дипломный проект!

Чтобы красиво оформить файл README.md, где рассказать о собственной работе над проектом и собственных достижениях, можно воспользоваться инструментом Markdown. Описание языка Markdown есть в Ваших лекциях по этой ссылке:
https://praktikum.yandex.ru/learn/web/courses/dbf98e55-0f76-444b-850c-4538708ad571/sprints/1425/topics/b4072eed-2089-45c0-9382-98ea71202341/lessons/939aeab7-0508-49e8-bcf2-199d4dbf74f7/.

Ссылки на интересные материалы и подкасты:
habr
https://soundcloud.com/everyonecan
https://soundcloud.com/podlodka
https://soundcloud.com/devschacht
https://soundcloud.com/begebot
https://soundcloud.com/web-standards
https://www.youtube.com/channel/UCZeU17nbVfzczAkJVTay9vw

Интересная статья о замыкании и лексическом окружении функций:
https://developer.mozilla.org/ru/docs/Web/JavaScript/Closures.

О пользовательских хуках:
https://ru.reactjs.org/docs/hooks-custom.html

https://reactdev.ru/
Справочник React

Какие бывают стили в названиях файлов js и зачем они нужны, интересно и кратко написано здесь:
https://medium.com/@alivander/camel-pascal-snake-case-и-другие-стили-написания-288ec62ca0d0

Ресурс по библиотеке Redux, которая очень широко используется в реальных проектах на React:
https://rajdee.gitbooks.io/redux-in-russian/content/

Создание приложений JavaScript с помощью TypeScript
https://docs.microsoft.com/ru-ru/learn/paths/build-javascript-applications-typescript/

Руководство Typescript
http://typescript-lang.ru/docs/

TypeScript в деталях.
https://typescript-definitive-guide.ru/book/chapters

Желаю дальнейших творческих успехов, экспертных знаний и удачи!

@maratdev maratdev merged commit d05cd50 into main Sep 28, 2023
1 check failed
@maratdev maratdev deleted the level-3 branch September 28, 2023 14:14
maratdev pushed a commit that referenced this pull request Oct 2, 2023
maratdev added a commit that referenced this pull request Oct 2, 2023
maratdev pushed a commit that referenced this pull request Oct 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants