This commit is contained in:
NotII
2025-03-10 17:39:37 +00:00
parent c08df8919d
commit 20d5559832
69 changed files with 7676 additions and 78 deletions

View File

@@ -21,65 +21,77 @@ function getAuthToken(): string | null {
?.split('=')[1] || null;
}
/**
* Gets the API base URL for client-side fetch calls
*/
function getClientApiBaseUrl(): string {
// For client-side, we can access window.location if in browser
if (typeof window !== 'undefined') {
// Use the same origin (which includes the correct port)
return `${window.location.origin}/api`;
}
// Fallback when window is not available
// For development mode, use port 3001 to match our server
if (process.env.NODE_ENV === 'development') {
return 'http://localhost:3001/api';
}
// Default fallback - relative URL
return '/api';
}
export async function fetchClient<T>(
endpoint: string,
options: FetchOptions = {}
): Promise<T> {
const { method = 'GET', body, headers = {}, ...rest } = options;
// Get the base API URL from environment or fallback
const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001';
// Ensure the endpoint starts with a slash
const normalizedEndpoint = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
// For the specific case of internal-api.inboxi.ng - remove duplicate /api
let url;
if (apiUrl.includes('internal-api.inboxi.ng')) {
// Special case for internal-api.inboxi.ng
if (normalizedEndpoint.startsWith('/api/')) {
url = `${apiUrl}${normalizedEndpoint.substring(4)}`; // Remove the /api part
} else {
url = `${apiUrl}${normalizedEndpoint}`;
}
} else {
// Normal case for other environments
url = `${apiUrl}${normalizedEndpoint}`;
}
// Get auth token from cookies
const authToken = getAuthToken();
// Prepare headers with authentication if token exists
const requestHeaders: Record<string, string> = {
'Content-Type': 'application/json',
...(headers as Record<string, string>),
};
if (authToken) {
// Backend expects "Bearer TOKEN" format
requestHeaders['Authorization'] = `Bearer ${authToken}`;
console.log('Authorization header set to:', `Bearer ${authToken.substring(0, 10)}...`);
}
console.log('API Request:', {
url,
method,
hasAuthToken: !!authToken
});
const fetchOptions: RequestInit = {
method,
credentials: 'include',
headers: requestHeaders,
...rest,
};
if (body && method !== 'GET') {
fetchOptions.body = JSON.stringify(body);
}
try {
// Get the base API URL
const baseUrl = getClientApiBaseUrl();
// Ensure endpoint doesn't start with a slash if baseUrl ends with one
const normalizedEndpoint = endpoint.startsWith('/') ? endpoint.substring(1) : endpoint;
// Ensure baseUrl ends with a slash if it doesn't already
const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;
// Combine them for the final URL
const url = `${normalizedBaseUrl}${normalizedEndpoint}`;
// Get auth token from cookies
const authToken = getAuthToken();
// Prepare headers with authentication if token exists
const requestHeaders: Record<string, string> = {
'Content-Type': 'application/json',
...(headers as Record<string, string>),
};
if (authToken) {
// Backend expects "Bearer TOKEN" format
requestHeaders['Authorization'] = `Bearer ${authToken}`;
console.log('Authorization header set to:', `Bearer ${authToken.substring(0, 10)}...`);
}
console.log('API Request:', {
url,
method,
hasAuthToken: !!authToken
});
const fetchOptions: RequestInit = {
method,
credentials: 'include',
headers: requestHeaders,
...rest,
};
if (body && method !== 'GET') {
fetchOptions.body = JSON.stringify(body);
}
const response = await fetch(url, fetchOptions);
if (!response.ok) {
@@ -97,6 +109,7 @@ export async function fetchClient<T>(
return data;
} catch (error) {
console.error('API request failed:', error);
console.error('Error details:', error instanceof Error ? error.message : 'Unknown error');
// Only show toast if this is a client-side error (not during SSR)
if (typeof window !== 'undefined') {