admin/services/wallet.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

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)
}
}