Files
promote/web/src/utils/api.ts

163 lines
5.6 KiB
TypeScript

import axios, { AxiosInstance, AxiosResponse } from 'axios';
import supabase from './supabase';
// Type definitions
interface LoginCredentials {
email: string;
password: string;
}
interface LoginResponse {
success: boolean;
token: string;
user: {
id: string;
email: string;
name?: string;
};
}
// Create a reusable Axios instance with default configuration
const apiClient: AxiosInstance = axios.create({
baseURL: 'http://localhost:4000',
headers: {
'Content-Type': 'application/json',
},
timeout: 10000, // 10 seconds timeout
});
// Request interceptor for adding auth token
apiClient.interceptors.request.use(
async (config) => {
// 从 Supabase 获取当前会话
const { data } = await supabase.auth.getSession();
const session = data.session;
if (session) {
config.headers.Authorization = `Bearer ${session.access_token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// Response interceptor for handling common errors
apiClient.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
// Handle errors globally
if (error.response) {
// Server responded with error status (4xx, 5xx)
if (error.response.status === 401) {
// Unauthorized - 可能是 token 过期,尝试刷新
try {
const { data, error: refreshError } = await supabase.auth.refreshSession();
if (refreshError || !data.session) {
// 刷新失败,重定向到登录页面
if (window.location.pathname !== '/login') {
window.location.href = '/login';
}
} else {
// 刷新成功,重试请求
const originalRequest = error.config;
originalRequest.headers.Authorization = `Bearer ${data.session.access_token}`;
return axios(originalRequest);
}
} catch (refreshError) {
console.error('Failed to refresh token:', refreshError);
// 重定向到登录页面
if (window.location.pathname !== '/login') {
window.location.href = '/login';
}
}
}
}
return Promise.reject(error);
}
);
// Auth API - 不再需要大部分方法,因为现在直接使用 Supabase
export const authApi = {
// 保留 verify 方法用于与后端验证
verify: async (): Promise<AxiosResponse> => {
const { data } = await supabase.auth.getSession();
const session = data.session;
if (!session) {
throw new Error('No active session');
}
return apiClient.get('/api/auth/verify', {
headers: {
Authorization: `Bearer ${session.access_token}`
}
});
}
};
// Comments API
export const commentsApi = {
getComments: (params?: Record<string, string | number | boolean>): Promise<AxiosResponse> =>
apiClient.get('/api/comments', { params }),
getComment: (id: string): Promise<AxiosResponse> =>
apiClient.get(`/api/comments/${id}`),
createComment: (data: Record<string, unknown>): Promise<AxiosResponse> =>
apiClient.post('/api/comments', data),
updateComment: (id: string, data: Record<string, unknown>): Promise<AxiosResponse> =>
apiClient.put(`/api/comments/${id}`, data),
deleteComment: (id: string): Promise<AxiosResponse> =>
apiClient.delete(`/api/comments/${id}`),
};
// Posts API
export const postsApi = {
getPosts: (params?: Record<string, string | number | boolean>): Promise<AxiosResponse> =>
apiClient.get('/api/posts', { params }),
getPost: (id: string): Promise<AxiosResponse> =>
apiClient.get(`/api/posts/${id}`),
createPost: (data: Record<string, unknown>): Promise<AxiosResponse> =>
apiClient.post('/api/posts', data),
updatePost: (id: string, data: Record<string, unknown>): Promise<AxiosResponse> =>
apiClient.put(`/api/posts/${id}`, data),
deletePost: (id: string): Promise<AxiosResponse> =>
apiClient.delete(`/api/posts/${id}`),
};
// Analytics API
export const analyticsApi = {
getPlatforms: (timeRange: string): Promise<AxiosResponse> =>
apiClient.get(`/api/analytics/platforms?timeRange=${timeRange}`),
getTimeline: (timeRange: string): Promise<AxiosResponse> =>
apiClient.get(`/api/analytics/timeline?timeRange=${timeRange}`),
getSentiment: (timeRange: string): Promise<AxiosResponse> =>
apiClient.get(`/api/analytics/sentiment?timeRange=${timeRange}`),
getStatus: (timeRange: string): Promise<AxiosResponse> =>
apiClient.get(`/api/analytics/status?timeRange=${timeRange}`),
getPopularContent: (timeRange: string): Promise<AxiosResponse> =>
apiClient.get(`/api/analytics/popular-content?timeRange=${timeRange}`),
getInfluencers: (timeRange: string): Promise<AxiosResponse> =>
apiClient.get(`/api/analytics/influencers?timeRange=${timeRange}`),
getConversion: (timeRange: string): Promise<AxiosResponse> =>
apiClient.get(`/api/analytics/conversion?timeRange=${timeRange}`),
};
// Templates API
export const templatesApi = {
getTemplates: (): Promise<AxiosResponse> =>
apiClient.get('/api/reply-templates'),
getTemplate: (id: string): Promise<AxiosResponse> =>
apiClient.get(`/api/reply-templates/${id}`),
createTemplate: (data: Record<string, unknown>): Promise<AxiosResponse> =>
apiClient.post('/api/reply-templates', data),
updateTemplate: (id: string, data: Record<string, unknown>): Promise<AxiosResponse> =>
apiClient.put(`/api/reply-templates/${id}`, data),
deleteTemplate: (id: string): Promise<AxiosResponse> =>
apiClient.delete(`/api/reply-templates/${id}`),
};
export default apiClient;