admin/services/adminChat.ts
alisaza e1eaf5eff5 feat: initial ghabilee-admin backoffice app
Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js
app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
2026-09-05 13:12:59 +03:30

109 lines
3.3 KiB
TypeScript

import axiosInstance from '@/config/axios'
import { parseRemittanceList, unwrapApiPayload } from '@/helpers/listResponse'
import { API_ROUTES } from '@/services/config'
export interface AdminChatUser {
userId: string
mobile: string
firstName: string | null
lastName: string | null
avatarUrl: string | null
gender: 'male' | 'female' | 'other' | null
status: string
joinedAt: string
}
export interface AdminConversation {
id: string
type: 'direct' | 'event_group'
eventId: string | null
eventTitle: string | null
participantPreview: AdminChatUser[]
memberCount: number
preview: string | null
closesAt: string | null
lastMessageAt: string | null
createdAt: string
}
export interface AdminChatMessage {
id: string
conversationId: string
senderId: string
senderMobile?: string | null
senderFirstName: string | null
senderLastName: string | null
senderAvatarUrl: string | null
senderGender: 'male' | 'female' | 'other' | null
body: string | null
imageUrl: string | null
replyTo?: {
id: string
senderId: string
senderDisplayName: string
bodyPreview?: string | null
hasImage: boolean
isUnavailable: boolean
} | null
createdAt: string
}
export interface AdminMessagesPage {
items: AdminChatMessage[]
olderCursor: string | null
newerCursor: string | null
hasMoreBefore: boolean
hasMoreAfter: boolean
aroundMessageId: string | null
}
export const GET_ADMIN_CONVERSATION = async (conversationId: string): Promise<AdminConversation> => {
const response = await axiosInstance.get(API_ROUTES.CHAT_OVERSIGHT.ADMIN_DETAIL(conversationId))
return unwrapApiPayload(response.data)
}
export const GET_ADMIN_CONVERSATION_PARTICIPANTS = async (conversationId: string): Promise<AdminChatUser[]> => {
const response = await axiosInstance.get(API_ROUTES.CHAT_OVERSIGHT.ADMIN_PARTICIPANTS(conversationId), {
params: { page: 1, pageSize: 100, sort: 'joinedAt' },
})
return parseRemittanceList<AdminChatUser>(response.data).items
}
export const GET_ADMIN_CONVERSATION_MESSAGES = async (
conversationId: string,
params?: { before?: string; after?: string; around?: string; pageSize?: number }
): Promise<AdminMessagesPage> => {
const response = await axiosInstance.get(API_ROUTES.CHAT_OVERSIGHT.ADMIN_MESSAGES(conversationId), {
params: {
pageSize: params?.pageSize ?? 50,
...(params?.before ? { before: params.before } : {}),
...(params?.after ? { after: params.after } : {}),
...(params?.around ? { around: params.around } : {}),
},
})
const payload = unwrapApiPayload(response.data)
const itemsRaw = payload.items
const responseRaw = payload.response
const responseMeta =
typeof responseRaw === 'object' && responseRaw !== null && !Array.isArray(responseRaw)
? (responseRaw as {
olderCursor?: string | null
newerCursor?: string | null
hasMoreBefore?: boolean
hasMoreAfter?: boolean
aroundMessageId?: string
})
: null
return {
items: Array.isArray(itemsRaw) ? (itemsRaw as AdminChatMessage[]) : [],
olderCursor: responseMeta?.olderCursor ?? null,
newerCursor: responseMeta?.newerCursor ?? null,
hasMoreBefore: responseMeta?.hasMoreBefore ?? false,
hasMoreAfter: responseMeta?.hasMoreAfter ?? false,
aroundMessageId: responseMeta?.aroundMessageId ?? null,
}
}