import api from './api'; // Use shared API_URL which already resolves to '/api/v1' under current origin export interface FileInfo { id: number; filename: string; file_path: string; file_url: string; url: string; file_size: number; size: number; mime_type: string; uploaded_by?: { id: number; email: string; first_name: string; last_name: string; }; created_at: string; usages?: FileUsage[]; usage_count: number; md5_hash?: string; } export interface FileUsage { id: number; file_id: number; entity_type: string; entity_id: number; field_name: string; entity_info?: { type: string; id: number; title?: string; name?: string; slug?: string; url?: string; position?: string; }; } export interface DuplicateFiles { [hash: string]: FileInfo[]; } export interface StorageUsage { used_bytes: number; used_count: number; quota_mb: number; quota_bytes: number; percent: number; warn_percent: number; critical_percent: number; status: 'ok' | 'warn' | 'critical'; } export const getAllFiles = async (params?: { search?: string; mime_type?: string; sort_by?: string; sort_order?: string; }): Promise => { const response = await api.get(`/admin/files`, { params }); return response.data; }; export const getUnusedFiles = async (): Promise => { const response = await api.get(`/admin/files/unused`); return response.data; }; export const getDuplicateFiles = async (): Promise => { const response = await api.get(`/admin/files/duplicates`); return response.data; }; export const getStorageUsage = async (): Promise => { const response = await api.get(`/admin/files/usage`); return response.data; }; export const getFileUsages = async (fileId: number): Promise => { const response = await api.get(`/admin/files/${fileId}/usages`); return response.data; }; export const deleteFile = async (fileId: number, force: boolean = false): Promise => { await api.delete(`/admin/files/${fileId}`, { params: { force } }); }; export const scanAndSyncFiles = async (): Promise<{ message: string; found_files: number; new_files: number; orphaned_files: number; skipped_files?: number; new_files_list?: string[]; orphaned_list?: string[]; }> => { const response = await api.post(`/admin/files/scan`, {}); return response.data; }; export const refreshFileTracking = async (entityType?: string): Promise<{ message: string; stats: { articles_scanned: number; events_scanned: number; players_scanned: number; sponsors_scanned: number; contacts_scanned: number; teams_scanned: number; settings_scanned: number; }; }> => { const response = await api.post(`/admin/files/refresh-tracking`, {}, { params: entityType ? { entity_type: entityType } : {} }); return response.data; }; export const formatFileSize = (bytes: number): string => { if (bytes === 0) return '0 B'; const k = 1024; const sizes = ['B', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]; }; import { IconType } from 'react-icons'; import { FiImage, FiFileText, FiVideo, FiFile } from 'react-icons/fi'; export const getFileIcon = (mimeType: string): IconType => { if (mimeType.startsWith('image/')) return FiImage; if (mimeType === 'application/pdf') return FiFileText; if (mimeType.startsWith('video/')) return FiVideo; return FiFile; };