const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8080"; export class ApiError extends Error { constructor( message: string, public statusCode: number, public code?: string ) { super(message); this.name = "ApiError"; } } export async function apiRequest( endpoint: string, options: RequestInit = {} ): Promise { const url = `${API_BASE_URL}${endpoint}`; const defaultHeaders = { "Content-Type": "application/json", }; const config: RequestInit = { ...options, headers: { ...defaultHeaders, ...options.headers, }, }; try { const response = await fetch(url, config); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new ApiError( errorData.message || `HTTP error! status: ${response.status}`, response.status, errorData.code ); } return await response.json(); } catch (error) { if (error instanceof ApiError) { throw error; } throw new ApiError("Network error", 0); } } export const api = { get: (endpoint: string, headers?: HeadersInit) => apiRequest(endpoint, { method: "GET", headers }), post: (endpoint: string, data?: unknown, headers?: HeadersInit) => apiRequest(endpoint, { method: "POST", body: JSON.stringify(data), headers, }), put: (endpoint: string, data?: unknown, headers?: HeadersInit) => apiRequest(endpoint, { method: "PUT", body: JSON.stringify(data), headers, }), delete: (endpoint: string, headers?: HeadersInit) => apiRequest(endpoint, { method: "DELETE", headers }), };