# Дизайн: Доработки админки заказов (маркер цены + быстрые статусы) **Дата:** 2026-05-28 **Статус:** Draft ## Контекст Нужно улучшить UX в админке заказов по двум направлениям: 1. Явно показывать в списке заказов, что требуется подтверждение цены (итоговой стоимости для оплаты). 2. Сделать смену статуса заказа более удобной для администратора. Ограничения, согласованные в обсуждении: - Не вводим новый статус заказа для подтверждения цены. - Используем короткий текст для индикатора. - Для смены статуса выбираем формат быстрых кнопок доступных переходов (вместо выпадающего списка). ## Цели - Сократить время на обнаружение заказов, требующих подтверждения цены. - Упростить и ускорить смену статуса до 1 клика. - Сохранить существующие API-контракты и логику допустимых переходов. ## Не в рамках этой итерации - Изменение серверной статусной модели. - Добавление новых серверных полей или эндпоинтов. - Массовая смена статусов из таблицы без открытия деталки. - Редизайн всей таблицы заказов. ## Решение (утвержденный вариант A) ### 1) Маркер в списке заказов В `client/src/pages/admin-orders/ui/AdminOrdersPage.tsx` добавить короткий бейдж `Цена не подтверждена` для строк, где: - `status === 'PENDING_PAYMENT'` - `deliveryType === 'delivery'` - `deliveryFeeLocked === false` Размещение: в колонке `ID` рядом с коротким номером заказа (`o.id.slice(-8)`), чтобы не расширять таблицу и чтобы сигнал был виден до открытия деталки. ### 2) Быстрая смена статуса в деталке заказа В `client/src/features/order-detail/ui/OrderDetailContent.tsx` заменить текущий `Select` "Сменить статус" на набор кнопок быстрых переходов: - Источник переходов остается прежним: `getAdminNextOrderStatuses(detail.status, detail.deliveryType)` - Для каждого допустимого статуса рендерится отдельная кнопка - Клик вызывает текущую мутацию `setAdminOrderStatus` через `statusMut.mutate(next)` Поведение кнопок: - Пока мутация выполняется (`statusMut.isPending`) все кнопки отключены - Если доступных переходов нет — показываем текст `Статус финальный, смена недоступна` - Для `CANCELLED` использовать визуально менее акцентную кнопку (`outlined`), чтобы снизить риск случайного нажатия ## Архитектурные границы и переиспользование - Используем существующие данные `deliveryFeeLocked`, `status`, `deliveryType`. - Правила переходов не дублируем в UI, берем из `getAdminNextOrderStatuses`. - API слой (`client/src/entities/order/api/admin-order-api.ts`) без изменений. - React Query инвалидация сохраняется текущая: - `['admin', 'orders']` - `['admin', 'orders', 'detail']` - `['admin', 'orders', 'summary']` ## Поток данных 1. Страница списка получает `items` из `fetchAdminOrders`. 2. Для каждой строки вычисляется `needsPriceApproval`. 3. Если `needsPriceApproval === true`, отображается бейдж `Цена не подтверждена`. 4. В деталке рассчитывается `nextStatuses`. 5. Клик по кнопке статуса вызывает `statusMut`. 6. После успеха инвалидация обновляет список/деталку/summary; маркер в списке исчезает автоматически, когда условие перестает выполняться. ## Обработка ошибок - Ошибка смены статуса: показать локальный `Alert` в деталке с текстом `Не удалось сменить статус`, дать возможность повторить действие. - Ошибка загрузки списка: сохранить текущее поведение (`Не удалось загрузить заказы.`). - Пустой список переходов: показать явное сообщение о финальном статусе. ## Тестирование Минимальный набор: 1. Unit: проверка условия `needsPriceApproval`. 2. Component (`OrderDetailContent`): - рендерит кнопки только допустимых переходов - вызывает `setAdminOrderStatus` при клике - блокирует кнопки в pending-состоянии 3. Component/Smoke (`AdminOrdersPage`): - показывает `Цена не подтверждена` для целевых заказов - не показывает бейдж для остальных ## Критерии готовности - В списке заказов видно короткий маркер `Цена не подтверждена` для релевантных заказов. - В деталке смена статуса выполняется через быстрые кнопки допустимых переходов. - Список и деталка синхронизируются после успешной смены статуса. - Для `CANCELLED` используется менее акцентный стиль кнопки. - Проходят `npm run lint` и `npm run format:check` в `client`. ## План изменений по файлам - `client/src/pages/admin-orders/ui/AdminOrdersPage.tsx` — маркер `Цена не подтверждена` в строках списка. - `client/src/features/order-detail/ui/OrderDetailContent.tsx` — замена select на быстрые кнопки. - (опционально) `client/src/shared/lib/` — небольшой хелпер `needsPriceApproval`, если нужно переиспользование или unit-тест вне компонента. ## Риски и меры - Риск перегруза UI в деталке при большом количестве кнопок: низкий, так как число допустимых переходов обычно 1-2. - Риск случайного нажатия на отмену: снижается стилем `outlined` для `CANCELLED`. - Риск расхождения логики переходов: отсутствует, т.к. используется единый источник `getAdminNextOrderStatuses`.