export const apiRequest = async (url: string, options: RequestInit = {}) => { const token = localStorage.getItem('token'); const allowedRequests = [ '/api/auth/login', '/api/auth/register', ] if (allowedRequests.includes(url)) { return publicRequest(url, options) } if (!token) { throw new Error('No authentication token found.' + url); } return privateRequest(url, token, options); }; export const publicRequest = async (fullUrl: string, options: RequestInit = {}) => { console.log('→ Sending request', fullUrl, options.method); const url = `${process.env.NEXT_PUBLIC_API_URL}${fullUrl}`; const response = await fetch(url, { headers: { ...(options.headers || {}), }, ...options, }); if (!response.ok) { throw new Error(`HTTP Error: ${response.status} ${response.statusText}`); } return response.json(); } export const privateRequest = async (fullUrl: string, token: string, options: RequestInit = {}) => { const headers = { ...(options.headers || {}), Authorization: `Bearer ${token}`, }; const url = `${process.env.NEXT_PUBLIC_API_URL}${fullUrl}`; const response = await fetch(url, { headers, ...options }); // Authentication failure - token invalid - redirect to login if (response.status === 401) { localStorage.removeItem('token'); localStorage.removeItem('refreshToken'); window.location.href = '/login'; throw new Error('Unauthorized. Redirecting to login.'); } if (!response.ok) { throw new Error(`HTTP Error: ${response.status} ${response.statusText}`); } return response.json(); } // Add shorthand HTTP methods apiRequest.get = (url: string, options: RequestInit = {}) => { return apiRequest(url, { ...options, method: 'GET' }); }; apiRequest.post = | undefined>( url: string, body: TBody, options: RequestInit = {} ) => { return apiRequest(url, { ...options, method: 'POST', headers: { 'Content-Type': 'application/json', ...(options.headers || {}), }, body: body ? JSON.stringify(body) : undefined, }); }; apiRequest.put = | undefined>( url: string, body: TBody, options: RequestInit = {} ) => { return apiRequest(url, { ...options, method: 'PUT', headers: { 'Content-Type': 'application/json', ...(options.headers || {}), }, body: body ? JSON.stringify(body) : undefined, }); }; apiRequest.delete = (url: string, options: RequestInit = {}) => { return apiRequest(url, { ...options, method: 'DELETE' }); };