144 lines
4.4 KiB
TypeScript
144 lines
4.4 KiB
TypeScript
/**
|
||
* Карточка домашнего задания для Dashboard
|
||
*/
|
||
|
||
'use client';
|
||
|
||
import React from 'react';
|
||
import { HomeworkPreview } from '@/api/dashboard';
|
||
|
||
interface HomeworkCardProps {
|
||
homework: HomeworkPreview;
|
||
}
|
||
|
||
export const HomeworkCard: React.FC<HomeworkCardProps> = ({
|
||
homework,
|
||
}) => {
|
||
const dueDate = new Date(homework.due_date);
|
||
const isOverdue = dueDate < new Date() && homework.status !== 'completed' && homework.status !== 'reviewed';
|
||
|
||
const getStatusColor = (status: string) => {
|
||
switch (status) {
|
||
case 'completed':
|
||
case 'reviewed':
|
||
return 'var(--md-sys-color-tertiary)';
|
||
case 'submitted':
|
||
return 'var(--md-sys-color-primary)';
|
||
case 'pending':
|
||
return isOverdue ? 'var(--md-sys-color-error)' : 'var(--md-sys-color-outline)';
|
||
default:
|
||
return 'var(--md-sys-color-outline)';
|
||
}
|
||
};
|
||
|
||
const getStatusText = (status: string) => {
|
||
switch (status) {
|
||
case 'completed':
|
||
return 'Выполнено';
|
||
case 'reviewed':
|
||
return 'Проверено';
|
||
case 'submitted':
|
||
return 'Отправлено';
|
||
case 'pending':
|
||
return isOverdue ? 'Просрочено' : 'В работе';
|
||
default:
|
||
return 'Неизвестно';
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div style={{
|
||
background: 'var(--md-sys-color-surface)',
|
||
borderRadius: '16px',
|
||
padding: '16px',
|
||
border: '1px solid var(--md-sys-color-outline-variant)',
|
||
marginBottom: '12px',
|
||
transition: 'all 0.2s ease',
|
||
cursor: 'pointer',
|
||
borderLeft: `4px solid ${getStatusColor(homework.status)}`
|
||
}}
|
||
onMouseEnter={(e) => {
|
||
e.currentTarget.style.borderColor = 'var(--md-sys-color-primary)';
|
||
e.currentTarget.style.boxShadow = '0 2px 8px rgba(0,0,0,0.08)';
|
||
}}
|
||
onMouseLeave={(e) => {
|
||
e.currentTarget.style.borderColor = 'var(--md-sys-color-outline-variant)';
|
||
e.currentTarget.style.boxShadow = 'none';
|
||
}}
|
||
>
|
||
<div style={{
|
||
display: 'flex',
|
||
justifyContent: 'space-between',
|
||
alignItems: 'flex-start',
|
||
marginBottom: '12px'
|
||
}}>
|
||
<div style={{ flex: 1 }}>
|
||
<h4 style={{
|
||
fontSize: '16px',
|
||
fontWeight: '500',
|
||
color: 'var(--md-sys-color-on-surface)',
|
||
margin: '0 0 4px 0'
|
||
}}>
|
||
{homework.title}
|
||
</h4>
|
||
{homework.subject && (
|
||
<p style={{
|
||
fontSize: '14px',
|
||
color: 'var(--md-sys-color-on-surface-variant)',
|
||
margin: '0'
|
||
}}>
|
||
{homework.subject}
|
||
</p>
|
||
)}
|
||
</div>
|
||
<span style={{
|
||
fontSize: '12px',
|
||
padding: '4px 8px',
|
||
borderRadius: '12px',
|
||
background: getStatusColor(homework.status) + '20',
|
||
color: getStatusColor(homework.status),
|
||
fontWeight: '500'
|
||
}}>
|
||
{getStatusText(homework.status)}
|
||
</span>
|
||
</div>
|
||
|
||
<div style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: '16px',
|
||
fontSize: '14px',
|
||
color: 'var(--md-sys-color-on-surface-variant)'
|
||
}}>
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>
|
||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||
<circle cx="12" cy="12" r="10"></circle>
|
||
<polyline points="12 6 12 12 16 14"></polyline>
|
||
</svg>
|
||
<span>
|
||
Срок: {dueDate.toLocaleDateString('ru-RU', {
|
||
day: 'numeric',
|
||
month: 'short',
|
||
year: 'numeric'
|
||
})}
|
||
</span>
|
||
</div>
|
||
{homework.grade !== undefined && (
|
||
<div style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
gap: '4px',
|
||
color: 'var(--md-sys-color-primary)',
|
||
fontWeight: '500'
|
||
}}>
|
||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path>
|
||
</svg>
|
||
<span>{homework.grade}/100</span>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|