// Use relative path since dashboard is served from same origin const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || ''; const API_KEY = process.env.NEXT_PUBLIC_DASHBOARD_API_KEY || ''; async function fetchAPI(endpoint: string, options: RequestInit = {}): Promise { const url = `${API_BASE_URL}${endpoint}`; const headers: HeadersInit = { 'Content-Type': 'application/json', ...(API_KEY ? { 'X-Dashboard-Key': API_KEY } : {}), ...options.headers, }; try { const response = await fetch(url, { ...options, headers, }); if (!response.ok) { console.error(`API error: ${response.status} ${response.statusText} for ${endpoint}`); throw new Error(`API error: ${response.status} ${response.statusText}`); } return response.json(); } catch (error) { console.error(`Failed to fetch ${endpoint}:`, error); throw error; } } // Default/fallback data for when API is unavailable const defaultStats = { uptime_seconds: 0, total_requests: 0, total_errors: 0, error_rate: 0, active_requests: 0, total_input_tokens: 0, total_output_tokens: 0, requests_by_model: {}, tokens_by_model: {}, avg_latency_ms: 0, p50_latency_ms: 0, p95_latency_ms: 0, p99_latency_ms: 0, accounts_total: 0, accounts_healthy: 0, accounts_unhealthy: 0, }; export const api = { getStats: async () => { try { return await fetchAPI('/api/dashboard/stats'); } catch { return defaultStats as import('@/types/metrics').DashboardStats; } }, getMetrics: async (params?: { start_time?: string; end_time?: string; model?: string; granularity?: string; limit?: number }) => { try { const searchParams = new URLSearchParams(); if (params?.start_time) searchParams.set('start_time', params.start_time); if (params?.end_time) searchParams.set('end_time', params.end_time); if (params?.model) searchParams.set('model', params.model); if (params?.granularity) searchParams.set('granularity', params.granularity); if (params?.limit) searchParams.set('limit', params.limit.toString()); const queryString = searchParams.toString(); return await fetchAPI( `/api/dashboard/metrics${queryString ? `?${queryString}` : ''}` ); } catch { return { query: { granularity: '1m', limit: 100 }, data: [], total_requests: 0, total_errors: 0, total_input_tokens: 0, total_output_tokens: 0 } as import('@/types/metrics').MetricsResponse; } }, getAccounts: async () => { try { return await fetchAPI('/api/dashboard/accounts'); } catch { return [] as import('@/types/metrics').Account[]; } }, getConfig: async () => { try { return await fetchAPI('/api/dashboard/config'); } catch { return null; } }, getHealth: async () => { try { return await fetchAPI('/api/dashboard/health'); } catch { return { status: 'unhealthy', version: 'unknown', uptime_seconds: 0, auth_healthy: false, api_reachable: false, accounts_status: null, metrics_enabled: false, prometheus_ready: false } as import('@/types/metrics').HealthResponse; } }, }; export default api;