Extracted components and constants into _components/ subdirectories to bring all three pages under the 300 LOC soft target (was 651/628/612, now 255/232/278 LOC respectively). Zero behavior changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
60 lines
2.7 KiB
TypeScript
60 lines
2.7 KiB
TypeScript
'use client'
|
|
|
|
import { Enrollment, ENROLLMENT_STATUS_INFO, isEnrollmentOverdue, getDaysUntilDeadline } from '@/lib/sdk/academy/types'
|
|
|
|
interface EnrollmentsTabProps {
|
|
enrollments: Enrollment[]
|
|
overdueEnrollments: number
|
|
}
|
|
|
|
export function EnrollmentsTab({ enrollments, overdueEnrollments }: EnrollmentsTabProps) {
|
|
return (
|
|
<div className="space-y-4">
|
|
{overdueEnrollments > 0 && (
|
|
<div className="bg-red-50 border border-red-200 rounded-xl p-4 text-sm text-red-700">
|
|
{overdueEnrollments} ueberfaellige Einschreibung(en)
|
|
</div>
|
|
)}
|
|
{enrollments.length === 0 ? (
|
|
<div className="bg-white rounded-xl border border-gray-200 p-12 text-center">
|
|
<p className="text-gray-500">Noch keine Einschreibungen fuer diesen Kurs.</p>
|
|
</div>
|
|
) : (
|
|
enrollments.map(enrollment => {
|
|
const statusInfo = ENROLLMENT_STATUS_INFO[enrollment.status]
|
|
const overdue = isEnrollmentOverdue(enrollment)
|
|
const daysUntil = getDaysUntilDeadline(enrollment.deadline)
|
|
return (
|
|
<div key={enrollment.id} className={`bg-white rounded-xl border-2 p-5 ${overdue ? 'border-red-200' : 'border-gray-200'}`}>
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<div className="flex items-center gap-2 mb-1">
|
|
<span className={`px-2 py-0.5 text-xs rounded-full ${statusInfo?.bgColor} ${statusInfo?.color}`}>
|
|
{statusInfo?.label}
|
|
</span>
|
|
{overdue && <span className="text-xs text-red-600">Ueberfaellig</span>}
|
|
</div>
|
|
<div className="font-medium text-gray-900">{enrollment.userName}</div>
|
|
<div className="text-sm text-gray-500">{enrollment.userEmail}</div>
|
|
</div>
|
|
<div className="text-right">
|
|
<div className="text-2xl font-bold text-gray-900">{enrollment.progress}%</div>
|
|
<div className="text-xs text-gray-500">
|
|
{enrollment.status === 'completed' ? 'Abgeschlossen' : `${daysUntil > 0 ? daysUntil + ' Tage verbleibend' : Math.abs(daysUntil) + ' Tage ueberfaellig'}`}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="mt-3 w-full h-2 bg-gray-200 rounded-full overflow-hidden">
|
|
<div
|
|
className={`h-full rounded-full ${enrollment.progress === 100 ? 'bg-green-500' : overdue ? 'bg-red-500' : 'bg-purple-500'}`}
|
|
style={{ width: `${enrollment.progress}%` }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
)
|
|
})
|
|
)}
|
|
</div>
|
|
)
|
|
}
|