feat: avatars in /me/messages chat

This commit is contained in:
Kirill
2026-05-21 21:55:10 +05:00
parent f6729210db
commit 4fa4a91ddc
@@ -10,19 +10,30 @@ import ListItemText from '@mui/material/ListItemText'
import Stack from '@mui/material/Stack' import Stack from '@mui/material/Stack'
import Typography from '@mui/material/Typography' import Typography from '@mui/material/Typography'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useUnit } from 'effector-react'
import { Link as RouterLink } from 'react-router-dom' import { Link as RouterLink } from 'react-router-dom'
import { fetchMyOrder, postOrderMessage } from '@/entities/order/api/order-api' import { fetchMyOrder, postOrderMessage } from '@/entities/order/api/order-api'
import { fetchMyConversations, markOrderMessagesRead } from '@/entities/user/api/messages-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 { orderStatusLabelRu } from '@/shared/lib/order-status-labels'
import { $user } from '@/shared/model/auth'
import { ChatMessageBubble } from '@/shared/ui/ChatMessageBubble' import { ChatMessageBubble } from '@/shared/ui/ChatMessageBubble'
import { OrderMessageBody } from '@/shared/ui/OrderMessageBody' import { OrderMessageBody } from '@/shared/ui/OrderMessageBody'
import { RichTextMessageContent } from '@/shared/ui/RichTextMessageContent' import { RichTextMessageContent } from '@/shared/ui/RichTextMessageContent'
import { RichTextMessageEditor } from '@/shared/ui/RichTextMessageEditor' import { RichTextMessageEditor } from '@/shared/ui/RichTextMessageEditor'
import { UserAvatar } from '@/shared/ui/UserAvatar'
export function MessagesPage() { export function MessagesPage() {
const qc = useQueryClient() const qc = useQueryClient()
const [selectedId, setSelectedId] = useState<string | null>(null) const [selectedId, setSelectedId] = useState<string | null>(null)
const [text, setText] = useState('') const [text, setText] = useState('')
const currentUser = useUnit($user)
const adminAvatarQuery = useQuery({
queryKey: ['admin', 'avatar'],
queryFn: fetchAdminAvatar,
staleTime: 5 * 60 * 1000,
})
const listQuery = useQuery({ const listQuery = useQuery({
queryKey: ['me', 'conversations'], queryKey: ['me', 'conversations'],
@@ -163,14 +174,35 @@ export function MessagesPage() {
</Button> </Button>
</Stack> </Stack>
<Stack spacing={1} sx={{ mb: 2, maxHeight: 360, overflow: 'auto' }}> <Stack spacing={1} sx={{ mb: 2, maxHeight: 360, overflow: 'auto' }}>
{order.messages.map((m) => ( {order.messages.map((m) => {
<ChatMessageBubble key={m.id} authorType={m.authorType === 'admin' ? 'admin' : 'user'}> const isAdminMsg = m.authorType === 'admin'
<Typography variant="caption" color="text.secondary"> const adminAv = adminAvatarQuery.data
{m.authorType === 'admin' ? 'Админ' : 'Вы'} · {new Date(m.createdAt).toLocaleString()} const avatarNode = isAdminMsg ? (
</Typography> <UserAvatar
<OrderMessageBody text={m.text} attachmentUrl={m.attachmentUrl} /> userId="admin"
</ChatMessageBubble> avatarUrl={adminAv?.avatar}
))} avatarType={adminAv?.avatarType}
avatarStyle={adminAv?.avatarStyle}
size={24}
/>
) : currentUser ? (
<UserAvatar
userId={currentUser.id}
avatarUrl={currentUser.avatar}
avatarType={currentUser.avatarType}
avatarStyle={currentUser.avatarStyle}
size={24}
/>
) : null
return (
<ChatMessageBubble key={m.id} authorType={isAdminMsg ? 'admin' : 'user'} avatar={avatarNode}>
<Typography variant="caption" color="text.secondary">
{isAdminMsg ? 'Админ' : 'Вы'} · {new Date(m.createdAt).toLocaleString()}
</Typography>
<OrderMessageBody text={m.text} attachmentUrl={m.attachmentUrl} />
</ChatMessageBubble>
)
})}
{order.messages.length === 0 && <Typography color="text.secondary">Нет сообщений.</Typography>} {order.messages.length === 0 && <Typography color="text.secondary">Нет сообщений.</Typography>}
</Stack> </Stack>
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ alignItems: { sm: 'flex-end' } }}> <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ alignItems: { sm: 'flex-end' } }}>