This commit is contained in:
2026-03-26 15:39:58 +03:30
parent e89c3a1b16
commit 93215a7366
3 changed files with 86 additions and 18 deletions
+66 -9
View File
@@ -28,6 +28,7 @@ export class ApiClient {
constructor(baseURL: string = resolveApiBaseUrl()) {
this.baseURL = baseURL.replace(/\/$/, ""); // Remove trailing slash
this.defaultHeaders = {
Accept: "application/json",
"Content-Type": "application/json",
};
}
@@ -95,6 +96,57 @@ export class ApiClient {
return headers;
}
private prepareBody(
data: any,
headers: Record<string, string>,
): BodyInit | undefined {
if (data === undefined || data === null) return undefined;
if (typeof FormData !== "undefined" && data instanceof FormData) {
delete headers["Content-Type"];
return data;
}
if (
typeof URLSearchParams !== "undefined" &&
data instanceof URLSearchParams
) {
return data;
}
if (typeof Blob !== "undefined" && data instanceof Blob) {
return data;
}
if (typeof ArrayBuffer !== "undefined" && data instanceof ArrayBuffer) {
return data;
}
if (typeof ArrayBuffer !== "undefined" && ArrayBuffer.isView(data)) {
return data;
}
const contentType = headers["Content-Type"]?.toLowerCase();
if (contentType?.includes("application/x-www-form-urlencoded")) {
return new URLSearchParams(
Object.entries(data).reduce<Record<string, string>>((acc, [key, value]) => {
if (value !== undefined && value !== null) {
acc[key] = String(value);
}
return acc;
}, {}),
).toString();
}
if (!contentType || contentType.includes("application/json")) {
return typeof data === "string" ? data : JSON.stringify(data);
}
return data as BodyInit;
}
/**
* Handle API response
*/
@@ -155,10 +207,12 @@ export class ApiClient {
customHeaders?: Record<string, string>,
): Promise<T> {
const url = `${this.baseURL}${endpoint}`;
const headers = this.getHeaders(customHeaders);
const response = await fetch(url, {
method: "POST",
headers: this.getHeaders(customHeaders),
body: data ? JSON.stringify(data) : undefined,
headers,
body: this.prepareBody(data, headers),
});
return this.handleResponse<T>(response);
@@ -173,12 +227,11 @@ export class ApiClient {
customHeaders?: Record<string, string>,
): Promise<T> {
const url = `${this.baseURL}${endpoint}`;
const headers = { ...this.getHeaders(customHeaders) };
delete headers["Content-Type"];
const headers = this.getHeaders(customHeaders);
const response = await fetch(url, {
method: "POST",
headers,
body: formData,
body: this.prepareBody(formData, headers),
});
return this.handleResponse<T>(response);
@@ -193,10 +246,12 @@ export class ApiClient {
customHeaders?: Record<string, string>,
): Promise<T> {
const url = `${this.baseURL}${endpoint}`;
const headers = this.getHeaders(customHeaders);
const response = await fetch(url, {
method: "PUT",
headers: this.getHeaders(customHeaders),
body: data ? JSON.stringify(data) : undefined,
headers,
body: this.prepareBody(data, headers),
});
return this.handleResponse<T>(response);
@@ -211,10 +266,12 @@ export class ApiClient {
customHeaders?: Record<string, string>,
): Promise<T> {
const url = `${this.baseURL}${endpoint}`;
const headers = this.getHeaders(customHeaders);
const response = await fetch(url, {
method: "PATCH",
headers: this.getHeaders(customHeaders),
body: data ? JSON.stringify(data) : undefined,
headers,
body: this.prepareBody(data, headers),
});
return this.handleResponse<T>(response);
@@ -176,7 +176,7 @@ export const farmDashboardService = {
try {
const response = await apiClient.get<
ApiResponse<FarmDashboardConfigResponse> | FarmDashboardConfigResponse
>("/api/farm-dashboard-config");
>("/api/farm-dashboard-config/");
const raw = response && "data" in response ? response.data : response;
if (
raw &&
@@ -202,7 +202,7 @@ export const farmDashboardService = {
try {
const response = await apiClient.patch<
ApiResponse<FarmDashboardConfigResponse> | FarmDashboardConfigResponse
>("/api/farm-dashboard-config", toApiRequest(data));
>("/api/farm-dashboard-config/", toApiRequest(data));
const raw = response && "data" in response ? response.data : response;
if (
raw &&