210 lines
5.1 KiB
TypeScript
210 lines
5.1 KiB
TypeScript
|
|
import axios from 'axios';
|
||
|
|
|
||
|
|
// Configure axios base URL for API calls
|
||
|
|
axios.defaults.baseURL = '/api/v1';
|
||
|
|
|
||
|
|
// Types for API responses
|
||
|
|
export interface ApiResponse<T = any> {
|
||
|
|
success: boolean;
|
||
|
|
data: T;
|
||
|
|
message: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface ApiError {
|
||
|
|
success: false;
|
||
|
|
message: string;
|
||
|
|
errors?: Record<string, string[]>;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface PaginatedResponse<T> {
|
||
|
|
data: T[];
|
||
|
|
pagination: {
|
||
|
|
current_page: number;
|
||
|
|
last_page: number;
|
||
|
|
per_page: number;
|
||
|
|
total: number;
|
||
|
|
from: number | null;
|
||
|
|
to: number | null;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// Article types
|
||
|
|
export interface Article {
|
||
|
|
id: number;
|
||
|
|
feed_id: number;
|
||
|
|
url: string;
|
||
|
|
title: string;
|
||
|
|
description: string;
|
||
|
|
is_valid: boolean;
|
||
|
|
is_duplicate: boolean;
|
||
|
|
approval_status: 'pending' | 'approved' | 'rejected';
|
||
|
|
approved_at: string | null;
|
||
|
|
approved_by: string | null;
|
||
|
|
fetched_at: string | null;
|
||
|
|
validated_at: string | null;
|
||
|
|
created_at: string;
|
||
|
|
updated_at: string;
|
||
|
|
feed?: Feed;
|
||
|
|
article_publication?: ArticlePublication;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Feed types
|
||
|
|
export interface Feed {
|
||
|
|
id: number;
|
||
|
|
name: string;
|
||
|
|
url: string;
|
||
|
|
type: 'website' | 'rss';
|
||
|
|
is_active: boolean;
|
||
|
|
description: string | null;
|
||
|
|
created_at: string;
|
||
|
|
updated_at: string;
|
||
|
|
articles_count?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Other types
|
||
|
|
export interface ArticlePublication {
|
||
|
|
id: number;
|
||
|
|
article_id: number;
|
||
|
|
status: string;
|
||
|
|
published_at: string | null;
|
||
|
|
created_at: string;
|
||
|
|
updated_at: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface PlatformAccount {
|
||
|
|
id: number;
|
||
|
|
platform_instance_id: number;
|
||
|
|
account_id: string;
|
||
|
|
username: string;
|
||
|
|
display_name: string | null;
|
||
|
|
description: string | null;
|
||
|
|
is_active: boolean;
|
||
|
|
created_at: string;
|
||
|
|
updated_at: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface PlatformChannel {
|
||
|
|
id: number;
|
||
|
|
platform_instance_id: number;
|
||
|
|
channel_id: string;
|
||
|
|
name: string;
|
||
|
|
display_name: string | null;
|
||
|
|
description: string | null;
|
||
|
|
is_active: boolean;
|
||
|
|
created_at: string;
|
||
|
|
updated_at: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface Settings {
|
||
|
|
article_processing_enabled: boolean;
|
||
|
|
publishing_approvals_enabled: boolean;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface DashboardStats {
|
||
|
|
article_stats: {
|
||
|
|
total_today: number;
|
||
|
|
total_week: number;
|
||
|
|
total_month: number;
|
||
|
|
approved_today: number;
|
||
|
|
approved_week: number;
|
||
|
|
approved_month: number;
|
||
|
|
approval_percentage_today: number;
|
||
|
|
approval_percentage_week: number;
|
||
|
|
approval_percentage_month: number;
|
||
|
|
};
|
||
|
|
system_stats: {
|
||
|
|
total_feeds: number;
|
||
|
|
active_feeds: number;
|
||
|
|
total_platform_accounts: number;
|
||
|
|
active_platform_accounts: number;
|
||
|
|
total_platform_channels: number;
|
||
|
|
active_platform_channels: number;
|
||
|
|
total_routes: number;
|
||
|
|
active_routes: number;
|
||
|
|
};
|
||
|
|
available_periods: Array<{ value: string; label: string }>;
|
||
|
|
current_period: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
// API Client class
|
||
|
|
class ApiClient {
|
||
|
|
constructor() {
|
||
|
|
this.setupInterceptors();
|
||
|
|
}
|
||
|
|
|
||
|
|
private setupInterceptors() {
|
||
|
|
// Response interceptor to handle errors
|
||
|
|
axios.interceptors.response.use(
|
||
|
|
(response) => response,
|
||
|
|
(error) => {
|
||
|
|
console.error('API Error:', error);
|
||
|
|
return Promise.reject(error);
|
||
|
|
}
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Dashboard endpoints
|
||
|
|
async getDashboardStats(period = 'today'): Promise<DashboardStats> {
|
||
|
|
const response = await axios.get<ApiResponse<DashboardStats>>('/dashboard/stats', {
|
||
|
|
params: { period }
|
||
|
|
});
|
||
|
|
return response.data.data;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Articles endpoints
|
||
|
|
async getArticles(page = 1, perPage = 15): Promise<{ articles: Article[]; pagination: any; settings: any }> {
|
||
|
|
const response = await axios.get<ApiResponse<{ articles: Article[]; pagination: any; settings: any }>>('/articles', {
|
||
|
|
params: { page, per_page: perPage }
|
||
|
|
});
|
||
|
|
return response.data.data;
|
||
|
|
}
|
||
|
|
|
||
|
|
async approveArticle(articleId: number): Promise<Article> {
|
||
|
|
const response = await axios.post<ApiResponse<Article>>(`/articles/${articleId}/approve`);
|
||
|
|
return response.data.data;
|
||
|
|
}
|
||
|
|
|
||
|
|
async rejectArticle(articleId: number): Promise<Article> {
|
||
|
|
const response = await axios.post<ApiResponse<Article>>(`/articles/${articleId}/reject`);
|
||
|
|
return response.data.data;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Feeds endpoints
|
||
|
|
async getFeeds(): Promise<Feed[]> {
|
||
|
|
const response = await axios.get<ApiResponse<Feed[]>>('/feeds');
|
||
|
|
return response.data.data;
|
||
|
|
}
|
||
|
|
|
||
|
|
async createFeed(data: Partial<Feed>): Promise<Feed> {
|
||
|
|
const response = await axios.post<ApiResponse<Feed>>('/feeds', data);
|
||
|
|
return response.data.data;
|
||
|
|
}
|
||
|
|
|
||
|
|
async updateFeed(id: number, data: Partial<Feed>): Promise<Feed> {
|
||
|
|
const response = await axios.put<ApiResponse<Feed>>(`/feeds/${id}`, data);
|
||
|
|
return response.data.data;
|
||
|
|
}
|
||
|
|
|
||
|
|
async deleteFeed(id: number): Promise<void> {
|
||
|
|
await axios.delete(`/feeds/${id}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
async toggleFeed(id: number): Promise<Feed> {
|
||
|
|
const response = await axios.post<ApiResponse<Feed>>(`/feeds/${id}/toggle`);
|
||
|
|
return response.data.data;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Settings endpoints
|
||
|
|
async getSettings(): Promise<Settings> {
|
||
|
|
const response = await axios.get<ApiResponse<Settings>>('/settings');
|
||
|
|
return response.data.data;
|
||
|
|
}
|
||
|
|
|
||
|
|
async updateSettings(data: Partial<Settings>): Promise<Settings> {
|
||
|
|
const response = await axios.put<ApiResponse<Settings>>('/settings', data);
|
||
|
|
return response.data.data;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export const apiClient = new ApiClient();
|