Newer
Older
cortex-hub / frontend / src / services / api / apiClient.js
export const API_BASE_URL = process.env.REACT_APP_API_BASE_URL || "http://localhost:8001";

/**
 * A central utility function to get the user ID.
 * If not found, it redirects to the login page.
 * @returns {string} The user ID.
 */
export const getUserId = () => {
  const userId = localStorage.getItem('userId');
  if (!userId) {
    console.error("User not authenticated. Redirecting to login.");
    // Redirect to the login page
    window.location.href = '/';
  }
  return userId;
};

/**
 * Base fetch utility with common headers and error handling.
 */
export const fetchWithAuth = async (endpoint, options = {}) => {
  const userId = options.anonymous ? 'anonymous' : getUserId();
  const token = localStorage.getItem('authToken');
  
  const headers = {
    "X-User-ID": userId,
    ...options.headers,
  };

  // If we have a JWT token, use it as the primary authentication method
  if (token) {
    headers["Authorization"] = `Bearer ${token}`;
  }

  if (options.json !== false && options.body && !(options.body instanceof FormData)) {
    headers["Content-Type"] = "application/json";
    options.body = JSON.stringify(options.body);
  }

  const url = endpoint.startsWith('http') ? endpoint : `${API_BASE_URL}${endpoint}`;
  
  const response = await fetch(url, {
    ...options,
    headers,
  });

  if (!response.ok) {
    let detail = `API error (${response.status})`;
    try {
      const errBody = await response.json();
      if (errBody.detail) {
        detail = typeof errBody.detail === 'string' 
          ? errBody.detail 
          : JSON.stringify(errBody.detail);
      }
    } catch { }
    throw new Error(detail);
  }

  if (options.raw) return response;
  return await response.json();
};