fedi-feed-router/frontend/src/lib/api.ts

210 lines
5.1 KiB
TypeScript
Raw Normal View History

2025-08-03 01:34:11 +02:00
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();