feat(frontend): add API client, layout, and routing

- Create Axios-based API client with sources, jobs, and dashboard endpoints
- Add responsive Layout component with navigation sidebar
- Set up React Router with Dashboard, Backups, and Settings routes
- Configure TanStack Query provider with default options
- Use lucide-react for navigation icons
This commit is contained in:
2026-05-11 21:47:20 +02:00
parent 7676438466
commit d3b92593d5
14073 changed files with 2182272 additions and 0 deletions
+61
View File
@@ -0,0 +1,61 @@
import axios from 'axios';
const API_BASE_URL = '/api';
export const apiClient = axios.create({
baseURL: API_BASE_URL,
headers: {
'Content-Type': 'application/json',
},
});
export interface BackupSource {
id: string;
name: string;
type: string;
config: Record<string, unknown>;
created_at: string;
updated_at: string;
}
export interface BackupJob {
id: string;
source_id: string;
status: 'pending' | 'running' | 'completed' | 'failed';
started_at: string | null;
completed_at: string | null;
error_message: string | null;
created_at: string;
}
export interface DashboardStats {
total_sources: number;
total_jobs: number;
completed_jobs: number;
failed_jobs: number;
pending_jobs: number;
}
export const sourcesApi = {
getAll: () => apiClient.get<BackupSource[]>('/sources'),
getById: (id: string) => apiClient.get<BackupSource>(`/sources/${id}`),
create: (data: Omit<BackupSource, 'id' | 'created_at' | 'updated_at'>) =>
apiClient.post<BackupSource>('/sources', data),
update: (id: string, data: Partial<BackupSource>) =>
apiClient.put<BackupSource>(`/sources/${id}`, data),
delete: (id: string) => apiClient.delete(`/sources/${id}`),
};
export const jobsApi = {
getAll: () => apiClient.get<BackupJob[]>('/jobs'),
getById: (id: string) => apiClient.get<BackupJob>(`/jobs/${id}`),
create: (sourceId: string) =>
apiClient.post<BackupJob>('/jobs', { source_id: sourceId }),
getLogs: (id: string) => apiClient.get<string>(`/jobs/${id}/logs`),
};
export const dashboardApi = {
getStats: () => apiClient.get<DashboardStats>('/dashboard/stats'),
getRecentJobs: (limit: number = 10) =>
apiClient.get<BackupJob[]>(`/dashboard/recent-jobs?limit=${limit}`),
};