Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
63 lines
2.0 KiB
TypeScript
63 lines
2.0 KiB
TypeScript
'use client'
|
|
|
|
import { useCallback, useState } from 'react'
|
|
import { useMutation, useQueryClient } from '@tanstack/react-query'
|
|
|
|
import { getServiceErrorCopy } from '@/helpers/serviceErrorCopy'
|
|
import { addToast } from '@/lib/toast'
|
|
import { adminKeys } from '@/queries/admin/adminKeys'
|
|
import { handleServiceError, resolveServiceErrorDisplayMessage } from '@/services/errorHandler'
|
|
|
|
interface UseAdminMutationOptions {
|
|
errorMessage?: string
|
|
url: string
|
|
}
|
|
|
|
interface AdminMutationVariables {
|
|
action: () => Promise<unknown>
|
|
id: string
|
|
successMessage: string
|
|
}
|
|
|
|
export default function useAdminMutation({ errorMessage = 'عملیات با خطا مواجه شد', url }: UseAdminMutationOptions) {
|
|
const queryClient = useQueryClient()
|
|
const [pendingId, setPendingId] = useState<string | null>(null)
|
|
const { mutateAsync } = useMutation({
|
|
mutationFn: ({ action }: AdminMutationVariables) => action(),
|
|
onSuccess: async (_data, { successMessage }) => {
|
|
addToast({ title: successMessage, color: 'success' })
|
|
await queryClient.invalidateQueries({ queryKey: adminKeys.listByUrl(url) })
|
|
},
|
|
onError: (error: unknown) => {
|
|
const normalizedError = handleServiceError(error, { errorMode: 'silent' })
|
|
const copy = getServiceErrorCopy()
|
|
const serviceMessage = resolveServiceErrorDisplayMessage(normalizedError, {
|
|
apiError: errorMessage || copy.apiError,
|
|
networkError: copy.networkError,
|
|
})
|
|
|
|
addToast({ title: serviceMessage || errorMessage, color: 'danger' })
|
|
},
|
|
})
|
|
|
|
const runAction = useCallback(
|
|
async (id: string, action: () => Promise<unknown>, successMessage: string) => {
|
|
setPendingId(id)
|
|
|
|
try {
|
|
await mutateAsync({ action, id, successMessage })
|
|
|
|
return true
|
|
} catch {
|
|
// Error presentation is centralized in the mutation's onError.
|
|
return false
|
|
} finally {
|
|
setPendingId(null)
|
|
}
|
|
},
|
|
[mutateAsync]
|
|
)
|
|
|
|
return { pendingId, runAction }
|
|
}
|