import axios from 'axios'; import toast from 'react-hot-toast'; // Base API configuration const API_BASE_URL = process.env.REACT_APP_API_URL || 'http://localhost:5000/api'; // Create axios instance const apiClient = axios.create({ baseURL: API_BASE_URL, timeout: 10000, headers: { 'Content-Type': 'application/json', }, }); // Rate limiting disabled - unlimited requests // let lastRequestTime = 0; // const MIN_REQUEST_INTERVAL = 0; // No delay between requests // Rate limiting interceptor disabled for unlimited requests // apiClient.interceptors.request.use(async (config) => { // return config; // }); // Request interceptor to add auth token apiClient.interceptors.request.use( (config) => { const token = localStorage.getItem('authToken'); console.log('Token from localStorage:', token); if (token && token !== 'undefined' && token !== 'null') { config.headers.Authorization = `Bearer ${token}`; } return config; }, (error) => { return Promise.reject(error); } ); // Response interceptor for error handling apiClient.interceptors.response.use( (response) => response, (error) => { // Handle specific error codes if (error.response?.status === 401 || error.response?.status === 403) { // Unauthorized or malformed token - clear token and redirect to login console.log('Clearing invalid token due to auth error:', error.response?.status); localStorage.removeItem('authToken'); // Use React Router navigation instead of hard redirect if (window.location.pathname !== '/login' && window.location.pathname !== '/register') { window.location.href = '/login'; } } else if (error.response?.status >= 500) { // Server error toast.error('Server error. Please try again later.'); } else if (error.code === 'ECONNABORTED') { // Timeout toast.error('Request timeout. Please check your connection.'); } else if (!error.response) { // Network error toast.error('Network error. Please check your connection.'); } return Promise.reject(error); } ); // Auth API endpoints export const authAPI = { login: (credentials) => apiClient.post('/auth/login', credentials), register: (userData) => apiClient.post('/auth/register', userData), getCurrentUser: () => apiClient.get('/auth/me'), changePassword: (passwordData) => apiClient.post('/auth/change-password', passwordData), forgotPassword: (email) => apiClient.post('/auth/forgot-password', { email }), }; // Users API endpoints export const usersAPI = { getProfile: () => apiClient.get('/users/profile'), updateProfile: (userData) => apiClient.put('/users/profile', userData), deleteAccount: () => apiClient.delete('/users/account'), getStats: () => apiClient.get('/users/stats'), }; // Properties API endpoints export const propertiesAPI = { getAll: () => apiClient.get('/properties'), getById: (id) => apiClient.get(`/properties/${id}`), create: (propertyData) => apiClient.post('/properties', propertyData), update: (id, propertyData) => apiClient.put(`/properties/${id}`, propertyData), delete: (id) => apiClient.delete(`/properties/${id}`), // Lawn sections createSection: (propertyId, sectionData) => apiClient.post(`/properties/${propertyId}/sections`, sectionData), updateSection: (propertyId, sectionId, sectionData) => apiClient.put(`/properties/${propertyId}/sections/${sectionId}`, sectionData), deleteSection: (propertyId, sectionId) => apiClient.delete(`/properties/${propertyId}/sections/${sectionId}`), }; // Equipment API endpoints export const equipmentAPI = { getAll: (params) => apiClient.get('/equipment', { params }), getById: (id) => apiClient.get(`/equipment/${id}`), create: (equipmentData) => apiClient.post('/equipment', equipmentData), update: (id, equipmentData) => apiClient.put(`/equipment/${id}`, equipmentData), delete: (id) => apiClient.delete(`/equipment/${id}`), getCategories: () => apiClient.get('/equipment/categories'), getTypes: (params) => apiClient.get('/equipment/types', { params }), getSpreaders: () => apiClient.get('/equipment/spreaders'), // Get user's spreader equipment getCalculations: (id, params) => apiClient.get(`/equipment/${id}/calculations`, { params }), }; // Nozzles API endpoints export const nozzlesAPI = { getAll: () => apiClient.get('/nozzles'), getById: (id) => apiClient.get(`/nozzles/${id}`), create: (nozzleData) => apiClient.post('/nozzles', nozzleData), update: (id, nozzleData) => apiClient.put(`/nozzles/${id}`, nozzleData), delete: (id) => apiClient.delete(`/nozzles/${id}`), getNozzleTypes: () => apiClient.get('/nozzles/types'), getUserNozzles: () => apiClient.get('/nozzles/user'), calculateFlowRate: (nozzleId, pressure) => apiClient.get(`/nozzles/${nozzleId}/flow-rate`, { params: { pressure } }), // Pump assignments getPumpAssignments: (sprayerId) => apiClient.get(`/nozzles/sprayer/${sprayerId}/pump-assignments`), assignPump: (sprayerId, pumpId) => apiClient.post(`/nozzles/sprayer/${sprayerId}/pump-assignments`, { pumpId }), unassignPump: (assignmentId) => apiClient.delete(`/nozzles/pump-assignments/${assignmentId}`), // Nozzle configurations getNozzleConfigurations: (sprayerId) => apiClient.get(`/nozzles/sprayer/${sprayerId}/nozzle-configurations`), addNozzleConfiguration: (sprayerId, configData) => apiClient.post(`/nozzles/sprayer/${sprayerId}/nozzle-configurations`, configData), removeNozzleConfiguration: (configId) => apiClient.delete(`/nozzles/nozzle-configurations/${configId}`), // Legacy endpoints for compatibility getTypes: (params) => apiClient.get('/nozzles/types', { params }), getAssignments: (equipmentId) => apiClient.get(`/nozzles/equipment/${equipmentId}/assignments`), assignToEquipment: (equipmentId, assignmentData) => apiClient.post(`/nozzles/equipment/${equipmentId}/assignments`, assignmentData), removeAssignment: (assignmentId) => apiClient.delete(`/nozzles/assignments/${assignmentId}`), }; // Products API endpoints export const productsAPI = { getAll: (params) => apiClient.get('/products', { params }), getById: (id) => apiClient.get(`/products/${id}`), search: (params) => apiClient.get('/products/search', { params }), getCategories: () => apiClient.get('/products/categories'), // User products getUserProducts: () => apiClient.get('/products/user'), createUserProduct: (productData) => apiClient.post('/products/user', productData), getUserProduct: (id) => apiClient.get(`/products/user/${id}`), updateUserProduct: (id, productData) => apiClient.put(`/products/user/${id}`, productData), deleteUserProduct: (id) => apiClient.delete(`/products/user/${id}`), }; // Applications API endpoints export const applicationsAPI = { // Plans getPlans: (params) => apiClient.get('/applications/plans', { params }), getPlan: (id) => apiClient.get(`/applications/plans/${id}`), createPlan: (planData) => apiClient.post('/applications/plans', planData), updatePlan: (id, planData) => apiClient.put(`/applications/plans/${id}`, planData), deletePlan: (id) => apiClient.delete(`/applications/plans/${id}`), updatePlanStatus: (id, status) => apiClient.put(`/applications/plans/${id}/status`, { status }), // Logs getLogs: (params) => apiClient.get('/applications/logs', { params }), createLog: (logData) => apiClient.post('/applications/logs', logData), // Stats getStats: (params) => apiClient.get('/applications/stats', { params }), }; // Spreader Settings API endpoints export const spreaderSettingsAPI = { getAll: () => apiClient.get('/spreader-settings'), getBrands: () => apiClient.get('/spreader-settings/brands'), getByBrand: (brand) => apiClient.get(`/spreader-settings/${brand}`), }; // Product Spreader Settings API endpoints export const productSpreaderSettingsAPI = { getByProduct: (productId) => apiClient.get(`/product-spreader-settings/product/${productId}`), getByUserProduct: (userProductId) => apiClient.get(`/product-spreader-settings/user-product/${userProductId}`), create: (settingData) => apiClient.post('/product-spreader-settings', settingData), update: (id, settingData) => apiClient.put(`/product-spreader-settings/${id}`, settingData), delete: (id) => apiClient.delete(`/product-spreader-settings/${id}`), }; // Weather API endpoints export const weatherAPI = { getCurrent: (propertyId) => apiClient.get(`/weather/${propertyId}`), getForecast: (propertyId) => apiClient.get(`/weather/${propertyId}/forecast`), getHistory: (propertyId, params) => apiClient.get(`/weather/${propertyId}/history`, { params }), checkSuitability: (propertyId, params) => apiClient.get(`/weather/conditions/suitable/${propertyId}`, { params }), }; // Admin API endpoints export const adminAPI = { getDashboard: () => apiClient.get('/admin/dashboard'), // Users management getUsers: (params) => apiClient.get('/admin/users', { params }), updateUserRole: (id, role) => apiClient.put(`/admin/users/${id}/role`, { role }), deleteUser: (id) => apiClient.delete(`/admin/users/${id}`), // Products management getProducts: (params) => apiClient.get('/admin/products', { params }), createProduct: (productData) => apiClient.post('/admin/products', productData), updateProduct: (id, productData) => apiClient.put(`/admin/products/${id}`, productData), deleteProduct: (id) => apiClient.delete(`/admin/products/${id}`), // System health getSystemHealth: () => apiClient.get('/admin/system/health'), }; // Utility functions export const handleApiError = (error, defaultMessage = 'An error occurred') => { if (error.response?.data?.message) { return error.response.data.message; } if (error.message) { return error.message; } return defaultMessage; }; export const formatApiResponse = (response) => { return response.data; }; // Export the configured axios instance for custom requests export default apiClient;