148 lines
4.1 KiB
TypeScript
148 lines
4.1 KiB
TypeScript
'use client';
|
||
|
||
import { useEffect, useState } from 'react';
|
||
import { useSearchParams } from 'next/navigation';
|
||
import { loadComponent } from '@/lib/material-components';
|
||
import { useOptimizedFetch } from '@/hooks/useOptimizedFetch';
|
||
|
||
export default function ChildrenProgressPage() {
|
||
const searchParams = useSearchParams();
|
||
const childId = searchParams.get('child');
|
||
const [componentsLoaded, setComponentsLoaded] = useState(false);
|
||
|
||
useEffect(() => {
|
||
Promise.all([
|
||
loadComponent('elevated-card'),
|
||
loadComponent('circular-progress'),
|
||
loadComponent('icon'),
|
||
]).then(() => {
|
||
setComponentsLoaded(true);
|
||
}).catch((err) => {
|
||
console.error('Error loading components:', err);
|
||
setComponentsLoaded(true);
|
||
});
|
||
}, []);
|
||
|
||
const { data: progressData, loading } = useOptimizedFetch({
|
||
url: childId ? `/users/student-progress/?child_id=${childId}` : '/users/student-progress/',
|
||
cacheKey: `child_progress_${childId}`,
|
||
cacheTTL: 5 * 60 * 1000, // 5 минут
|
||
enabled: !!childId,
|
||
});
|
||
|
||
if (!componentsLoaded) {
|
||
return (
|
||
<div style={{
|
||
display: 'flex',
|
||
justifyContent: 'center',
|
||
alignItems: 'center',
|
||
height: '50vh'
|
||
}}>
|
||
<div>Загрузка...</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
if (!childId) {
|
||
return (
|
||
<div>
|
||
<h1 style={{
|
||
fontSize: '28px',
|
||
fontWeight: '400',
|
||
marginBottom: '24px',
|
||
color: 'var(--md-sys-color-on-surface)'
|
||
}}>
|
||
Прогресс ребенка
|
||
</h1>
|
||
<md-elevated-card style={{
|
||
padding: '40px',
|
||
borderRadius: '20px',
|
||
textAlign: 'center'
|
||
}}>
|
||
<p style={{
|
||
fontSize: '16px',
|
||
color: 'var(--md-sys-color-on-surface-variant)'
|
||
}}>
|
||
Выберите ребенка для просмотра прогресса
|
||
</p>
|
||
</md-elevated-card>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<div>
|
||
<h1 style={{
|
||
fontSize: '28px',
|
||
fontWeight: '400',
|
||
marginBottom: '24px',
|
||
color: 'var(--md-sys-color-on-surface)'
|
||
}}>
|
||
Прогресс ребенка
|
||
</h1>
|
||
|
||
{loading ? (
|
||
<div style={{
|
||
display: 'flex',
|
||
justifyContent: 'center',
|
||
padding: '40px'
|
||
}}>
|
||
<div>Загрузка данных о прогрессе...</div>
|
||
</div>
|
||
) : (
|
||
<div style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
|
||
gap: '16px'
|
||
}}>
|
||
<md-elevated-card style={{
|
||
padding: '24px',
|
||
borderRadius: '20px',
|
||
textAlign: 'center'
|
||
}}>
|
||
<h2 style={{
|
||
fontSize: '18px',
|
||
fontWeight: '500',
|
||
marginBottom: '16px',
|
||
color: 'var(--md-sys-color-on-surface)'
|
||
}}>
|
||
Завершено занятий
|
||
</h2>
|
||
<div style={{
|
||
fontSize: '48px',
|
||
fontWeight: '700',
|
||
color: 'var(--md-sys-color-primary)',
|
||
marginBottom: '8px'
|
||
}}>
|
||
{progressData?.completed_lessons || 0}
|
||
</div>
|
||
</md-elevated-card>
|
||
|
||
<md-elevated-card style={{
|
||
padding: '24px',
|
||
borderRadius: '20px',
|
||
textAlign: 'center'
|
||
}}>
|
||
<h2 style={{
|
||
fontSize: '18px',
|
||
fontWeight: '500',
|
||
marginBottom: '16px',
|
||
color: 'var(--md-sys-color-on-surface)'
|
||
}}>
|
||
Выполнено заданий
|
||
</h2>
|
||
<div style={{
|
||
fontSize: '48px',
|
||
fontWeight: '700',
|
||
color: 'var(--md-sys-color-primary)',
|
||
marginBottom: '8px'
|
||
}}>
|
||
{progressData?.completed_homework || 0}
|
||
</div>
|
||
</md-elevated-card>
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|