'use client'; import { toast } from "@/components/ui/use-toast"; type FetchMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'; interface FetchOptions { method?: FetchMethod; body?: any; cache?: RequestCache; headers?: HeadersInit; } // Helper function to get auth token from cookies function getAuthToken(): string | null { if (typeof document === 'undefined') return null; // Guard for SSR return document.cookie .split('; ') .find(row => row.startsWith('Authorization=')) ?.split('=')[1] || null; } export async function fetchClient( endpoint: string, options: FetchOptions = {} ): Promise { 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 = { 'Content-Type': 'application/json', ...(headers as Record), }; if (authToken) { requestHeaders['Authorization'] = `Bearer ${authToken}`; } 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 { const response = await fetch(url, fetchOptions); if (!response.ok) { const errorData = await response.json().catch(() => ({})); const errorMessage = errorData.message || errorData.error || 'An error occurred'; throw new Error(errorMessage); } if (response.status === 204) { return {} as T; } const data = await response.json(); return data; } catch (error) { console.error('API request failed:', error); // Only show toast if this is a client-side error (not during SSR) if (typeof window !== 'undefined') { const message = error instanceof Error ? error.message : 'Failed to connect to server'; toast({ title: 'Error', description: message, variant: 'destructive', }); } throw error; } }