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 30 commits into from
Jul 24, 2023
Merged

Level 3 #2

merged 30 commits into from
Jul 24, 2023

Conversation

MariaZlnva
Copy link
Owner

Здравствуйте. Реализована основная функциональность сайта.

@irinamozes
Copy link

Резюме:

JavaScript

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

  • Функциональность проекта из брифа реализована полностью:
    • Общее
      • Все ссылки и кнопки в проекте работают.
      • Правильно работают оба состояния шапки: если пользователь не залогинился, в шапке должны быть кнопки «Войти» и «Регистрация»; если пользователь залогинился, кнопки исчезают — и появляются кнопки «Фильмы», «Сохранённые фильмы» и «Аккаунт», в том числе и на главной странице.
      • При поиске на странице фильмов текст запроса, найденные фильмы и состояние переключателя короткометражек сохраняются в хранилище. Если пользователь повторно переходит на страницу фильмов, то при монтировании компонента данные достаются из локального хранилища. Страница отображается в соответствии с загруженными из хранилища данными.
      • Все формы валидируются и на стороне клиента. Пользователь не может отправить запрос с невалидными данными.
    • Страницы «Регистрация» и «Авторизация»:
      • На странице «Регистрация» клик по кнопке «Зарегистрироваться» отправляет запрос на роут /signup, если данные введены корректно. Если запрос прошёл успешно, то автоматически производится вход и редирект на страницу /movies.
      • На странице «Авторизация» клик по кнопке «Войти» отправляет запрос на роут /signin, если данные введены корректно. Если запрос прошёл успешно, происходит редирект на страницу /movies.
      • Все формы валидируются и на стороне клиента.
    • Страница редактирование профиля:
      • На странице редактирования профиля клик по кнопке «Сохранить» отправляет запрос на роут /users/me, если данные введены корректно.
        Комментарий: На странице профиля при попытке пользователя сохранить адрес почты, который принадлежит другому пользователю, сервер приложения присылает в ответе ошибку 500. Но, если почта уже была зарегистрирована другим пользователем, сервер приложения должен присылать ошибку 409 в ответе, пользователю нужно выдать об этом сообщение.
      • Пользователю отображается уведомление об успешном запросе к серверу при сохранении профиля.
      • Если на странице редактирования профиля введённая информация соответствует текущим данным пользователя, кнопка «Сохранить» заблокирована и нельзя отправить запрос сохранения.
    • Поиск фильмов:
      • Прелоадер крутится во время выполнения запроса фильмов.
      • Работа с фильтром настроена:
        • Поиск фильмов регистронезависимый.
        • Если запрос выполняется впервые, то работа с фильтром происходит после получения данных.
        • Если карточки уже были отображены на странице в блоке результатов, клик по чекбоксу «Короткометражки» приводит к повторной фильтрации результата.
      • После успешного сабмита формы поиска появляется блок с результатами.
      • Если ничего не найдено, выводится надпись «Ничего не найдено».
        Комментарий: Надпись "Ничего не найдено." присутствует на странице фильмов сразу же при входе, когда пользователь ещё ничего не искал, а не только когда ничего не найдено.
    • На странице всех фильмов в блоке результата отображается такое же количество карточек, как в макете. Нажатие на кнопку «Ещё» отображает следующий ряд с тем же числом карточек. При отображении всех карточек кнопка "Ещё" скрывается.
      Комментарий: карточки из результата поиска отображаются сразу все, а не по одному ряду при нажатии кнопки «Ещё».
    • Карточки:
      • Карточка состоит из изображения, названия фильма и его длительности. Длительность фильма рассчитывается корректно и соответствует формату в макете. Клик по карточке ведёт на трейлер фильма.
      • Кнопка лайка имеет правильное состояние, в зависимости от того, добавлен ли фильм в сохранённые или нет.
      • При клике на иконку «Лайк» в блоке карточки выполняется запрос к /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-тэги для компонентов, которые состоят из одноуровневых блоков.
  • Отсутствует «мусор» в коде:
    • нет беспорядка в коде;
    • нет лишнего кода: переменная объявлена, но не используется или есть какая-то лишняя логика;
    • код форматирован одинаково, соблюдается иерархия отступов.

Доп. Комментарии:

Комментарий: Если у пользователя есть сохранённые фильмы, при переходе на страницу «Сохранённые фильмы» надо выводить на экран все сохранённые карточки, так как пользователь может не помнить, какие фильмы он сохранял, и не найти их. Нужно, чтобы при входе на эту страницу пользователь видел все свои избранные фильмы без задания параметров поиска, а не результат какого-либо поиска. Сохранять данные последнего поиска на странице «Сохранённые фильмы» нет необходимости.

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

2 балла снято за замечание из комментария в разделе "Доп. Комментарии".

@MariaZlnva
Copy link
Owner Author

Здравствуйте. Исправлены замечания.

@irinamozes
Copy link

Резюме:

