Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
109 lines
3.3 KiB
TypeScript
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,
|
|
}
|
|
}
|