# Frontend (React + Vite + Tailwind)

## Технологии

- React 18
- Vite (сборщик)
- Tailwind CSS (стили)
- React Router DOM (роутинг)
- Axios (HTTP-запросы)
- i18next (интернационализация)
- react-qr-code (QR-коды)

## Сборка

```bash
cd frontend && npm run build
```

Результат: папка `dist/` (на уровень выше, в корне проекта)

## Роутинг (App.jsx)

| Путь | Компонент | Защищён |
|------|-----------|---------|
| `/login` | LoginPage | Нет |
| `/` | DashboardPage | Да |
| `/wallets` | WalletsPage | Да |
| `/manage-crypto` | ManageCryptoPage | Да |
| `/currency/:symbol` | CurrencyPage | Да |
| `/staking/:symbol` | StakingPage | Да |
| `/swap` | SwapPage | Да |
| `/earn` | EarnPage | Да |
| `/settings` | SettingsPage | Да |
| `/receive` | ReceivePage | Да |

`ProtectedRoute` проверяет наличие `sessionLogin` в `WalletContext`.

## Страницы

### LoginPage (`/login`)
- Два режима: создание нового кошелька или импорт
- Шаг 1: создание пароля (валидация: 8+ символов, заглавная, цифра, спецсимвол)
- Шаг 2: для создания — показ мнемоники; для импорта — ввод мнемоники
- Валидация мнемоники: 12 или 24 слова, только латинские строчные буквы и пробелы
- Автоматическое приведение к lowercase при вводе и вставке
- Чекбокс «Правила сервиса»

### DashboardPage (`/`)
- Общий баланс в USD
- PNL за 24 часа (изменение баланса)
- Список токенов с балансами
- Фильтр по сетям
- Кнопки: «Отправить» (модалка загруженности сети), «Мои адреса» (→ /receive)

### CurrencyPage (`/currency/:symbol`)
- Баланс токена
- График/цена
- Кнопки: Отправить (SendModal), Получить (ReceiveModal)
- История операций (BalanceHistory)
- Секция стейкинга (если поддерживается)

### StakingPage (`/staking/:symbol`)
- Информация о стейкинге (APR, период)
- Форма размещения
- Активные позиции с наградами
- Кнопки Unstake и Claim

### EarnPage (`/earn`)
- Список всех токенов с APR
- Ссылки на страницы стейкинга

### SwapPage (`/swap`)
- Выбор пары токенов
- Ввод суммы
- Отображение курса и комиссии
- Выполнение обмена

### ManageCryptoPage (`/manage-crypto`)
- Список всех токенов
- Тогл видимости (показать/скрыть на дашборде)

### ReceivePage (`/receive`)
- Все токены с адресами
- Кнопки: копировать адрес, показать QR-код
- Сетевой бейдж для каждого токена

### WalletsPage (`/wallets`)
- Список кошельков в сессии
- Создание/импорт нового (при импорте передаётся `isImport=true` в `login()`)
- Удаление

### SettingsPage (`/settings`)
- Управление кошельками
- Выход

## Ключевые компоненты

### WalletContext (context/WalletContext.jsx)

Глобальный стейт авторизации:
- `sessionLogin` — хранится в localStorage
- `activeWallet` — текущий активный кошелёк
- `userSessionWalletList` — все кошельки сессии
- `login(mnemonic, password, username, isImport)`
- `createNewWallet()`
- `switchWallet(walletId)`
- `logout()`
- `refreshSession()`

### TokenIcon (components/TokenIcon.jsx)

Отображает иконку токена с бейджем сети. Конфиг `TOKEN_ICON_MAP`:

```javascript
TOKEN_ICON_MAP = {
  BTC: { mainImage: '/coins/btc.png', networkName: 'Bitcoin', networkSymbol: 'BTC', ... },
  ETH: { mainImage: '/coins/eth.png', networkName: 'Ethereum', networkSymbol: 'ETH', ... },
  // ... 72+ токенов
}
```

Каждый токен имеет: `mainImage`, `networkImage`, `mainSymbol`, `networkSymbol`, `networkName`, `mainColor`, `networkColor`.

### SendModal (components/SendModal.jsx)

Модалка отправки токенов:
- Выбор сети (автоматически по токену)
- Адрес получателя (с валидацией по сети)
- Сумма (с USD-эквивалентом)
- Кнопка MAX
- Минимальная сумма: $0.10
- Создаёт заявку через POST `/api/withdraw/create`

### ReceiveModal (components/ReceiveModal.jsx)

- QR-код адреса
- Кнопка копирования
- Название сети

## API клиент (api/client.js)

- Base URL: `window.location.origin`
- Content-Type: `application/json`
- Credentials: `withCredentials: true`
- Очередь запросов для `/api/staking/` (предотвращение гонки)
- Обработка 429 (Too Many Requests)

## Стили

- Тёмная тема: `bg-[#1b1b1c]`, `text-white`
- Акцентный цвет: `#48FF91` (зелёный)
- Иконки токенов: `/coins/` (PNG-файлы в dist)
- Шрифты: кастомные (папка fonts/)
- Скрытие стрелок у input[number]: CSS-правила в index.css
