import { useMemo, useState } from 'react' import Alert from '@mui/material/Alert' import Box from '@mui/material/Box' import Button from '@mui/material/Button' import Link from '@mui/material/Link' import Stack from '@mui/material/Stack' import Typography from '@mui/material/Typography' import { useMutation, useQueryClient } from '@tanstack/react-query' import { useUnit } from 'effector-react' import { Link as RouterLink } from 'react-router-dom' import { postAdminOrderMessage, setAdminOrderStatus } from '@/entities/order/api/admin-order-api' import type { AdminOrderDetailResponse } from '@/entities/order/api/admin-order-api' import { deliveryCarrierLabelRu } from '@/shared/constants/delivery-carrier' import { getAdminNextOrderStatuses } from '@/shared/constants/order' import { formatPriceRub } from '@/shared/lib/format-price' import { invalidateQueryKeys } from '@/shared/lib/invalidate-query-keys' import { parseOrderAddressSnapshot } from '@/shared/lib/order-address-snapshot' import { ORDER_STATUS_MAP } from '@/shared/lib/order-status-data' import { $user } from '@/shared/model/auth' import { ChatMessageBubble } from '@/shared/ui/ChatMessageBubble' import { OrderMessageBody } from '@/shared/ui/OrderMessageBody' import { RichTextMessageEditor } from '@/shared/ui/RichTextMessageEditor.lazy' import { UserAvatar } from '@/shared/ui/UserAvatar' import { DeliveryFeeAdjustmentForm } from './DeliveryFeeAdjustmentForm' export function OrderDetailContent({ detail, orderId }: { detail: AdminOrderDetailResponse['item']; orderId: string }) { const qc = useQueryClient() const [msg, setMsg] = useState('') const statusMut = useMutation({ mutationFn: (next: string) => setAdminOrderStatus(orderId, next), onSuccess: async () => { await invalidateQueryKeys(qc, [ ['admin', 'orders'], ['admin', 'orders', 'detail'], ['admin', 'orders', 'summary'], ]) }, }) const msgMut = useMutation({ mutationFn: () => postAdminOrderMessage(orderId, msg.trim()), onSuccess: async () => { setMsg('') await invalidateQueryKeys(qc, [['admin', 'orders', 'detail']]) }, }) const deliverySnapshot = useMemo( () => (detail.deliveryType === 'delivery' ? parseOrderAddressSnapshot(detail.addressSnapshotJson) : null), [detail], ) const nextStatuses = useMemo( () => getAdminNextOrderStatuses(detail.status, detail.deliveryType ?? 'delivery'), [detail], ) const canSendMessage = msg.replace(/<[^>]*>/g, ' ').trim().length > 0 const currentUser = useUnit($user) return ( #{detail.id.slice(-8)} · {detail.user.email} · {ORDER_STATUS_MAP[detail.status] ?? detail.status} ·{' '} {formatPriceRub(detail.totalCents)} Получение: {detail.deliveryType === 'pickup' ? 'самовывоз' : 'доставка'} {(detail.paymentMethod ?? 'online') === 'on_pickup' ? ' · оплата при получении' : ' · онлайн-оплата'} {detail.deliveryType === 'delivery' && deliveryCarrierLabelRu(detail.deliveryCarrier) && ( <> · служба: {deliveryCarrierLabelRu(detail.deliveryCarrier)} )} {detail.deliveryType === 'delivery' && ( Адрес и получатель (на момент заказа) {deliverySnapshot ? ( {deliverySnapshot.label?.trim() && ( Метка: {deliverySnapshot.label} )} Адрес: {' '} {deliverySnapshot.addressLine ?? '—'} Получатель: {' '} {deliverySnapshot.recipientName ?? '—'} Телефон: {' '} {deliverySnapshot.recipientPhone ?? '—'} {deliverySnapshot.comment?.trim() && ( Комментарий к адресу: {deliverySnapshot.comment} )} ) : ( Данные адреса в заказе отсутствуют или не распознаны. )} )} Товары в заказе {detail.items.map((item) => ( {item.titleSnapshot} {item.qty} × {formatPriceRub(item.priceCentsSnapshot)} {formatPriceRub(item.priceCentsSnapshot * item.qty)} ))} {detail.status === 'PENDING_PAYMENT' && detail.deliveryFeeLocked === false && ( Укажите итоговую стоимость доставки (₽). После сохранения клиент сможет оплатить заказ с учётом этой суммы. )} {detail.status === 'PENDING_PAYMENT' && detail.deliveryFeeLocked === false && ( )} Быстрый переход статуса {statusMut.isError && Не удалось сменить статус} {nextStatuses.length === 0 ? ( Статус финальный, смена недоступна ) : ( {nextStatuses.map((nextStatus) => { const isCancelled = nextStatus === 'CANCELLED' return ( ) })} )} Сообщения {detail.messages.map((m) => { const isAdminMsg = m.authorType === 'admin' const avatarNode = isAdminMsg ? ( currentUser && ( ) ) : ( ) return ( {isAdminMsg ? 'Админ (вы)' : 'Пользователь'} · {new Date(m.createdAt).toLocaleString()} ) })} {detail.messages.length === 0 && Нет сообщений.} ) }