import axios from 'axios'; const API_BASE_URL = import.meta.env.VITE_API_URL || '/api'; const api = axios.create({ baseURL: API_BASE_URL, headers: { 'Content-Type': 'application/json', }, }); // Add auth token to requests api.interceptors.request.use((config) => { const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); // Handle auth errors api.interceptors.response.use( (response) => response, (error) => { if (error.response?.status === 401) { localStorage.removeItem('token'); localStorage.removeItem('user'); window.location.href = '/login'; } return Promise.reject(error); } ); // Auth API export const authApi = { register: (email: string, password: string) => api.post('/auth/register', { email, password }), login: (email: string, password: string) => api.post('/auth/login', { email, password }), getRegistrationStatus: () => api.get<{ registration_enabled: boolean }>('/auth/registration-status'), }; // Products API export type StockStatus = 'in_stock' | 'out_of_stock' | 'unknown'; export interface SparklinePoint { price: number; recorded_at: string; } export interface Product { id: number; user_id: number; url: string; name: string | null; image_url: string | null; refresh_interval: number; last_checked: string | null; stock_status: StockStatus; price_drop_threshold: number | null; target_price: number | null; notify_back_in_stock: boolean; created_at: string; current_price: number | null; currency: string | null; sparkline?: SparklinePoint[]; price_change_7d?: number | null; min_price?: number | null; } export interface ProductWithStats extends Product { stats: { min_price: number; max_price: number; avg_price: number; price_count: number; } | null; } export interface PriceHistory { id: number; product_id: number; price: number; currency: string; recorded_at: string; } export const productsApi = { getAll: () => api.get('/products'), getById: (id: number) => api.get(`/products/${id}`), create: (url: string, refreshInterval?: number) => api.post('/products', { url, refresh_interval: refreshInterval }), update: (id: number, data: { name?: string; refresh_interval?: number; price_drop_threshold?: number | null; target_price?: number | null; notify_back_in_stock?: boolean; }) => api.put(`/products/${id}`, data), delete: (id: number) => api.delete(`/products/${id}`), }; // Prices API export const pricesApi = { getHistory: (productId: number, days?: number) => api.get<{ product: Product; prices: PriceHistory[] }>( `/products/${productId}/prices`, { params: days ? { days } : undefined } ), refresh: (productId: number) => api.post<{ message: string; price: PriceHistory }>( `/products/${productId}/refresh` ), }; // Settings API export interface NotificationSettings { telegram_configured: boolean; telegram_chat_id: string | null; discord_configured: boolean; } export const settingsApi = { getNotifications: () => api.get('/settings/notifications'), updateNotifications: (data: { telegram_bot_token?: string | null; telegram_chat_id?: string | null; discord_webhook_url?: string | null; }) => api.put('/settings/notifications', data), testTelegram: () => api.post<{ message: string }>('/settings/notifications/test/telegram'), testDiscord: () => api.post<{ message: string }>('/settings/notifications/test/discord'), // AI Settings getAI: () => api.get('/settings/ai'), updateAI: (data: { ai_enabled?: boolean; ai_provider?: 'anthropic' | 'openai' | null; anthropic_api_key?: string | null; openai_api_key?: string | null; }) => api.put('/settings/ai', data), testAI: (url: string) => api.post('/settings/ai/test', { url }), }; // AI Settings types export interface AISettings { ai_enabled: boolean; ai_provider: 'anthropic' | 'openai' | null; anthropic_configured: boolean; openai_configured: boolean; } export interface AITestResult { success: boolean; name: string | null; price: { price: number; currency: string } | null; imageUrl: string | null; stockStatus: string; confidence: number; } // Profile API export interface UserProfile { id: number; email: string; name: string | null; is_admin: boolean; created_at: string; } export const profileApi = { get: () => api.get('/profile'), update: (data: { name?: string }) => api.put('/profile', data), changePassword: (currentPassword: string, newPassword: string) => api.put<{ message: string }>('/profile/password', { current_password: currentPassword, new_password: newPassword, }), }; // Admin API export interface SystemSettings { registration_enabled: string; } export const adminApi = { getUsers: () => api.get('/admin/users'), createUser: (email: string, password: string, isAdmin: boolean) => api.post<{ message: string; user: UserProfile }>('/admin/users', { email, password, is_admin: isAdmin, }), deleteUser: (id: number) => api.delete(`/admin/users/${id}`), setUserAdmin: (id: number, isAdmin: boolean) => api.put(`/admin/users/${id}/admin`, { is_admin: isAdmin }), getSettings: () => api.get('/admin/settings'), updateSettings: (data: { registration_enabled?: boolean }) => api.put('/admin/settings', data), }; export default api;