Files
shop-server/docs/superpowers/specs/2026-05-28-admin-orders-improvements-design.md
T
2026-05-28 21:20:35 +05:00

7.6 KiB
Raw Blame History

Дизайн: Доработки админки заказов (маркер цены + быстрые статусы)

Дата: 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.