diff --git a/README.md b/README.md index 760e1c5..e9f5d60 100644 --- a/README.md +++ b/README.md @@ -1,442 +1,166 @@ -# Nashel Frontend +# ✨ Nashel — Frontend -Фронтенд для маркетплейса услуг "Nashel" — современное веб-приложение на Next.js для поиска мастеров и исполнителей. +> **Next.js 15 · TypeScript · React · TailwindCSS · Shadcn/UI** -## 🏗️ Архитектура +Клиентская часть платформы **Nashel** — маркетплейса для поиска и найма профессиональных исполнителей. Реализован как современное SPA/SSR приложение с тёмной темой, интерактивной картой и богатым UX. -Проект построен на **Feature-Sliced Design (FSD)** архитектуре: +--- + +## 🎯 Какую проблему решает Nashel + +Клиенты тратят часы на поиск надёжных мастеров. Исполнители теряют заказы из-за отсутствия нормального онлайн-присутствия. + +**Nashel** соединяет их мгновенно: +- Ищи мастера прямо на карте рядом с домом +- Смотри фото работ, цены и описание услуги +- Нажми одну кнопку — и выйди на связь с исполнителем + +--- + +## 👤 Роли пользователей + +| Роль | Возможности | +|------|-------------| +| **Клиент** | Поиск услуг, просмотр профилей, карта | +| **Кандидат в мастера** | Личный кабинет, создание профиля исполнителя | +| **Мастер** | Полный кабинет: управление услугами, расписание, статус | +| **Компания** | Расширенный кабинет с представлением от юрлица | + +--- + +## 🗂️ Структура проекта ``` -nashel-frontend/ -├── src/ -│ ├── app/ # Next.js App Router (страницы и роутинг) -│ ├── entities/ # Бизнес-сущности (User, Session, Order) -│ ├── features/ # Бизнес-фичи (Auth, Orders, Map) -│ ├── widgets/ # Составные виджеты (Header, Footer) -│ ├── shared/ # Общий код (UI, lib, api) -│ ├── components/ # Переиспользуемые UI-компоненты -│ └── lib/ # Утилиты и хелперы -├── public/ # Статические файлы -└── tests/ # Тесты +src/ +├── app/ # Страницы (Next.js App Router) +│ ├── (auth)/ # Регистрация, вход +│ ├── dashboard/ # Личный кабинет исполнителя +│ │ ├── offers/ # Управление услугами: список, создание, редактирование +│ │ ├── profile/ # Профиль, аватар, локация, расписание, компетенции +│ │ └── settings/ # Настройки аккаунта +│ ├── offers/[id]/ # Публичная страница просмотра услуги +│ ├── search/ # Поиск услуг + карта +│ └── layout.tsx # Общий layout с навигацией +│ +├── components/ # Переиспользуемые компоненты +│ ├── ui/ # Shadcn UI компоненты (Button, Card, Dialog и т.д.) +│ ├── ImageUploader/ # Компонент загрузки, перетаскивания и удаления фото +│ └── ... +│ +└── shared/ + ├── api/ # Функции для обращения к API (catalog, search, auth) + └── store/ # Zustand: геолокация пользователя ``` -### FSD Слои +--- -- **app** — страницы и роутинг приложения -- **entities** — бизнес-сущности (User, Session) -- **features** — бизнес-фичи (Auth, Orders) -- **widgets** — составные виджеты (Header, Footer) -- **shared** — общий код (UI-компоненты, утилиты) -- **pages** — страницы (интеграция виджетов и фич) -- **processes** — бизнес-процессы (в планах) +## ✅ Что реализовано -## 🚀 Технологический стек +### Аутентификация +- Регистрация и вход (JWT в localStorage) +- Защищённые маршруты +- Сохранение сессии -- **Next.js 15** — React фреймворк с App Router -- **TypeScript** — типизация -- **Tailwind CSS** — стилизация -- **shadcn/ui** — UI компоненты -- **Zustand** — state management -- **React Hook Form** — формы -- **Zod** — валидация -- **Axios** — HTTP клиент -- **React Easy Crop** — кроп изображений -- **Lucide React** — иконки -- **Sonner** — уведомления (toasts) -- **next-themes** — темная тема +### Карта и поиск +- Интерактивная карта на `React Leaflet` (без SSR) +- Поиск по **названию услуги**, **описанию** и **компетенциям** +- Результаты поиска появляются по мере ввода (от 2 символов) +- Маркеры исполнителей на карте с всплывающими подсказками +- Отображение расстояния до исполнителя (м/км) +- Сортировка: «Идеально подходят», «Ближайшие», «Лучший рейтинг» +- Фильтры поиска: по названию, описанию, компетенциям +- Отображение услуги **приоритетнее** исполнителя (если нашлась услуга — исполнитель отдельно не показывается) -## 📦 Установка и запуск +### Карточка услуги в поиске +- Большое фото с hover-анимацией (scale + fade) +- Цена в рублях (₽), расстояние с иконкой +- Краткое описание услуги +- Роль и статус исполнителя (Мастер / Кандидат в мастера / Компания) +- Кнопка «Просмотреть услугу» — открывает страницу в новой вкладке -### Требования +### Публичная страница услуги (`/offers/[id]`) +- Большой блок с фото-галереей (карусель): + - Навигация мышью (стрелки видны при наведении) + - Навигация клавишами ← → + - Счётчик фото (1/N) + - Превью-ряд внизу (миниатюры) с кольцевой подсветкой активного +- Блок описания с аккуратным заголовком +- Блок характеристик услуги (атрибуты ключ-значение) — под описанием +- Правая колонка: карточка исполнителя (имя, роль, рейтинг, документы) +- Блок «Готовы заказать?» с кнопкой «Связаться с исполнителем» +- Блок похожих услуг из категории (заглушка, готовится к наполнению) +- Адаптивная верстка: мобильная → десктопная -- Node.js 18+ и npm/yarn/pnpm +### Профиль исполнителя (личный кабинет) +- Загрузка аватара (превью + сохранение) +- Редактирование описания, компетенций (теги с поиском) +- Установка рабочего расписания по дням недели +- Переход в роль исполнителя +- Смена пароля -### Установка +### Управление услугами +- Список моих услуг с фото-обложкой +- Создание и редактирование услуги: + - **Блок загрузки фото** (первым, до 10 шт., каждое ≤ 5 МБ) + - Drag-and-drop для перестановки фото мышью + - Кнопка удаления под каждым фото + - Первое фото = обложка услуги + - Название, описание, цена (тип + сумма), атрибуты +- Приостановка услуги (пауза) +- Удаление услуги (soft delete) +- Приостановленные и удалённые услуги не видны в поиске + +--- + +## 🚀 Запуск ```bash -# Клонирование репозитория -git clone cd nashel-frontend -# Установка зависимостей +# Установить зависимости npm install -# Копирование файла переменных окружения -cp .env.example .env.local -# Отредактируйте переменные в .env.local +# Запустить dev-сервер +npm run dev ``` +Приложение доступно по адресу: `http://localhost:3000` + ### Переменные окружения -Создайте файл `.env.local` в корне проекта: +Создать файл `.env.local`: ```env -# API NEXT_PUBLIC_API_URL=http://localhost:5000 - -# Другие переменные (опционально) -NEXT_PUBLIC_APP_NAME=Nashel -NEXT_PUBLIC_APP_URL=http://localhost:3000 ``` -### Запуск - -```bash -# Режим разработки -npm run dev - -# Сборка для продакшена -npm run build - -# Запуск продакшен-сборки -npm start - -# Линтинг -npm run lint -``` - -Приложение будет доступно по адресу: `http://localhost:3000` - -## 📚 Структура страниц - -### Основные страницы - -| Путь | Описание | Защищена | -|------|----------|----------| -| `/` | Главная страница | ❌ | -| `/map` | Поиск исполнителей на карте | ❌ | -| `/orders` | Мои заказы | ✅ | -| `/dashboard/profile` | Профиль пользователя | ✅ | -| `/auth/login` | Вход в систему | ❌ | -| `/auth/register` | Регистрация | ❌ | - -## 🎯 Реализованный функционал - -### Аутентификация - -#### Вход в систему -- ✅ Форма входа с валидацией -- ✅ Отправка номера телефона и пароля -- ✅ Сохранение токенов в cookies -- ✅ Перенаправление после входа - -#### Регистрация -- ✅ Регистрация частных лиц (ФИО) -- ✅ Регистрация компаний (название + ИНН) -- ✅ Валидация формы (zod) -- ✅ Переключатель "Я представляю компанию" -- ✅ Перенаправление после регистрации - -#### Авторизация -- ✅ Проверка токена при загрузке приложения -- ✅ Автоматический вход при наличии токена -- ✅ Сохранение сессии между перезагрузками -- ✅ Выход из системы - -### Профиль пользователя - -#### Личные данные -- ✅ Отображение ФИО или названия компании -- ✅ Редактирование профиля -- ✅ Разные поля для частных лиц и компаний -- ✅ ИНН для компаний - -#### Аватар -- ✅ Загрузка аватара -- ✅ Кроп изображения (круглый) -- ✅ Предпросмотр аватара -- ✅ Валидация размера (до 5 МБ) и формата (JPG, PNG) -- ✅ Отображение аватара в профиле и хедере - -#### Компетенции -- ✅ Добавление компетенций -- ✅ Автодополнение при вводе (в стиле Яндекс) -- ✅ Теги в стиле hh.ru -- ✅ Нормализация в нижний регистр -- ✅ Общий пул компетенций для всех исполнителей -- ✅ Управление компетенциями (добавление/удаление) - -#### Рейтинг (заглушка) -- ✅ Отображение рейтинга в профиле -- ✅ 5 звезд с прогресс-баром -- ✅ Цветовая схема как в Ozon: - - Зеленый (> 4.0) - - Синий (3.0 - 4.0) - - Красный (< 3.0) -- ✅ Числовое значение с точностью до сотых -- ✅ Случайный рейтинг (изменяется каждую секунду) - -#### Связь -- ✅ Отображение номера телефона -- ✅ Изменение номера телефона - -#### Безопасность -- ✅ Отображение ролей аккаунта -- ✅ Кнопка смены пароля (в планах) -- ✅ Выход из аккаунта - -#### Стать исполнителем -- ✅ Блок "Зарабатывайте с нами" для клиентов -- ✅ Кнопка "Стать исполнителем" -- ✅ Смена роли на Master/Candidate - -### Компании - -#### Регистрация -- ✅ Отдельная форма регистрации -- ✅ Поля: название компании, ИНН -- ✅ Валидация ИНН (10 цифр) - -#### Профиль -- ✅ Отображение названия компании вместо ФИО -- ✅ Отображение ИНН -- ✅ Редактирование данных компании -- ✅ Рейтинг компании -- ✅ Компетенции компании - -### Исполнители - -#### Статус исполнителя -- ✅ Роли: Master, Candidate -- ✅ Блок "Компетенции" -- ✅ Рейтинг исполнителя - -#### Навигация -- ✅ Кнопка "Подобрать заказы" вместо "Стать исполнителем" -- ✅ Отображается в хедере и на главной странице - -### UI/UX - -#### Хедер -- ✅ Логотип и название -- ✅ Навигация (Поиск, Мои заказы) -- ✅ Информация о пользователе -- ✅ Кнопка входа/выхода -- ✅ Кнопка "Стать исполнителем" / "Подобрать заказы" -- ✅ Переключатель темы (светлая/темная) - -#### Главная страница -- ✅ Hero секция с призывом к действию -- ✅ Кнопка "Найти исполнителя" -- ✅ Кнопка "Стать исполнителем" / "Подобрать заказы" -- ✅ Преимущества сервиса -- ✅ Адаптивный дизайн - -#### Темы -- ✅ Светлая тема -- ✅ Темная тема -- ✅ Переключатель тем -- ✅ Сохранение выбора темы - -#### Уведомления -- ✅ Toast уведомления (Sonner) -- ✅ Успешные операции -- ✅ Ошибки -- ✅ Информационные сообщения - -## 🧩 Компоненты - -### UI Компоненты (shadcn/ui) - -- ✅ Button -- ✅ Input -- ✅ Card -- ✅ Badge -- ✅ Form -- ✅ Slider -- ✅ Avatar -- ✅ Dialog -- ✅ Dropdown Menu -- ✅ и др. - -### Кастомные компоненты - -#### AvatarUploader -- Загрузка аватара с кропом -- Предпросмотр -- Валидация - -#### TagInput -- Ввод компетенций -- Автодополнение -- Теги в стиле hh.ru - -#### Rating -- Отображение рейтинга -- 5 звезд с прогресс-баром -- Цветовая схема - -## 📊 State Management - -### Zustand Store - -```typescript -// entities/session/store.ts -interface SessionState { - user: User | null - isAuth: boolean - isLoading: boolean - isInitialized: boolean - checkAuth: () => Promise - login: (phone: string, password: string) => Promise - register: (data: any) => Promise - logout: () => void - getProfile: () => Promise - updateProfile: (data: any) => Promise - changePhone: (newPhone: string) => Promise - becomePerformer: () => Promise - updateCompetencies: (competencies: string[]) => Promise - uploadAvatar: (file: File) => Promise -} -``` - -## 🔧 API Клиент - -### Axios Configuration - -```typescript -// shared/api/axios.ts -- Базовый URL -- Интерцептор для токена -- Обработка ошибок -- Таймауты -``` - -### API Методы - -```typescript -// lib/api.ts -- login -- register -- getProfile -- updateProfile -- changePhone -- becomePerformer -- uploadAvatar -- updateCompetencies -- searchCompetencies -``` - -## 📝 Конвенции кода - -### TypeScript - -- Строгая типизация -- Интерфейсы для всех DTO -- Generics где необходимо -- JSDoc для сложных функций - -### React - -- Функциональные компоненты -- Hooks (useState, useEffect, useCallback, useMemo) -- Компоненты высшего порядка (HOC) по необходимости -- Composition over inheritance - -### Стилизация - -- Tailwind CSS для стилей -- CSS Modules для сложных компонентов (при необходимости) -- Атомарные классы -- Responsive design (mobile-first) - -## 🧪 Тестирование - -```bash -# Запуск тестов -npm test - -# Запуск с покрытием -npm test -- --coverage - -# E2E тесты (Playwright) -npm run test:e2e -``` - -## 🚨 Обработка ошибок - -- Глобальный обработчик ошибок -- Toast уведомления для пользователя -- Логирование в консоль (development) -- Отправка ошибок на сервер (production - в планах) - -## 🎨 Дизайн - -### Цветовая схема - -- **Основной цвет:** синий (`blue-600`) -- **Успех:** зеленый (`green-600`) -- **Ошибка:** красный (`red-600`) -- **Предупреждение:** желтый (`yellow-600`) -- **Текст:** серый (`slate-900`) - -### Шрифты - -- **Основной:** Inter (Google Fonts) -- **Моноширинный:** для кода (при необходимости) - -### Иконки - -- **Библиотека:** Lucide React -- **Размеры:** sm (16px), md (20px), lg (24px) - -## 📱 Адаптивность - -- Mobile-first подход -- Breakpoints: sm (640px), md (768px), lg (1024px), xl (1280px) -- Адаптивная навигация -- Адаптивные формы - -## 🔐 Безопасность - -- JWT токены в cookies (httpOnly) -- Валидация на клиенте и сервере -- XSS защита (React по умолчанию) -- CSRF защита (в планах) - -## 🚀 Оптимизация - -- Код-сплиттинг (Next.js по умолчанию) -- Ленивая загрузка компонентов -- Оптимизация изображений (Next.js Image) -- Кэширование (в планах) - -## 📦 Сборка - -```bash -# Production сборка -npm run build - -# Анализ бандла -npm run analyze -``` - -## 🔄 CI/CD - -- GitHub Actions для автоматического тестирования -- Vercel для деплоя (в планах) -- Автоматический деплой (в планах) - -## 📞 Контакты - -- **Проект:** Nashel -- **Версия:** 1.0.0 -- **Лицензия:** MIT - -## 🤝 Вклад в проект - -1. Fork репозитория -2. Создайте ветку для фичи (`git checkout -b feature/AmazingFeature`) -3. Закоммитьте изменения (`git commit -m 'Add some AmazingFeature'`) -4. Запушьте в ветку (`git push origin feature/AmazingFeature`) -5. Откройте Pull Request - -## 📚 Дополнительные ресурсы - -- [Next.js Documentation](https://nextjs.org/docs) -- [React Documentation](https://react.dev) -- [TypeScript Documentation](https://www.typescriptlang.org/docs) -- [Tailwind CSS Documentation](https://tailwindcss.com/docs) -- [shadcn/ui Documentation](https://ui.shadcn.com) -- [Zustand Documentation](https://zustand-demo.pmnd.rs) -- [Feature-Sliced Design](https://feature-sliced.design) +--- + +## 🔧 Технологии + +| Технология | Назначение | +|------------|------------| +| **Next.js 15** (App Router) | SSR/SPA, маршрутизация | +| **TypeScript** | Типизация | +| **Tailwind CSS** | Стилизация | +| **Shadcn/UI** | Готовые UI компоненты | +| **Zustand** | Глобальное состояние (геолокация) | +| **React Leaflet** | Карта (с отключённым SSR) | +| **React Hook Form + Zod** | Формы и валидация | +| **Axios** | HTTP-запросы к API | +| **Lucide React** | Иконки | +| **Sonner** | Тосты/уведомления | + +--- + +## 🔮 Планы развития + +- [ ] Реальный чат с исполнителем (WebSocket) +- [ ] Страница профиля исполнителя (публичная) +- [ ] Система отзывов и рейтингов (реальные данные) +- [ ] Оформление заказа через платформу +- [ ] Push-уведомления +- [ ] Мобильное приложение (React Native) +- [ ] Полнотекстовый фильтр по категориям и тегам +- [ ] Похожие услуги (реальные данные из той же категории) +- [ ] SEO-оптимизация публичных страниц