[Restore from backup: vip-coordinator-backup-2025-06-08-00-29-user and admin online ready for dockerhub]
80 lines
2.0 KiB
TypeScript
80 lines
2.0 KiB
TypeScript
// API Configuration
|
|
// Use relative URLs by default so it works with any domain/reverse proxy
|
|
export const API_BASE_URL = (import.meta as any).env.VITE_API_URL || '';
|
|
|
|
// API Error class
|
|
export class ApiError extends Error {
|
|
constructor(
|
|
message: string,
|
|
public status?: number,
|
|
public code?: string,
|
|
public details?: unknown
|
|
) {
|
|
super(message);
|
|
this.name = 'ApiError';
|
|
}
|
|
}
|
|
|
|
// Helper function for API calls with error handling
|
|
export const apiCall = async (endpoint: string, options?: RequestInit) => {
|
|
const url = endpoint.startsWith('/') ? `${API_BASE_URL}${endpoint}` : endpoint;
|
|
|
|
// Get auth token from localStorage
|
|
const authToken = localStorage.getItem('authToken');
|
|
|
|
// Build headers
|
|
const headers: HeadersInit = {
|
|
'Content-Type': 'application/json',
|
|
...options?.headers,
|
|
};
|
|
|
|
// Add authorization header if token exists
|
|
if (authToken) {
|
|
headers['Authorization'] = `Bearer ${authToken}`;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(url, {
|
|
...options,
|
|
headers,
|
|
});
|
|
|
|
// Handle non-2xx responses
|
|
if (!response.ok) {
|
|
let errorData;
|
|
try {
|
|
errorData = await response.json();
|
|
} catch {
|
|
errorData = { error: { message: response.statusText } };
|
|
}
|
|
|
|
throw new ApiError(
|
|
errorData.error?.message || `Request failed with status ${response.status}`,
|
|
response.status,
|
|
errorData.error?.code,
|
|
errorData.error?.details
|
|
);
|
|
}
|
|
|
|
// Try to parse JSON response
|
|
const contentType = response.headers.get('content-type');
|
|
if (contentType && contentType.includes('application/json')) {
|
|
const data = await response.json();
|
|
return { response, data };
|
|
}
|
|
|
|
return { response, data: null };
|
|
} catch (error) {
|
|
// Network errors or other issues
|
|
if (error instanceof ApiError) {
|
|
throw error;
|
|
}
|
|
|
|
throw new ApiError(
|
|
error instanceof Error ? error.message : 'Network request failed',
|
|
undefined,
|
|
'NETWORK_ERROR'
|
|
);
|
|
}
|
|
};
|