Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
145 lines
4.0 KiB
TypeScript
145 lines
4.0 KiB
TypeScript
import axiosInstance from '@/config/axios'
|
|
import type { WalletResponseDto, WalletTransactionResponseDto, WalletTransactionType } from '@/api/generated/models'
|
|
import {
|
|
createServiceError,
|
|
errorResult,
|
|
handleServiceError,
|
|
type ServiceCallOptions,
|
|
type ServiceResult,
|
|
shouldBubbleErrorToParent,
|
|
successResult,
|
|
} from '@/services/errorHandler'
|
|
import { unwrapApiData } from '@/services/apiResponse'
|
|
import { getFinancial } from '@/api/generated/financial/financial'
|
|
import { parseRemittanceList } from '@/helpers/listResponse'
|
|
import { texts } from '@/texts'
|
|
|
|
export type { WalletTransactionType }
|
|
export type Wallet = WalletResponseDto
|
|
export type WalletTransaction = WalletTransactionResponseDto
|
|
|
|
export interface WalletDepositCheckout {
|
|
trackingId: string
|
|
paymentUrl: string
|
|
}
|
|
|
|
export interface CreateWalletDepositResult {
|
|
id: string
|
|
amount: number
|
|
status: string
|
|
checkout: WalletDepositCheckout | null
|
|
isSimulated: boolean
|
|
}
|
|
|
|
export const MIN_WALLET_DEPOSIT_AMOUNT = 10_000
|
|
|
|
export const CREATE_WALLET_DEPOSIT = async (
|
|
amount: number,
|
|
options?: ServiceCallOptions
|
|
): Promise<ServiceResult<CreateWalletDepositResult>> => {
|
|
try {
|
|
const res = await axiosInstance.post<{ success: boolean; message?: string; data: CreateWalletDepositResult }>(
|
|
'/users/me/wallet/deposits',
|
|
{ amount }
|
|
)
|
|
const payload = res.data
|
|
|
|
if (!payload.success) {
|
|
throw createServiceError(payload.message || texts.wallet.topUpFailed)
|
|
}
|
|
|
|
if (!payload.data?.id) {
|
|
throw createServiceError(texts.common.invalidServerResponse)
|
|
}
|
|
|
|
return successResult(payload.data)
|
|
} catch (error) {
|
|
const normalizedError = handleServiceError(error, options)
|
|
|
|
if (shouldBubbleErrorToParent(options)) {
|
|
throw normalizedError
|
|
}
|
|
|
|
return errorResult(normalizedError)
|
|
}
|
|
}
|
|
|
|
export const GET_WALLET_DEPOSIT = async (
|
|
depositId: string,
|
|
options?: ServiceCallOptions
|
|
): Promise<ServiceResult<{ id: string; status: string; amount: number }>> => {
|
|
try {
|
|
const res = await axiosInstance.get<{ success: boolean; message?: string; data: { id: string; status: string; amount: number } }>(
|
|
`/users/me/wallet/deposits/${depositId}`
|
|
)
|
|
const payload = res.data
|
|
|
|
if (!payload.success || !payload.data?.id) {
|
|
throw createServiceError(payload.message || texts.wallet.topUpFailed)
|
|
}
|
|
|
|
return successResult(payload.data)
|
|
} catch (error) {
|
|
const normalizedError = handleServiceError(error, options)
|
|
|
|
if (shouldBubbleErrorToParent(options)) {
|
|
throw normalizedError
|
|
}
|
|
|
|
return errorResult(normalizedError)
|
|
}
|
|
}
|
|
|
|
const financialApi = getFinancial()
|
|
|
|
export const GET_WALLET = async (options?: ServiceCallOptions): Promise<ServiceResult<Wallet>> => {
|
|
try {
|
|
const res = await financialApi.walletControllerGetMyWallet()
|
|
const payload = res.data
|
|
|
|
if (!payload.success) {
|
|
throw createServiceError(payload.message || texts.wallet.fetchWalletFailed)
|
|
}
|
|
|
|
const wallet = unwrapApiData(payload)
|
|
|
|
if (!wallet?.id) {
|
|
throw createServiceError(texts.common.invalidServerResponse)
|
|
}
|
|
|
|
return successResult(wallet)
|
|
} catch (error) {
|
|
const normalizedError = handleServiceError(error, options)
|
|
|
|
if (shouldBubbleErrorToParent(options)) {
|
|
throw normalizedError
|
|
}
|
|
|
|
return errorResult(normalizedError)
|
|
}
|
|
}
|
|
|
|
export const LIST_WALLET_TRANSACTIONS = async (options?: ServiceCallOptions): Promise<ServiceResult<{ items: WalletTransaction[] }>> => {
|
|
try {
|
|
const res = await financialApi.walletControllerListMyTransactions({ page: 1, pageSize: 30, sort: '-createdAt' })
|
|
|
|
const payload = res.data
|
|
|
|
if (!payload.success) {
|
|
throw createServiceError(payload.message || texts.wallet.fetchTransactionsFailed)
|
|
}
|
|
|
|
const parsed = parseRemittanceList<WalletTransaction>(unwrapApiData(payload) ?? {}, 'items')
|
|
|
|
return successResult({ items: parsed.items })
|
|
} catch (error) {
|
|
const normalizedError = handleServiceError(error, options)
|
|
|
|
if (shouldBubbleErrorToParent(options)) {
|
|
throw normalizedError
|
|
}
|
|
|
|
return errorResult(normalizedError)
|
|
}
|
|
}
|