Files
clinicpro/assets/admin/lib/api.ts
T
hamed 147a2a894e feat: implement admin API for user and representation management
- Updated UsersPage to fetch users from the new admin endpoint.
- Enhanced user data structure to include 'name' and modified rendering logic.
- Added RepresentationDetailPage for detailed representation management.
- Created AdminApiController to handle user and representation CRUD operations.
- Implemented pagination and search functionality for users and representations.
- Updated user and representation data models to reflect new API structure.
2026-06-09 23:41:44 +03:30

77 lines
1.9 KiB
TypeScript

const BASE_URL = '';
function getToken(): string | null {
try {
const raw = localStorage.getItem('clinicpro-auth');
if (!raw) return null;
const parsed = JSON.parse(raw);
return parsed?.state?.token ?? null;
} catch {
return null;
}
}
export class ApiError extends Error {
constructor(
public status: number,
public code: string,
message: string,
) {
super(message);
}
}
async function request<T>(
path: string,
options: RequestInit = {},
): Promise<T> {
const token = getToken();
const headers: Record<string, string> = {
'Content-Type': 'application/json',
...(options.headers as Record<string, string>),
};
if (token) headers['Authorization'] = `Bearer ${token}`;
const res = await fetch(`${BASE_URL}${path}`, { ...options, headers });
if (!res.ok) {
const body = await res.json().catch(() => ({}));
const firstErr = body?.errors?.[0];
throw new ApiError(
res.status,
firstErr?.code ?? 'ERR_UNKNOWN',
firstErr?.message ?? 'خطای ناشناخته',
);
}
return res.json() as Promise<T>;
}
export const api = {
get: <T>(path: string) => request<T>(path),
post: <T>(path: string, body: unknown) =>
request<T>(path, { method: 'POST', body: JSON.stringify(body) }),
patch: <T>(path: string, body: unknown) =>
request<T>(path, { method: 'PATCH', body: JSON.stringify(body) }),
put: <T>(path: string, body: unknown) =>
request<T>(path, { method: 'PUT', body: JSON.stringify(body) }),
delete: <T>(path: string) => request<T>(path, { method: 'DELETE' }),
};
export interface ApiResponse<T> {
success: boolean;
data: T;
errors: { code: string; message: string; field?: string }[];
}
export interface PaginatedResponse<T> {
success: boolean;
data: T[];
meta: {
totalRecords: number;
totalPages: number;
currentPage: number;
};
errors: [];
}