131 lines
3.8 KiB
TypeScript
131 lines
3.8 KiB
TypeScript
import { adminApiClient } from './client'
|
|
import type { TestDto, PaginatedResponse } from '@/types/models'
|
|
import type { AxiosError } from 'axios'
|
|
|
|
export interface TestsApiError {
|
|
message: string
|
|
statusCode?: number
|
|
field?: string
|
|
originalError?: unknown
|
|
name: 'TestsApiError'
|
|
}
|
|
|
|
export function createTestsApiError(
|
|
message: string,
|
|
statusCode?: number,
|
|
field?: string,
|
|
originalError?: unknown
|
|
): TestsApiError {
|
|
return {
|
|
message,
|
|
statusCode,
|
|
field,
|
|
originalError,
|
|
name: 'TestsApiError',
|
|
}
|
|
}
|
|
|
|
export function isTestsApiError(error: unknown): error is TestsApiError {
|
|
return (
|
|
typeof error === 'object' &&
|
|
error !== null &&
|
|
'name' in error &&
|
|
error.name === 'TestsApiError'
|
|
)
|
|
}
|
|
|
|
export const testsApi = {
|
|
// Get all tests with pagination and search
|
|
getTests: async (params?: {
|
|
page?: number
|
|
limit?: number
|
|
search?: string
|
|
}): Promise<PaginatedResponse<TestDto>> => {
|
|
try {
|
|
const response = await adminApiClient.get('/api/v2/admin/tests', {
|
|
params: {
|
|
page: params?.page || 1,
|
|
limit: params?.limit || 20,
|
|
search: params?.search,
|
|
},
|
|
})
|
|
return response.data
|
|
} catch (error) {
|
|
const axiosError = error as AxiosError<{ error?: string; message?: string; field?: string }>
|
|
throw createTestsApiError(
|
|
axiosError.response?.data?.message ||
|
|
axiosError.response?.data?.error ||
|
|
'Failed to load tests',
|
|
axiosError.response?.status,
|
|
axiosError.response?.data?.field,
|
|
error
|
|
)
|
|
}
|
|
},
|
|
|
|
// Get a specific test by ID
|
|
getTest: async (testId: string): Promise<TestDto> => {
|
|
try {
|
|
const response = await adminApiClient.get(`/api/v2/admin/tests/${testId}`)
|
|
return response.data
|
|
} catch (error) {
|
|
const axiosError = error as AxiosError<{ error?: string; message?: string }>
|
|
throw createTestsApiError(
|
|
axiosError.response?.data?.message ||
|
|
axiosError.response?.data?.error ||
|
|
`Failed to load test ${testId}`,
|
|
axiosError.response?.status,
|
|
undefined,
|
|
error
|
|
)
|
|
}
|
|
},
|
|
|
|
// Create or update a test
|
|
upsertTest: async (test: TestDto): Promise<{ success: boolean; test: TestDto }> => {
|
|
try {
|
|
const response = await adminApiClient.post('/api/v2/admin/tests', test)
|
|
return response.data
|
|
} catch (error) {
|
|
const axiosError = error as AxiosError<{ error?: string; message?: string; field?: string; details?: string }>
|
|
const isUpdate = test.id && test.id.length > 0
|
|
const operation = isUpdate ? 'update test' : 'create test'
|
|
const message = axiosError.response?.data?.message ||
|
|
axiosError.response?.data?.error ||
|
|
`Failed to ${operation}`
|
|
|
|
let fullMessage = message
|
|
if (axiosError.response?.data?.details) {
|
|
fullMessage += `. ${axiosError.response.data.details}`
|
|
}
|
|
if (axiosError.response?.data?.field) {
|
|
fullMessage += ` (Field: ${axiosError.response.data.field})`
|
|
}
|
|
|
|
throw createTestsApiError(
|
|
fullMessage,
|
|
axiosError.response?.status,
|
|
axiosError.response?.data?.field,
|
|
error
|
|
)
|
|
}
|
|
},
|
|
|
|
// Delete a test by ID
|
|
deleteTest: async (testId: string): Promise<{ success: boolean; message: string }> => {
|
|
try {
|
|
const response = await adminApiClient.delete(`/api/v2/admin/tests/${testId}`)
|
|
return response.data
|
|
} catch (error) {
|
|
const axiosError = error as AxiosError<{ error?: string; message?: string }>
|
|
throw createTestsApiError(
|
|
axiosError.response?.data?.message ||
|
|
axiosError.response?.data?.error ||
|
|
`Failed to delete test ${testId}`,
|
|
axiosError.response?.status,
|
|
undefined,
|
|
error
|
|
)
|
|
}
|
|
},
|
|
}
|