Files
breakpilot-compliance/admin-compliance/app/sdk/training/_components/OverviewTab.tsx
Sharang Parnerkar b5d20a4c1d
Some checks failed
Build + Deploy / build-admin-compliance (push) Failing after 34s
Build + Deploy / build-developer-portal (push) Successful in 56s
Build + Deploy / build-tts (push) Successful in 1m8s
CI/CD / go-lint (push) Has been skipped
Build + Deploy / trigger-orca (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Successful in 38s
CI/CD / test-python-backend-compliance (push) Successful in 32s
Build + Deploy / build-backend-compliance (push) Successful in 7s
Build + Deploy / build-ai-sdk (push) Successful in 7s
Build + Deploy / build-document-crawler (push) Successful in 33s
Build + Deploy / build-dsms-gateway (push) Successful in 20s
CI/CD / test-python-dsms-gateway (push) Has been cancelled
CI/CD / validate-canonical-controls (push) Has been cancelled
CI/CD / test-python-document-crawler (push) Has been cancelled
fix: add missing training page components to fix admin-compliance Docker build
All 8 components imported by app/sdk/training/page.tsx were missing.
Docker build was failing with Module not found errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 10:32:35 +02:00

90 lines
3.7 KiB
TypeScript

'use client'
import type { TrainingStats, DeadlineInfo } from '@/lib/sdk/training/types'
import { STATUS_COLORS, STATUS_LABELS } from '@/lib/sdk/training/types'
export default function OverviewTab({
stats,
deadlines,
escalationResult,
onDismissEscalation,
}: {
stats: TrainingStats
deadlines: DeadlineInfo[]
escalationResult: { total_checked: number; escalated: number } | null
onDismissEscalation: () => void
}) {
return (
<div className="space-y-6">
{escalationResult && (
<div className="bg-orange-50 border border-orange-200 rounded-lg p-4 flex items-center justify-between">
<div>
<p className="text-sm font-medium text-orange-800">Eskalationspruefung abgeschlossen</p>
<p className="text-xs text-orange-600 mt-0.5">
{escalationResult.total_checked} geprueft, {escalationResult.escalated} eskaliert
</p>
</div>
<button onClick={onDismissEscalation} className="text-xs text-orange-600 underline hover:text-orange-800">
Schliessen
</button>
</div>
)}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
<StatCard label="Gesamt Module" value={stats.total_modules} color="blue" />
<StatCard label="Zuweisungen" value={stats.total_assignments} color="gray" />
<StatCard label="Abschlussrate" value={`${Math.round(stats.completion_rate)}%`} color="green" />
<StatCard label="Ueberfaellig" value={stats.overdue_count} color="red" />
<StatCard label="Ausstehend" value={stats.pending_count} color="yellow" />
<StatCard label="In Bearbeitung" value={stats.in_progress_count} color="blue" />
<StatCard label="Abgeschlossen" value={stats.completed_count} color="green" />
<StatCard label="Ø Quiz-Score" value={`${Math.round(stats.avg_quiz_score)}%`} color="purple" />
</div>
{deadlines.length > 0 && (
<div className="bg-white border rounded-lg p-4">
<h3 className="text-sm font-medium text-gray-700 mb-3">Bevorstehende Fristen</h3>
<div className="space-y-2">
{deadlines.map(d => {
const colors = STATUS_COLORS[d.status]
return (
<div key={d.assignment_id} className="flex items-center justify-between text-sm py-2 border-b last:border-0">
<div>
<span className="font-medium text-gray-900">{d.user_name}</span>
<span className="text-gray-500 ml-2">{d.module_code} {d.module_title}</span>
</div>
<div className="flex items-center gap-3 shrink-0">
<span className={`text-xs px-2 py-0.5 rounded-full ${colors.bg} ${colors.text}`}>
{STATUS_LABELS[d.status]}
</span>
<span className={`text-xs font-medium ${d.days_left <= 3 ? 'text-red-600' : d.days_left <= 7 ? 'text-orange-600' : 'text-gray-500'}`}>
{d.days_left <= 0 ? 'Ueberfaellig' : `${d.days_left}d`}
</span>
</div>
</div>
)
})}
</div>
</div>
)}
</div>
)
}
function StatCard({ label, value, color }: { label: string; value: string | number; color: string }) {
const colorMap: Record<string, string> = {
blue: 'text-blue-700',
green: 'text-green-700',
red: 'text-red-700',
yellow: 'text-yellow-700',
purple: 'text-purple-700',
gray: 'text-gray-700',
}
return (
<div className="bg-white border rounded-lg p-4">
<p className="text-xs text-gray-500">{label}</p>
<p className={`text-2xl font-bold mt-1 ${colorMap[color] ?? 'text-gray-700'}`}>{value}</p>
</div>
)
}