This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/admin-v2/components/companion/companion-mode/StatsGrid.tsx
Benjamin Admin 21a844cb8a fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.

This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).

Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 09:51:32 +01:00

115 lines
3.3 KiB
TypeScript

'use client'
import { Users, GraduationCap, BookOpen, FileCheck } from 'lucide-react'
import { CompanionStats } from '@/lib/companion/types'
interface StatsGridProps {
stats: CompanionStats
loading?: boolean
}
interface StatCardProps {
label: string
value: number
icon: React.ReactNode
color: string
loading?: boolean
}
function StatCard({ label, value, icon, color, loading }: StatCardProps) {
return (
<div className="bg-white border border-slate-200 rounded-xl p-4 hover:shadow-md transition-shadow">
<div className="flex items-start justify-between">
<div>
<p className="text-sm text-slate-500 mb-1">{label}</p>
{loading ? (
<div className="h-8 w-16 bg-slate-200 rounded animate-pulse" />
) : (
<p className="text-2xl font-bold text-slate-900">{value}</p>
)}
</div>
<div className={`p-2 rounded-lg ${color}`}>
{icon}
</div>
</div>
</div>
)
}
export function StatsGrid({ stats, loading }: StatsGridProps) {
const statCards = [
{
label: 'Klassen',
value: stats.classesCount,
icon: <Users className="w-5 h-5 text-blue-600" />,
color: 'bg-blue-100',
},
{
label: 'Schueler',
value: stats.studentsCount,
icon: <GraduationCap className="w-5 h-5 text-green-600" />,
color: 'bg-green-100',
},
{
label: 'Lerneinheiten',
value: stats.learningUnitsCreated,
icon: <BookOpen className="w-5 h-5 text-purple-600" />,
color: 'bg-purple-100',
},
{
label: 'Noten',
value: stats.gradesEntered,
icon: <FileCheck className="w-5 h-5 text-amber-600" />,
color: 'bg-amber-100',
},
]
return (
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
{statCards.map((card) => (
<StatCard
key={card.label}
label={card.label}
value={card.value}
icon={card.icon}
color={card.color}
loading={loading}
/>
))}
</div>
)
}
/**
* Compact version of StatsGrid for sidebar or smaller spaces
*/
export function StatsGridCompact({ stats, loading }: StatsGridProps) {
const items = [
{ label: 'Klassen', value: stats.classesCount, icon: <Users className="w-4 h-4" /> },
{ label: 'Schueler', value: stats.studentsCount, icon: <GraduationCap className="w-4 h-4" /> },
{ label: 'Einheiten', value: stats.learningUnitsCreated, icon: <BookOpen className="w-4 h-4" /> },
{ label: 'Noten', value: stats.gradesEntered, icon: <FileCheck className="w-4 h-4" /> },
]
return (
<div className="bg-white border border-slate-200 rounded-xl p-4">
<h3 className="text-sm font-medium text-slate-500 mb-3">Statistiken</h3>
<div className="space-y-3">
{items.map((item) => (
<div key={item.label} className="flex items-center justify-between">
<div className="flex items-center gap-2 text-slate-600">
{item.icon}
<span className="text-sm">{item.label}</span>
</div>
{loading ? (
<div className="h-5 w-8 bg-slate-200 rounded animate-pulse" />
) : (
<span className="font-semibold text-slate-900">{item.value}</span>
)}
</div>
))}
</div>
</div>
)
}