implement TeleEMS platform architecture with centralized API client and master data management system
This commit is contained in:
134
src/api/apiClient.ts
Normal file
134
src/api/apiClient.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
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}`;
|
||||
}
|
||||
|
||||
// --- MOCK BYPASS FOR DEMO SESSIONS ---
|
||||
if (authToken && (
|
||||
authToken.startsWith('mock-') ||
|
||||
authToken.startsWith('dev-token-') ||
|
||||
authToken === 'dev-super-token-2026'
|
||||
)) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
if (endpoint.includes('/v1/incidents')) {
|
||||
resolve({
|
||||
status: 200,
|
||||
data: [
|
||||
{
|
||||
id: 'INC-MOCK-001',
|
||||
category: 'MEDICAL',
|
||||
severity: 'CRITICAL',
|
||||
status: 'PENDING',
|
||||
address: 'Sector 7G, Tactical Hub',
|
||||
notes: 'High-priority mock incident for system validation.',
|
||||
createdAt: new Date().toISOString(),
|
||||
gps_lat: 13.0827,
|
||||
gps_lon: 80.2707,
|
||||
patients: [{ name: 'Tactical Test', age: 34, gender: 'Male', symptoms: ['None'], triage_code: 'RED' }]
|
||||
}
|
||||
]
|
||||
});
|
||||
} else if (endpoint.includes('/v1/auth/users')) {
|
||||
resolve({
|
||||
status: 200,
|
||||
data: [
|
||||
{ id: 'u1', username: 'admin', roles: ['CURESELECT_ADMIN'], status: 'ACTIVE', email: 'admin@teleems.com' },
|
||||
{ id: 'u2', username: 'fleet_op', roles: ['FLEET_OPERATOR'], status: 'ACTIVE', email: 'fleet@teleems.com' }
|
||||
]
|
||||
});
|
||||
} else if (endpoint.includes('/v1/auth/audit-logs')) {
|
||||
resolve({
|
||||
status: 200,
|
||||
data: {
|
||||
logs: [
|
||||
{ id: 'l1', action: 'LOGIN_SUCCESS', createdAt: new Date().toISOString(), ipAddress: '127.0.0.1', user: { username: 'admin' } },
|
||||
{ id: 'l2', action: 'INCIDENT_VIEW', createdAt: new Date().toISOString(), ipAddress: '127.0.0.1', user: { username: 'admin' } }
|
||||
],
|
||||
total: 2
|
||||
}
|
||||
});
|
||||
} else {
|
||||
resolve({ status: 200, data: [] });
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
|
||||
const url = endpoint.startsWith('http') ? endpoint : `${BASE_URL}${endpoint}`;
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
headers: { ...defaultHeaders, ...headers },
|
||||
...rest,
|
||||
});
|
||||
|
||||
// Handle session expiration
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
console.warn('Unauthorized request detected. 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' }),
|
||||
};
|
||||
Reference in New Issue
Block a user