const BASE_URL = process.env.REACT_APP_API_URL || '/api';
class ApiError extends Error {
constructor(message, status, data) {
super(message);
this.name = 'ApiError';
this.status = status;
this.data = data;
}
}
async function handleResponse(response) {
const contentType = response.headers.get('content-type');
const isJson = contentType?.includes('application/json');
const data = isJson ? await response.json() : await response.text();
if (!response.ok) {
throw new ApiError(
data.message || 'Request failed',
response.status,
data
);
}
return data;
}
function getHeaders() {
const headers = {
'Content-Type': 'application/json',
};
const token = localStorage.getItem('auth_token');
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
return headers;
}
export const apiClient = {
async get(endpoint, options = {}) {
const response = await fetch(`${BASE_URL}${endpoint}`, {
method: 'GET',
headers: getHeaders(),
...options,
});
return handleResponse(response);
},
async post(endpoint, data, options = {}) {
const response = await fetch(`${BASE_URL}${endpoint}`, {
method: 'POST',
headers: getHeaders(),
body: JSON.stringify(data),
...options,
});
return handleResponse(response);
},
async put(endpoint, data, options = {}) {
const response = await fetch(`${BASE_URL}${endpoint}`, {
method: 'PUT',
headers: getHeaders(),
body: JSON.stringify(data),
...options,
});
return handleResponse(response);
},
async delete(endpoint, options = {}) {
const response = await fetch(`${BASE_URL}${endpoint}`, {
method: 'DELETE',
headers: getHeaders(),
...options,
});
return handleResponse(response);
},
};