JavaScript

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

  • Функциональность проекта из брифа реализована полностью:
    • Общее
      • Все ссылки и кнопки в проекте работают.
      • Правильно работают оба состояния шапки: если пользователь не залогинился, в шапке должны быть кнопки «Войти» и «Регистрация»; если пользователь залогинился, кнопки исчезают — и появляются кнопки «Фильмы», «Сохранённые фильмы» и «Аккаунт», в том числе и на главной странице.
      • При поиске на странице фильмов текст запроса, найденные фильмы и состояние переключателя короткометражек сохраняются в хранилище. Если пользователь повторно переходит на страницу фильмов, то при монтировании компонента данные достаются из локального хранилища. Страница отображается в соответствии с загруженными из хранилища данными.
      • Все формы валидируются и на стороне клиента. Пользователь не может отправить запрос с невалидными данными.
    • Страницы «Регистрация» и «Авторизация»:
      • На странице «Регистрация» клик по кнопке «Зарегистрироваться» отправляет запрос на роут /signup, если данные введены корректно. Если запрос прошёл успешно, то автоматически производится вход и редирект на страницу /movies.
      • На странице «Авторизация» клик по кнопке «Войти» отправляет запрос на роут /signin, если данные введены корректно. Если запрос прошёл успешно, происходит редирект на страницу /movies.
      • Все формы валидируются и на стороне клиента.
    • Страница редактирование профиля:
      • На странице редактирования профиля клик по кнопке «Сохранить» отправляет запрос на роут /users/me, если данные введены корректно.
      • Пользователю отображается уведомление об успешном запросе к серверу при сохранении профиля.
      • Если на странице редактирования профиля введённая информация соответствует текущим данным пользователя, кнопка «Сохранить» заблокирована и нельзя отправить запрос сохранения.
    • Поиск фильмов:
      • Прелоадер крутится во время выполнения запроса фильмов.
      • Работа с фильтром настроена:
        • Поиск фильмов регистронезависимый.
        • Если запрос выполняется впервые, то работа с фильтром происходит после получения данных.
        • Если карточки уже были отображены на странице в блоке результатов, клик по чекбоксу «Короткометражки» приводит к повторной фильтрации результата.
      • После успешного сабмита формы поиска появляется блок с результатами.
      • Если ничего не найдено, выводится надпись «Ничего не найдено».
    • На странице всех фильмов в блоке результата отображается такое же количество карточек, как в макете. Нажатие на кнопку «Ещё» отображает следующий ряд с тем же числом карточек. При отображении всех карточек кнопка "Ещё" скрывается.
    • Карточки:
      • Карточка состоит из изображения, названия фильма и его длительности. Длительность фильма рассчитывается корректно и соответствует формату в макете. Клик по карточке ведёт на трейлер фильма.
      • Кнопка лайка имеет правильное состояние, в зависимости от того, добавлен ли фильм в сохранённые или нет.
      • При клике на иконку «Лайк» в блоке карточки выполняется запрос к /movies нашего API для установки или снятия лайка, в зависимости от текущего состояния.
    • На странице «Сохранённые фильмы»:
      • Отображается форма поиска. Она позволяет искать фильмы по уже полученным данным о сохранённых фильмах.
      • Блок карточки содержит кнопку удаления, а не лайка.
      • При нажатии на кнопку удаления выполняется запрос на удаление фильма. После успешного запроса карточка удаляется со страницы.
  • Отсутствуют серьёзные баги, которые возникают при работе с сервисом, например:
    • Удалённые или добавленные карточки фильмов появляются только после перезагрузки страницы.
    • Если осталось отобразить меньше карточек фильмов, чем в полном ряду, то нажатие кнопки «Ещё» вызывает появление ошибок в консоли.
    • При удалении сохранённых карточек на соответствующей странице «Сохранённые фильмы» их по-прежнему можно найти через поиск. Поиск начинает корректно работать только после перезагрузки страницы.
    • Другие баги, которые возникают при работе с сервисом и требуют перезагрузки страницы или «ломают» пользовательский опыт.
  • Регистрация и авторизация:
    • Роуты /saved-movies, /movies, /profile защищёны HOC-компонентом ProtectedRoute. Роуты / , /signin, /signup не являются защищёнными.
    • При попытке перейти на любой защищённый роут происходит редирект на / .
    • Если пользователь был авторизован и закрыл вкладку, он может вернуться сразу на любую страницу приложения по URL-адресу, кроме страниц авторизации и регистрации.
      Комментарий: При попытке авторизованного пользователя войти на любую страницу по её 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:
    • пользователь получает сообщение в случае любой ошибки;
    • поля формы заблокированы во время отправки запросов и у пользователя нет возможности отправить новый запрос до завершения предыдущего.
      Комментарий: При запросах на авторизацию и регистрацию, разблокировать формы нужно только в блоке catch, а не в finally. Иначе, после завершения успешного запроса, можно ещё раз успеть послать новый запрос перед переходом на страницу фильмов.
  • Фиксированные значения (константы) именуются заглавными буквами и вынесены в отдельный конфиг-файл.

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

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

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

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

Чтобы красиво оформить файл 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

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

@MariaZlnva
Copy link
Owner Author

MariaZlnva commented Jul 9, 2023

Ирина, статус в личном кабинете по проверке проекта "есть замечания- кое что нужно поправить "
Нужно еще отправить на проверку после доработки? Или позднее статус поменяется на "принято"?

@irinamozes
Copy link

irinamozes commented Jul 9, 2023

@MariaZlnva
Здравствуйте, Мария!
Я , видимо, по ошибке поставила к работе не тот статус. Извините. Работа принята. Пришлите, пожалуйста, проект, как на следующую проверку, и я выставлю ей правильный статус "Работа принята".

@MariaZlnva
Copy link
Owner Author

Отправила.

@MariaZlnva MariaZlnva merged commit a7b7ef2 into main Jul 24, 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