feat: public admin avatar endpoint, real admin avatar in user chat
This commit is contained in:
@@ -30,6 +30,17 @@ export async function updateAdminUser(
|
||||
return data
|
||||
}
|
||||
|
||||
export type AdminAvatarResponse = {
|
||||
avatar: string | null
|
||||
avatarType: string | null
|
||||
avatarStyle: string | null
|
||||
}
|
||||
|
||||
export async function fetchAdminAvatar(): Promise<AdminAvatarResponse> {
|
||||
const { data } = await apiClient.get<AdminAvatarResponse>('admin/avatar')
|
||||
return data
|
||||
}
|
||||
|
||||
export async function deleteAdminUser(id: string): Promise<void> {
|
||||
await apiClient.delete(`admin/users/${id}`)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@ import Box from '@mui/material/Box'
|
||||
import Button from '@mui/material/Button'
|
||||
import Stack from '@mui/material/Stack'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useUnit } from 'effector-react'
|
||||
import { fetchAdminAvatar } from '@/entities/user/api/user-api'
|
||||
import { $user } from '@/shared/model/auth'
|
||||
import { ChatMessageBubble } from '@/shared/ui/ChatMessageBubble'
|
||||
import { OrderMessageBody } from '@/shared/ui/OrderMessageBody'
|
||||
@@ -29,6 +31,12 @@ export function OrderChat({ messages, isPending, onSend }: Props) {
|
||||
const canSend = text.replace(/<[^>]*>/g, ' ').trim().length > 0
|
||||
const currentUser = useUnit($user)
|
||||
|
||||
const adminAvatarQuery = useQuery({
|
||||
queryKey: ['admin', 'avatar'],
|
||||
queryFn: fetchAdminAvatar,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
})
|
||||
|
||||
const handleSend = () => {
|
||||
if (!canSend || isPending) return
|
||||
onSend(text.trim())
|
||||
@@ -43,8 +51,15 @@ export function OrderChat({ messages, isPending, onSend }: Props) {
|
||||
<Stack spacing={1} sx={{ mb: 2 }}>
|
||||
{messages.map((m) => {
|
||||
const isAdminMsg = m.authorType === 'admin'
|
||||
const adminAv = adminAvatarQuery.data
|
||||
const avatarNode = isAdminMsg ? (
|
||||
<UserAvatar userId="admin" avatarUrl={null} avatarType={null} avatarStyle={null} size={24} />
|
||||
<UserAvatar
|
||||
userId="admin"
|
||||
avatarUrl={adminAv?.avatar}
|
||||
avatarType={adminAv?.avatarType}
|
||||
avatarStyle={adminAv?.avatarStyle}
|
||||
size={24}
|
||||
/>
|
||||
) : currentUser ? (
|
||||
<UserAvatar
|
||||
userId={currentUser.id}
|
||||
|
||||
Binary file not shown.
@@ -1,3 +1,4 @@
|
||||
import { normalizeEmail } from '../../lib/auth.js'
|
||||
import { prisma } from '../../lib/prisma.js'
|
||||
|
||||
export async function registerAdminProfileRoutes(fastify) {
|
||||
@@ -15,6 +16,20 @@ export async function registerAdminProfileRoutes(fastify) {
|
||||
}
|
||||
})
|
||||
|
||||
fastify.get('/api/admin/avatar', async (request, reply) => {
|
||||
const adminEmail = normalizeEmail(process.env.ADMIN_EMAIL)
|
||||
if (!adminEmail || !adminEmail.includes('@')) return reply.code(404).send({ error: 'Администратор не найден' })
|
||||
|
||||
const user = await prisma.user.findUnique({ where: { email: adminEmail } })
|
||||
if (!user) return reply.code(404).send({ error: 'Администратор не найден' })
|
||||
|
||||
return {
|
||||
avatar: user.avatar,
|
||||
avatarType: user.avatarType,
|
||||
avatarStyle: user.avatarStyle,
|
||||
}
|
||||
})
|
||||
|
||||
fastify.patch('/api/admin/profile', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => {
|
||||
const userId = request.user.sub
|
||||
const nameRaw = request.body?.displayName
|
||||
|
||||
Reference in New Issue
Block a user