CRM #
Добро пожаловать на финальный уровень — CRM! Это задание - уменьшенная копия реальных проектов, которыми разработчики занимаются за 300к в наносек на реальных работах. ТЗ здесь тоже приближено к тому, что дают в реальности: поверхностно описано ЧТО нужно сделать, а КАК решать уже разработчику.
О проекте #
Чему научишься #
- Роутинг. В этом проекте будет гораздо больше двух экранов и для удобного перехода между страницами нужно иметь инструмент навигации
- Работа с бэкендом. Для этого урока настроен сервер, прям как на реальной работе. На нем буду храниться данные, которые вы создаете на своем фронтенде.
- Авторизация и регистрация. CRM - закрытая система и она должна быть защищена от посторонних.
- Архитектура и декомпозиция. В одном из прошлых заданий я говорил, что структура folder-by-type плоха для больших проектов, в этом уроке мы рассмотрим альтернативу.
Материалы для подготовки #
Самостоятельный поиск других источников приветствуется
- Работа с API и данными
- REST API: для чего нужен и как работает
- Что такое CRUD
- Документация axios - HTTP-клиент для JS приложений. Де-факто стандарт фронтенд индустрии для работы с сетью.
- react-query
- Документация @tanstack/react-query - библиотека для удобного хранения и манипулирования данными на сервере с клиента.
- React Query за 10 минут
- react-query не является заменой локальным менеджерам состояний. Хоть в этой задаче бОльшая часть данных будет храниться на сервере, локальный стейт все же нужен. Выбор за тобой: redux-toolkit или классический redux
- Пять простых шагов для понимания JSON Web Tokens (JWT)
- Авторизация на JWT токенах - цикл коротких видео
- Как сделать приватные роуты в React. Имейте в виду, что в этом проекте мы не используем MobX и create-react-app, но статья от этого не является менее полезной.
- Postman - Это инструмент для удобной работы с API за пределами приложения
- Основы Postman
- Гайд с примерами. Актуально до параграфа “Создание тестов в Postman”
- Подход к стилизации выбери самостоятельно: БЭМ, CSS модули или tailwind.
- Feature-Sliced Design (FSD)
- Обзор архитектуры
- Документация
- Разбираемся в Feature-Sliced Design
- Cohesion и Coupling: отличия - статья, которая может лучше разобраться в проектировании, в отрыве от любой архитектуры
- Роутинг
- Общее
Техническое задание #
- Сделай форк репозитория https://github.com/Ospens/crm-app-template. В нем уже есть все нужные настойки, можно сразу писать приложение.
- Макет приложения
- IP сервера: 167.71.2.84
- Swagger: http://167.71.2.84/api-docs/
Базовый функционал #
- Адаптивный дизайн всего сайта
- Реализация авторизации и регистрации пользователей.
- Управление контактами, клиентами и сделками — добавление, редактирование, удаление и поиск. В соответствии с интерактивным дизайном.
- Фильтры и сортировки, примененные к таблицам, должны быть сохранены в параметры url. Например http://localhost:3000/deals?sort_by=name&order=asc. Открытие такой ссылки должно вести на страницу с активной сортировкой
Авторизация #
- Не авторизованный пользователь должен попадать на страницу логина.
- Описание формы логина
- Email - Обязательное строковое поле. Формат должен соответствовать формату email
- Password - Обязательное строковое поле. Минимум 6 символов
- В случае успешного ответа от бэкенда сессия должна быть сохранена в браузере, а пользователь перенаправлен в Dashboard
- В случае ошибки от бэкенда нужно отобразить текст ошибок в интерфейсе
- При нажатии на кнопку Sign up пользователь попадает на страницу регистрации.
Регистрация #
- Описание формы логина. Все поля обязательные
- First name - Обязательное строковое поле. Разрешены только буквы алфавита
- Last name - Обязательное строковое поле. Разрешены только буквы алфавита
- Email - Обязательное строковое поле. Формат должен соответствовать формату email
- Password - Обязательное строковое поле. Минимум 6 символов
- Repeat password - Обязательное строковое поле. Должна быть проверка на то, что пароли совпадают.
- В случае успешного ответа от бэкенда должен появиться тост об успехе, а пользователь перенаправлен на страницу логина
- В случае ошибки от бэкенда нужно отобразить текст ошибок в интерфейсе.
- При нажатии на кнопку Back пользователь попадает на страницу авторизации.
Dashboard (Главная) #
- Авторизованный пользователь должен попадать на страницу Dashboard.
- В Дашборде левый сайдбар с навигацией и правый с Клинтами и Задачами имеют статическую ширину. Область в центре адаптивна.
- Страницу Календаря делать не нужно. При нажатии на кнопку должна быть заглушка в соответствии с дизайном.
- Блок “Next Appointment” - это сделка, у которой статус in progress И Appointment Date еще не настало (в будущем) И Appointment Date ближе всего к текущему времени.
Deals (Сделки) #
- По нажатию на кнопку “Удалить” должен появляться диалог подтверждения “Do you really want to delete {deal.name}?”
- Описание формы сделки
- Customer - Обязательное поле. В запросе нужно отправлять id кастомера.
- Room Images - Обязательное файловое поле. Допустимые форматы: png, img. Максимальный размер: 1МБ. Максимум 5 файлов
- Address - Обязательные строковое поле. Поля City и State / Province должны содержать только заглавные и строчные буквы. Поле Zip Code должно содержать только цифры. Минимум 4 цифры, максимум - 8
- Room Area (m2) - Обязательные числовое поле. Минимальное значение 10, максимальное 9999.
- # of People - Необязательное числовое поле.
- Appointment Date - Необязательное поле даты. Формат: DD.MM.YYYY
- Special Instructions - Необязательное строковое поле.
- Room Access - Обязательные селект поле. Варианты значений приходят с бэкенда
- Price ($) - Обязательные числовое поле. Минимальное значение 100.
- Progress - Обязательные селект поле. Варианты значений приходят с бэкенда
- Описание формы активности (Record Activity)
- Description - Необязательное строковое поле.
- Date - Обязательные поле даты. Формат: DD.MM.YYYY hh:mm
- Images - Обязательное файловое поле. Допустимые форматы: png, img. Максимальный размер: 1МБ
- Описание таблицы
- Если данных в таблице нет - отображается заглушка “No deals found.”
- Кнопка “Load More” должна загружать следующую партию данных и добавлять в конец таблицы. Если загружена последняя страница с данными, то кнопка “Load More” не должна больше отображаться
- Если строки не вмещаются на экран, то скроллится должно только тело таблицы. Макет страницы, фильтры и хэдер таблицы должны оставаться на своих местах.
Customers (Клиенты) #
- По нажатию на кнопку “Удалить” должен появляться диалог подтверждения “Do you really want to delete {deal.name}?”
- Описание формы клиента
- Avatar - Обязательное файловое поле. Допустимые форматы: png, img. Максимальный размер: 1МБ. Максимум 1 файл
- First Name - Обязательное строковое поле.
- Last Name - Обязательное строковое поле.
- Email - Обязательное строковое поле. Формат должен соответствовать формату email
- Phone - Обязательное строковое поле. Формат должен соответствовать формату телефона твоей страны
- Address - Обязательные строковые поля. Поля City и State / Province должны содержать только заглавные и строчные буквы. Поле Zip Code должно содержать только цифры. Минимум 4 цифры, максимум - 8
- Описание страницы клиента
- В основном контенте все поля редактируемые. Если пользователь что-то изменил и убрал фокус с поля - изменения сохранятся автоматически.
- Правый сайдбар имеет фиксированную ширину. В нем отображаются последние ЗАВЕРШЕННЫЕ сделки клиента
- Если завершенных сделок еще нет - отображается заглушка “No deals found.”
- По клику на карандаш около аватара должно открываться проводник ОС, чтобы пользователь смог выбрать другую картинку. Если она подходит валидацию - обновить картинку. Если нет - показать тост с текстом ошибки.
- Описание таблицы
- Если данных в таблице нет - отображается заглушка “No customers found.”
- Кнопка “Load More” должна загружать следующую партию данных и добавлять в конец таблицы. Если загружена последняя страница с данными, то кнопка “Load More” не должна больше отображаться
- Если строки не вмещаются на экран, то скроллится должно только тело таблицы. Макет страницы, фильтры и хэдер таблицы должны оставаться на своих местах.
Tasks (задачи) #
- По нажатию на кнопку “Удалить” должен появляться диалог подтверждения “Do you really want to delete {deal.name}?”
- Описание формы задачи
- description - Обязательное текстовое поле.
- Due Date - Обязательные поле даты. Формат: DD.MM.YYYY hh:mm
- Complete? - Необязательное чекбокс поле. При создании задачи это поле не отображается
- Описание таблицы
- Первый столбец - статус. По нажатию на поля чекбокса должен переключаться статус completed у задачи. Если due date меньше текущей И задача не завершена, то вместо пустого чекбокса должен показываться красная иконка с восклицательным знаком, которую можно нажать и выполнить задачу.
- Второй столбец - Due date. Дедлайн задачи. Если due date меньше текущей И задача не завершена, то текст должен быть красным
- Третий столбец - описание задачи. Максимум одна строка. Если текст слишком длинный, то он должен обрезаться с помощью “…”
- Четвертый столбец - действия редактирования и удаления.
- Если данных в таблице нет - отображается заглушка “No tasks found.”
- Кнопка “Load More” должна загружать следующую партию данных и добавлять в конец таблицы. Если загружена последняя страница с данными, то кнопка “Load More” не должна больше отображаться
- Если строки не вмещаются на экран, то скроллится должно только тело таблицы. Макет страницы, фильтры и хэдер таблицы должны оставаться на своих местах.
Требования к коду #
- Используй архитектуру FSD
- Используй axios и react-query для работы с данными API
- Работа с формами должна осуществляться с помощью библиотеки react-hook-form
- В проекте должен быть настроен eslint и prettier и код должен соответствовать их конфигурации
Заметки #
Обратная связь и контакты #
По любым вопросам пиши мне, @i_urKing, и подписывайся на канал @js_is_easy