import { useEffect, useMemo, useState } from 'react' import Alert from '@mui/material/Alert' import Box from '@mui/material/Box' import Button from '@mui/material/Button' import Chip from '@mui/material/Chip' import List from '@mui/material/List' import ListItem from '@mui/material/ListItem' import ListItemButton from '@mui/material/ListItemButton' import ListItemText from '@mui/material/ListItemText' import Stack from '@mui/material/Stack' import Typography from '@mui/material/Typography' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { useUnit } from 'effector-react' import { Link as RouterLink } from 'react-router-dom' import { fetchMyOrder, postOrderMessage } from '@/entities/order/api/order-api' import { fetchMyConversations, markOrderMessagesRead } from '@/entities/user/api/messages-api' import { fetchAdminAvatar } from '@/entities/user/api/user-api' import { orderStatusLabelRu } from '@/shared/lib/order-status-labels' import { $user } from '@/shared/model/auth' import { ChatMessageBubble } from '@/shared/ui/ChatMessageBubble' import { OrderMessageBody } from '@/shared/ui/OrderMessageBody' import { RichTextMessageContent } from '@/shared/ui/RichTextMessageContent' import { RichTextMessageEditor } from '@/shared/ui/RichTextMessageEditor' import { UserAvatar } from '@/shared/ui/UserAvatar' export function MessagesPage() { const qc = useQueryClient() const [selectedId, setSelectedId] = useState(null) const [text, setText] = useState('') const currentUser = useUnit($user) const adminAvatarQuery = useQuery({ queryKey: ['admin', 'avatar'], queryFn: fetchAdminAvatar, staleTime: 5 * 60 * 1000, }) const listQuery = useQuery({ queryKey: ['me', 'conversations'], queryFn: fetchMyConversations, }) const conversationsList = useMemo(() => listQuery.data?.items ?? [], [listQuery.data?.items]) const activeThreadId = useMemo(() => { return selectedId ?? conversationsList[0]?.orderId ?? null }, [selectedId, conversationsList]) const orderQuery = useQuery({ queryKey: ['me', 'orders', activeThreadId], queryFn: () => fetchMyOrder(activeThreadId!), enabled: Boolean(activeThreadId), }) useEffect(() => { if (!activeThreadId || orderQuery.status !== 'success') return void (async () => { await markOrderMessagesRead(activeThreadId).catch(() => undefined) await qc.invalidateQueries({ queryKey: ['me', 'messages', 'unread-count'] }) await qc.invalidateQueries({ queryKey: ['me', 'conversations'] }) })() }, [activeThreadId, orderQuery.status, qc]) const msgMut = useMutation({ mutationFn: () => postOrderMessage(activeThreadId!, text.trim()), onSuccess: async () => { setText('') await qc.invalidateQueries({ queryKey: ['me', 'orders', activeThreadId] }) await qc.invalidateQueries({ queryKey: ['me', 'conversations'] }) }, }) const order = orderQuery.data?.item const canSendMessage = text.replace(/<[^>]*>/g, ' ').trim().length > 0 return ( Сообщения Переписка по всем заказам. Последнее сообщение в каждом заказе — в списке слева. {listQuery.isError && Не удалось загрузить переписки.} {listQuery.isSuccess && conversationsList.length === 0 && ( Пока нет сообщений в заказах. Их отправит администратор — или напишите сами на странице заказа. )} {conversationsList.length > 0 && ( {conversationsList.map((c) => ( 0 ? ( ) : null } > setSelectedId(c.orderId)}> №{c.orderId.slice(-6)} · {orderStatusLabelRu(c.status)} } slotProps={{ secondary: { sx: { mt: 0.5, overflow: 'hidden', display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', }, }, }} secondary={} /> ))} {!activeThreadId && Выберите заказ.} {activeThreadId && orderQuery.isLoading && Загрузка чата…} {activeThreadId && orderQuery.isError && Не удалось загрузить заказ.} {order && ( <> Чат заказа №{order.id.slice(-6)}{' '} ({orderStatusLabelRu(order.status)}) {order.messages.map((m) => { const isAdminMsg = m.authorType === 'admin' const adminAv = adminAvatarQuery.data const avatarNode = isAdminMsg ? ( ) : currentUser ? ( ) : null return ( {isAdminMsg ? 'Админ' : 'Вы'} · {new Date(m.createdAt).toLocaleString()} ) })} {order.messages.length === 0 && Нет сообщений.} )} )} ) }