uchill/front_material/api/dashboard.ts

277 lines
8.1 KiB
TypeScript

/**
* API модуль для dashboard
*/
import apiClient from '@/lib/api-client';
// Типы данных dashboard
export interface DashboardStats {
total_clients?: number;
active_clients?: number;
lessons_this_month?: number;
lessons_today?: number;
lessons_this_week?: number;
earnings_this_month?: number;
total_revenue?: number;
upcoming_lessons?: LessonPreview[];
recent_homework?: HomeworkPreview[];
total_lessons?: number;
completed_lessons?: number;
homework_pending?: number;
homework_completed?: number;
average_grade?: number;
next_lesson?: LessonPreview | null;
children_count?: number;
children_stats?: ChildStats[];
total_homeworks?: number;
pending_submissions?: number;
total_materials?: number;
unread_notifications?: number;
}
export interface LessonPreview {
id: string;
title: string;
subject: string;
start_time: string;
end_time: string;
mentor?: UserPreview;
client?: UserPreview;
status: 'scheduled' | 'in_progress' | 'completed' | 'cancelled';
room_url?: string;
}
export interface HomeworkPreview {
id: string;
title: string;
subject: string;
due_date: string;
status: 'pending' | 'submitted' | 'reviewed' | 'completed';
grade?: number;
lesson?: LessonPreview;
}
export interface ChildStats {
id: string;
name: string;
avatar?: string | null;
avatar_url?: string | null;
total_lessons: number;
completed_lessons: number;
average_grade: number;
next_lesson?: LessonPreview | null;
homework_pending: number;
}
export interface UserPreview {
id: string;
email?: string;
name?: string;
first_name: string;
last_name: string;
avatar?: string;
}
export interface MentorDashboardResponse {
summary: {
total_clients: number;
total_lessons: number;
lessons_this_week: number;
lessons_this_month: number;
completed_lessons: number;
total_homeworks: number;
pending_submissions: number;
total_materials: number;
unread_notifications: number;
total_revenue: number;
revenue_this_month: number;
};
upcoming_lessons: Array<{
id: string;
title: string;
subject?: string | null;
client: {
id: string;
name: string;
avatar?: string | null;
first_name?: string;
last_name?: string;
};
start_time: string;
end_time: string;
}>;
recent_submissions?: Array<{
id: string;
homework: {
id: string;
title: string;
};
subject?: string | null;
student: {
id: string;
name: string;
avatar?: string | null;
first_name?: string;
last_name?: string;
};
status: string;
score?: number | null;
max_score: number;
submitted_at: string;
}>;
}
export interface IncomeChartData {
date: string;
income: number;
lessons: number;
}
export interface MentorIncomeResponse {
period: string;
start_date: string;
end_date: string;
summary: {
total_income: number;
total_lessons: number;
average_lesson_price: number;
};
chart_data: IncomeChartData[];
}
/**
* Получить статистику для дашборда ментора
*/
export async function getMentorDashboard(options?: { signal?: AbortSignal }): Promise<MentorDashboardResponse> {
const config = options?.signal ? { signal: options.signal } : undefined;
const response = await apiClient.get<MentorDashboardResponse>('/mentor/dashboard/', config);
return response.data;
}
/**
* Ответ API прогресса клиента (оценки по предметам, посещаемость и т.д.)
*/
export interface ClientProgressResponse {
total_lessons: number;
completed_lessons: number;
cancelled_lessons: number;
attendance_rate: number;
average_mentor_grade: number;
average_school_grade: number;
total_homework: number;
completed_homework: number;
homework_completion_rate: number;
grades_by_subject: Array<{ subject: string; average_grade: number; lessons_count: number }>;
recent_grades?: Array<{
lesson_title: string;
date: string | null;
mentor_grade: number;
school_grade: number;
}>;
}
/**
* Получить прогресс клиента (для списка предметов и сводок).
* GET /api/client/progress/?period=90
*/
export async function getClientProgress(params?: { period?: number }): Promise<ClientProgressResponse> {
const url = params?.period != null ? `/client/progress/?period=${params.period}` : '/client/progress/';
const response = await apiClient.get<ClientProgressResponse>(url);
return response.data;
}
/** Ответ API /client/dashboard/ и /parent/{id}/child_dashboard/ — данные в summary */
interface ClientDashboardApiResponse {
summary?: {
total_lessons?: number;
completed_lessons?: number;
lessons_this_week?: number;
total_homeworks?: number;
completed_homeworks?: number;
pending_homeworks?: number;
average_score?: number;
shared_materials?: number;
unread_notifications?: number;
};
upcoming_lessons?: Array<{
id: string | number;
title?: string;
mentor?: { id: number; name: string };
start_time?: string | null;
end_time?: string | null;
}>;
}
function normalizeClientDashboardResponse(raw: ClientDashboardApiResponse): DashboardStats {
const s = raw.summary ?? {};
const upcoming = raw.upcoming_lessons ?? [];
return {
total_lessons: s.total_lessons ?? 0,
completed_lessons: s.completed_lessons ?? 0,
homework_pending: s.pending_homeworks ?? 0,
homework_completed: s.completed_homeworks ?? 0,
average_grade: s.average_score ?? 0,
next_lesson: upcoming[0] ? {
id: String(upcoming[0].id),
title: upcoming[0].title ?? '',
subject: '',
start_time: upcoming[0].start_time ?? '',
end_time: upcoming[0].end_time ?? '',
status: 'scheduled',
mentor: upcoming[0].mentor ? { id: String(upcoming[0].mentor.id), first_name: upcoming[0].mentor.name, last_name: '', email: '' } : undefined,
} : null,
upcoming_lessons: upcoming.map((l) => ({
id: String(l.id),
title: l.title ?? '',
subject: '',
start_time: l.start_time ?? '',
end_time: l.end_time ?? '',
status: 'scheduled' as const,
mentor: l.mentor ? { id: String(l.mentor.id), first_name: l.mentor.name, last_name: '', email: '' } : undefined,
})),
recent_homework: [],
};
}
/**
* Получить статистику для дашборда клиента
*/
export async function getClientDashboard(): Promise<DashboardStats> {
const response = await apiClient.get<ClientDashboardApiResponse>('/client/dashboard/');
return normalizeClientDashboardResponse(response.data);
}
/**
* Получить статистику для дашборда родителя
*/
export async function getParentDashboard(): Promise<DashboardStats> {
const response = await apiClient.get<DashboardStats>('/parent/dashboard/');
return response.data;
}
/**
* Получить дашборд выбранного ребенка для родителя
*/
export async function getChildDashboard(childId: string): Promise<DashboardStats> {
const response = await apiClient.get<ClientDashboardApiResponse>(`/parent/${childId}/child_dashboard/`);
return normalizeClientDashboardResponse(response.data);
}
/**
* Получить статистику доходов ментора
*/
export async function getMentorIncome(
period: 'day' | 'week' | 'month' | 'range' = 'week',
startDate?: string,
endDate?: string,
options?: { signal?: AbortSignal }
): Promise<MentorIncomeResponse> {
let url = `/mentor/income/?period=${period}`;
if (period === 'range' && startDate && endDate) {
url += `&start_date=${startDate}&end_date=${endDate}`;
}
const config = options?.signal ? { signal: options.signal } : undefined;
const response = await apiClient.get<MentorIncomeResponse>(url, config);
return response.data;
}