saas-market-analysis-dubai/frontend/src/services/api.js
2025-09-17 03:04:22 +05:30

136 lines
4.8 KiB
JavaScript

import axios from 'axios'
import toast from 'react-hot-toast'
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000/api/v1'
// Create axios instance
export const api = axios.create({
baseURL: API_BASE_URL,
headers: {
'Content-Type': 'application/json',
},
})
// Request interceptor to add auth token
api.interceptors.request.use(
(config) => {
const token = localStorage.getItem('accessToken')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
(error) => {
return Promise.reject(error)
}
)
// Response interceptor to handle token refresh
api.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config
if (error.response?.status === 401 && !originalRequest._retry) {
originalRequest._retry = true
try {
const refreshToken = localStorage.getItem('refreshToken')
if (refreshToken) {
const response = await axios.post(`${API_BASE_URL}/auth/refresh/`, {
refresh: refreshToken,
})
const { access } = response.data
localStorage.setItem('accessToken', access)
// Retry original request with new token
originalRequest.headers.Authorization = `Bearer ${access}`
return api(originalRequest)
} else {
// No refresh token, clear everything and redirect
localStorage.removeItem('accessToken')
localStorage.removeItem('refreshToken')
// Only redirect if not already on login page
if (window.location.pathname !== '/login') {
window.location.href = '/login'
}
}
} catch (refreshError) {
// Refresh failed, clear tokens but don't redirect if already on login
localStorage.removeItem('accessToken')
localStorage.removeItem('refreshToken')
if (window.location.pathname !== '/login') {
window.location.href = '/login'
}
return Promise.reject(refreshError)
}
}
// Handle other errors
if (error.response?.status >= 500) {
toast.error('Server error. Please try again later.')
} else if (error.response?.status === 403) {
toast.error('Access denied. You do not have permission to perform this action.')
} else if (error.response?.status === 404) {
toast.error('Resource not found.')
} else if (error.response?.data?.message) {
toast.error(error.response.data.message)
} else if (error.message) {
toast.error(error.message)
}
return Promise.reject(error)
}
)
// API endpoints
export const authAPI = {
login: (credentials) => api.post('/auth/login/', credentials),
register: (userData) => api.post('/auth/register/', userData),
logout: () => api.post('/auth/logout/'),
refresh: (refreshToken) => api.post('/auth/refresh/', { refresh: refreshToken }),
getUser: () => api.get('/auth/user/'),
updateUser: (userData) => api.patch('/auth/update/', userData),
changePassword: (passwordData) => api.post('/auth/change-password/', passwordData),
}
export const analyticsAPI = {
getTransactions: (params) => api.get('/analytics/transactions/', { params }),
getTransactionSummary: (params) => api.get('/analytics/summary/', { params }),
getAreaStats: (params) => api.get('/analytics/area-stats-data/', { params }),
getPropertyTypeStats: (params) => api.get('/analytics/property-type-stats/', { params }),
getTimeSeriesData: (params) => api.get('/analytics/time-series-data/', { params }),
getMarketAnalysis: (params) => api.get('/analytics/market-analysis/', { params }),
generateForecast: (data) => api.post('/analytics/forecast/', data),
}
export const reportsAPI = {
getReports: (params) => api.get('/reports/', { params }),
getReport: (id) => api.get(`/reports/${id}/`),
generateTransactionSummary: (data) => api.post('/reports/generate/transaction-summary/', data),
generateAreaAnalysis: (data) => api.post('/reports/generate/area-analysis/', data),
generateForecast: (data) => api.post('/reports/generate/forecast/', data),
downloadReport: (id) => api.get(`/reports/${id}/download/`, { responseType: 'blob' }),
}
export const usersAPI = {
getUsers: (params) => api.get('/auth/list/', { params }),
getUser: (id) => api.get(`/auth/${id}/`),
updateUser: (id, data) => api.patch(`/auth/${id}/`, data),
updateSubscription: (data) => api.post('/auth/update-subscription/', data),
toggleApiAccess: (data) => api.post('/auth/toggle-api-access/', data),
regenerateApiKey: () => api.post('/auth/regenerate-api-key/'),
}
export const billingAPI = {
getUsageStats: () => api.get('/billing/usage/'),
getSubscriptionInfo: () => api.get('/billing/subscription/'),
}
export const monitoringAPI = {
getMetrics: () => api.get('/monitoring/metrics/'),
getHealthCheck: () => api.get('/monitoring/health/'),
}