Refine order detail status layout

This commit is contained in:
Ruslan Bakiev
2026-04-06 20:58:08 +07:00
parent aabebe9b90
commit f1129199bd
4 changed files with 179 additions and 64 deletions

View File

@@ -9,6 +9,8 @@ type OrderStatusCode =
| 'IN_PROGRESS'
| 'COMPLETED';
export type OrderStatusTone = 'warning' | 'info' | 'success' | 'danger';
type TimelineStage = {
code: string;
label: string;
@@ -17,6 +19,11 @@ type TimelineStage = {
state: 'done' | 'current' | 'upcoming';
};
type StatusBadgePresentation = {
label: string;
tone: OrderStatusTone;
};
type StatusPresentation = {
title: string;
summary: string;
@@ -37,6 +44,18 @@ const DAY_FORMATTER = new Intl.DateTimeFormat('ru-RU', {
month: 'long',
});
const STATUS_BADGE_MAP: Record<string, StatusBadgePresentation> = {
NEW: { label: 'Заявка', tone: 'warning' },
MANAGER_PROCESSING: { label: 'Готовим предложение', tone: 'warning' },
WAITING_DOUBLE_CONFIRM: { label: 'Предложение', tone: 'info' },
CLIENT_REJECTED: { label: 'Отклонен', tone: 'danger' },
MANAGER_REJECTED: { label: 'Отклонен', tone: 'danger' },
MANAGER_BLOCKED: { label: 'Пауза', tone: 'warning' },
CONFIRMED: { label: 'Производство', tone: 'info' },
IN_PROGRESS: { label: 'Отгрузка', tone: 'success' },
COMPLETED: { label: 'Доставка', tone: 'success' },
};
function addDays(date: Date, days: number) {
const next = new Date(date);
next.setDate(next.getDate() + days);
@@ -149,14 +168,14 @@ function buildClientStages(status: string, createdAt: string | Date): StatusPres
stages: [
{
code: 'NEW',
label: 'Заказ создан',
label: 'Заявка',
note: 'Заказ принят в обработку.',
dateLabel: formatDay(dates.created),
state: 'done',
},
{
code: status,
label: 'Заказ остановлен',
label: 'Отклонен',
note: 'Дальнейшее исполнение не планируется.',
dateLabel: formatDay(dates.approval),
state: 'current',
@@ -172,14 +191,14 @@ function buildClientStages(status: string, createdAt: string | Date): StatusPres
stages: [
{
code: 'NEW',
label: 'Заказ создан',
label: 'Заявка',
note: 'Заказ принят в обработку.',
dateLabel: formatDay(dates.created),
state: 'done',
},
{
code: status,
label: 'Уточняем детали',
label: 'Пауза',
note: 'После уточнения покажем плановые даты по исполнению.',
dateLabel: formatDay(dates.approval),
state: 'current',
@@ -193,31 +212,45 @@ function buildClientStages(status: string, createdAt: string | Date): StatusPres
const stages: TimelineStage[] = [
{
code: 'NEW',
label: 'Заказ создан',
label: 'Заявка',
note: 'Приняли заказ и начали обработку.',
dateLabel: formatDay(dates.created),
state: currentIndex > 0 ? 'done' : 'current',
state: currentIndex > 0 ? 'done' : currentIndex === 0 ? 'current' : 'upcoming',
},
{
code: 'MANAGER_PROCESSING',
label: 'Готовим предложение',
note: 'Собираем стоимость и плановые сроки по заказу.',
dateLabel: formatDay(dates.offer),
state: currentIndex > 1 ? 'done' : currentIndex === 1 ? 'current' : 'upcoming',
},
{
code: 'WAITING_DOUBLE_CONFIRM',
label: 'Предложение',
note: 'Цена и условия готовы, ждём подтверждения.',
dateLabel: formatDay(dates.approval),
state: currentIndex > 2 ? 'done' : currentIndex === 2 ? 'current' : 'upcoming',
},
{
code: 'CONFIRMED',
label: 'Производство',
note: 'Плановая дата запуска или выхода из производства.',
dateLabel: formatDay(dates.production),
state: currentIndex > 3 ? 'done' : currentIndex >= 3 ? 'current' : 'upcoming',
state: currentIndex > 3 ? 'done' : currentIndex === 3 ? 'current' : 'upcoming',
},
{
code: 'IN_PROGRESS',
label: 'Отгрузка',
note: 'Плановая дата передачи в логистику.',
dateLabel: formatDay(dates.shipment),
state: currentIndex > 4 ? 'done' : currentIndex >= 4 ? 'current' : 'upcoming',
state: currentIndex > 4 ? 'done' : currentIndex === 4 ? 'current' : 'upcoming',
},
{
code: 'COMPLETED',
label: 'Доставка',
note: 'Плановая дата получения заказа.',
dateLabel: formatDay(dates.delivered),
state: currentIndex >= 5 ? 'current' : 'upcoming',
state: currentIndex === 5 ? 'current' : 'upcoming',
},
];
@@ -247,7 +280,7 @@ function buildClientStages(status: string, createdAt: string | Date): StatusPres
if (status === 'CONFIRMED') {
return {
title: ланируем производство',
title: 'Производство запланировано',
summary: `Ориентируемся на производство ${formatDay(dates.production)}, затем отгрузку и доставку по плану.`,
stages,
};
@@ -255,7 +288,7 @@ function buildClientStages(status: string, createdAt: string | Date): StatusPres
if (status === 'IN_PROGRESS') {
return {
title: 'Заказ в работе',
title: 'Готовим отгрузку',
summary: `Производство идёт. Следующая плановая дата: отгрузка около ${formatDay(dates.shipment)}.`,
stages,
};
@@ -268,6 +301,13 @@ function buildClientStages(status: string, createdAt: string | Date): StatusPres
};
}
export function getOrderStatusBadgePresentation(status: string): StatusBadgePresentation {
return STATUS_BADGE_MAP[status] ?? {
label: status,
tone: 'info',
};
}
export function getOrderStatusPresentation(
status: string,
createdAt: string | Date,