uchill/front_material/components/dashboard/mentor/StatsSection.tsx

97 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Секция карточек метрик для дашборда ментора (iOS 26).
*/
'use client';
import React from 'react';
import { MentorDashboardResponse } from '@/api/dashboard';
import { StatsGrid, type StatsGridItem } from '../ui';
const IconUsers = (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
<circle cx="9" cy="7" r="4" />
<path d="M23 21v-2a4 4 0 0 0-3-3.87" />
<path d="M16 3.13a4 4 0 0 1 0 7.75" />
</svg>
);
const IconCalendar = (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<rect x="3" y="4" width="18" height="18" rx="2" ry="2" />
<line x1="16" y1="2" x2="16" y2="6" />
<line x1="8" y1="2" x2="8" y2="6" />
<line x1="3" y1="10" x2="21" y2="10" />
</svg>
);
const IconRevenue = (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<line x1="12" y1="1" x2="12" y2="23" />
<path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6" />
</svg>
);
const IconClipboard = (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
<polyline points="14 2 14 8 20 8" />
<line x1="16" y1="13" x2="8" y2="13" />
<line x1="16" y1="17" x2="8" y2="17" />
<polyline points="10 9 9 9 8 9" />
</svg>
);
export interface StatsSectionProps {
stats: MentorDashboardResponse | null;
loading: boolean;
}
function buildGridItems(stats: MentorDashboardResponse | null, loading: boolean): StatsGridItem[] {
const s = stats?.summary;
return [
{
title: 'Всего учеников',
value: loading ? '—' : (s?.total_clients ?? 0),
icon: IconUsers,
loading,
},
{
title: 'Завершённых занятий (месяц / всего)',
value: loading
? '—'
: `${s?.lessons_this_month ?? 0}/${s?.completed_lessons ?? 0}`,
icon: IconCalendar,
loading,
},
{
title: 'Доход (месяц / всё время)',
value: loading
? '—'
: `${s?.revenue_this_month != null ? `${Math.round(s.revenue_this_month).toLocaleString('ru-RU')}` : '0 ₽'} / ${
s?.total_revenue != null ? `${Math.round(s.total_revenue).toLocaleString('ru-RU')}` : '0 ₽'
}`,
icon: IconRevenue,
loading,
},
{
title: 'Заданий на проверке / всего',
value: loading
? '—'
: `${s?.pending_submissions ?? 0}/${s?.total_homeworks ?? 0}`,
icon: IconClipboard,
loading,
},
];
}
export const StatsSection: React.FC<StatsSectionProps> = ({ stats, loading }) => {
const gridItems = buildGridItems(stats, loading);
return (
<div style={{ marginBottom: 'var(--ios26-spacing-lg)' }}>
<StatsGrid items={gridItems} />
</div>
);
};