fedi-feed-router/resources/js/lib/api.ts

288 lines
7 KiB
TypeScript
Raw Normal View History

2025-08-02 15:28:38 +02:00
import axios from 'axios';
// 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;
};
}
// User types
export interface User {
id: number;
name: string;
email: string;
}
export interface LoginCredentials {
email: string;
password: string;
}
export interface RegisterData {
name: string;
email: string;
password: string;
password_confirmation: string;
}
export interface AuthResponse {
user: User;
token: string;
token_type: string;
}
// 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 {
private token: string | null = null;
constructor() {
// Get token from localStorage if available
this.token = localStorage.getItem('auth_token');
this.setupInterceptors();
}
private setupInterceptors() {
// Request interceptor to add auth token
axios.interceptors.request.use((config) => {
if (this.token) {
config.headers.Authorization = `Bearer ${this.token}`;
}
return config;
});
// Response interceptor to handle errors
axios.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
this.clearAuth();
window.location.href = '/login';
}
return Promise.reject(error);
}
);
}
setAuth(token: string, user: User) {
this.token = token;
localStorage.setItem('auth_token', token);
localStorage.setItem('user', JSON.stringify(user));
}
clearAuth() {
this.token = null;
localStorage.removeItem('auth_token');
localStorage.removeItem('user');
}
getUser(): User | null {
const userStr = localStorage.getItem('user');
return userStr ? JSON.parse(userStr) : null;
}
isAuthenticated(): boolean {
return !!this.token;
}
// Auth endpoints
async login(credentials: LoginCredentials): Promise<AuthResponse> {
const response = await axios.post<ApiResponse<AuthResponse>>('/auth/login', credentials);
return response.data.data;
}
async register(data: RegisterData): Promise<AuthResponse> {
const response = await axios.post<ApiResponse<AuthResponse>>('/auth/register', data);
return response.data.data;
}
async logout(): Promise<void> {
await axios.post('/auth/logout');
this.clearAuth();
}
async me(): Promise<User> {
const response = await axios.get<ApiResponse<{ user: User }>>('/auth/me');
return response.data.data.user;
}
// 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();