feat: initial admin panel
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'https://api.approagency.ir/api';
|
||||
|
||||
interface ApiOptions extends RequestInit {
|
||||
token?: string;
|
||||
}
|
||||
|
||||
class ApiClient {
|
||||
private async request<T>(
|
||||
endpoint: string,
|
||||
options: ApiOptions = {}
|
||||
): Promise<T> {
|
||||
const { token, ...fetchOptions } = options;
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
...(options.headers as Record<string, string> || {}),
|
||||
};
|
||||
|
||||
// Don't set Content-Type for FormData (browser will set it automatically with boundary)
|
||||
if (!(options.body instanceof FormData)) {
|
||||
headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
|
||||
if (token) {
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
|
||||
...fetchOptions,
|
||||
headers,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json().catch(() => ({}));
|
||||
throw new Error(error.message || 'API request failed');
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
async post<T>(endpoint: string, data: any, token?: string): Promise<T> {
|
||||
const body = data instanceof FormData ? data : JSON.stringify(data);
|
||||
|
||||
return this.request<T>(endpoint, {
|
||||
method: 'POST',
|
||||
body,
|
||||
token,
|
||||
});
|
||||
}
|
||||
|
||||
async get<T>(endpoint: string, token?: string): Promise<T> {
|
||||
return this.request<T>(endpoint, {
|
||||
method: 'GET',
|
||||
token,
|
||||
});
|
||||
}
|
||||
|
||||
async put<T>(endpoint: string, data: any, token?: string): Promise<T> {
|
||||
const body = data instanceof FormData ? data : JSON.stringify(data);
|
||||
|
||||
return this.request<T>(endpoint, {
|
||||
method: 'PUT',
|
||||
body,
|
||||
token,
|
||||
});
|
||||
}
|
||||
|
||||
async delete<T>(endpoint: string, data?: any, token?: string): Promise<T> {
|
||||
const options: ApiOptions = {
|
||||
method: 'DELETE',
|
||||
token,
|
||||
};
|
||||
|
||||
// Handle DELETE with body if data is provided
|
||||
if (data) {
|
||||
options.body = data instanceof FormData ? data : JSON.stringify(data);
|
||||
|
||||
// Don't set Content-Type for FormData
|
||||
if (!(data instanceof FormData)) {
|
||||
options.headers = {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return this.request<T>(endpoint, options);
|
||||
}
|
||||
|
||||
// Convenience method for DELETE with JSON body
|
||||
async deleteWithBody<T>(endpoint: string, data: any, token?: string): Promise<T> {
|
||||
return this.delete<T>(endpoint, data, token);
|
||||
}
|
||||
|
||||
async patch<T>(endpoint: string, data: any, token?: string): Promise<T> {
|
||||
const body = data instanceof FormData ? data : JSON.stringify(data);
|
||||
|
||||
return this.request<T>(endpoint, {
|
||||
method: 'PATCH',
|
||||
body,
|
||||
token,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const apiClient = new ApiClient();
|
||||
Reference in New Issue
Block a user