84 lines
2.6 KiB
TypeScript
84 lines
2.6 KiB
TypeScript
import { logout } from '../utils/auth';
|
|
|
|
const BASE_URL = 'https://teleems-api-gateway.onrender.com';
|
|
|
|
interface RequestOptions extends RequestInit {
|
|
token?: string;
|
|
}
|
|
|
|
/**
|
|
* Centralized API client that handles automatic token injection
|
|
* and global error handling (like 401 Unauthorized)
|
|
*/
|
|
export const apiClient = {
|
|
request: async (endpoint: string, options: RequestOptions = {}) => {
|
|
const { token, headers, ...rest } = options;
|
|
|
|
// Use provided token or get from localStorage
|
|
const authToken = token || localStorage.getItem('teleems_token');
|
|
|
|
const defaultHeaders: Record<string, string> = {
|
|
'Content-Type': 'application/json',
|
|
};
|
|
|
|
if (authToken) {
|
|
defaultHeaders['Authorization'] = `Bearer ${authToken}`;
|
|
}
|
|
|
|
|
|
const url = endpoint.startsWith('http') ? endpoint : `${BASE_URL}${endpoint}`;
|
|
console.log(`[API] ${options.method || 'GET'} ${url}`);
|
|
try {
|
|
const response = await fetch(url, {
|
|
headers: { ...defaultHeaders, ...headers },
|
|
...rest,
|
|
});
|
|
|
|
// Handle session expiration
|
|
if (response.status === 401 && !url.includes('/auth/login')) {
|
|
console.warn('Token expired or invalid. Triggering auto-logout...');
|
|
logout();
|
|
return null; // Return null as the app will redirect
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
return { ...data, status: response.status };
|
|
}
|
|
|
|
return data;
|
|
} catch (error) {
|
|
console.error('API Request Error:', error);
|
|
throw error;
|
|
}
|
|
},
|
|
|
|
get: (endpoint: string, options: RequestOptions = {}) =>
|
|
apiClient.request(endpoint, { ...options, method: 'GET' }),
|
|
|
|
post: (endpoint: string, body: any, options: RequestOptions = {}) =>
|
|
apiClient.request(endpoint, {
|
|
...options,
|
|
method: 'POST',
|
|
body: JSON.stringify(body)
|
|
}),
|
|
|
|
put: (endpoint: string, body: any, options: RequestOptions = {}) =>
|
|
apiClient.request(endpoint, {
|
|
...options,
|
|
method: 'PUT',
|
|
body: JSON.stringify(body)
|
|
}),
|
|
|
|
patch: (endpoint: string, body: any, options: RequestOptions = {}) =>
|
|
apiClient.request(endpoint, {
|
|
...options,
|
|
method: 'PATCH',
|
|
body: JSON.stringify(body)
|
|
}),
|
|
|
|
delete: (endpoint: string, options: RequestOptions = {}) =>
|
|
apiClient.request(endpoint, { ...options, method: 'DELETE' }),
|
|
};
|