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/app/(admin)/compliance/ai-act/page.tsx
BreakPilot Dev 660295e218 fix(admin-v2): Restore complete admin-v2 application
The admin-v2 application was incomplete in the repository. This commit
restores all missing components:

- Admin pages (76 pages): dashboard, ai, compliance, dsgvo, education,
  infrastructure, communication, development, onboarding, rbac
- SDK pages (45 pages): tom, dsfa, vvt, loeschfristen, einwilligungen,
  vendor-compliance, tom-generator, dsr, and more
- Developer portal (25 pages): API docs, SDK guides, frameworks
- All components, lib files, hooks, and types
- Updated package.json with all dependencies

The issue was caused by incomplete initial repository state - the full
admin-v2 codebase existed in backend/admin-v2 and docs-src/admin-v2
but was never fully synced to the main admin-v2 directory.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 23:40:15 -08:00

832 lines
36 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
/**
* EU-AI-Act Risk Classification Page
*
* Self-assessment and documentation of AI risk categories according to EU AI Act.
* Provides module-by-module risk assessment, warning lines, and exportable documentation.
*/
import { useState } from 'react'
import { PagePurpose } from '@/components/common/PagePurpose'
// =============================================================================
// TYPES
// =============================================================================
type RiskLevel = 'unacceptable' | 'high' | 'limited' | 'minimal'
interface ModuleAssessment {
id: string
name: string
description: string
riskLevel: RiskLevel
justification: string
humanInLoop: boolean
transparencyMeasures: string[]
aiActArticle: string
}
interface WarningLine {
id: string
title: string
description: string
wouldTrigger: RiskLevel
currentStatus: 'safe' | 'approaching' | 'violated'
recommendation: string
}
// =============================================================================
// DATA - Breakpilot Module Assessments
// =============================================================================
const MODULE_ASSESSMENTS: ModuleAssessment[] = [
{
id: 'text-suggestions',
name: 'Textvorschlaege / Formulierhilfen',
description: 'KI-generierte Textvorschlaege fuer Gutachten und Feedback',
riskLevel: 'minimal',
justification: 'Reine Assistenzfunktion ohne Entscheidungswirkung. Lehrer editieren und finalisieren alle Texte.',
humanInLoop: true,
transparencyMeasures: ['KI-Label auf generierten Texten', 'Editierbare Vorschlaege'],
aiActArticle: 'Art. 69 (Freiwillige Verhaltenskodizes)',
},
{
id: 'rag-sources',
name: 'RAG-basierte Quellenanzeige',
description: 'Retrieval Augmented Generation fuer Lehrplan- und Erwartungshorizont-Referenzen',
riskLevel: 'minimal',
justification: 'Zitierende Referenzfunktion. Zeigt nur offizielle Quellen an, trifft keine Entscheidungen.',
humanInLoop: true,
transparencyMeasures: ['Quellenangaben', 'Direkte Links zu Originaldokumenten'],
aiActArticle: 'Art. 69 (Freiwillige Verhaltenskodizes)',
},
{
id: 'correction-suggestions',
name: 'Korrektur-Vorschlaege',
description: 'KI-Vorschlaege fuer Bewertungskriterien und Punktevergabe',
riskLevel: 'limited',
justification: 'Vorschlaege ohne bindende Wirkung. Lehrkraft behaelt vollstaendige Entscheidungshoheit.',
humanInLoop: true,
transparencyMeasures: [
'Klare Kennzeichnung als KI-Vorschlag',
'Begruendung fuer jeden Vorschlag',
'Einfache Ueberschreibung moeglich',
],
aiActArticle: 'Art. 52 (Transparenzpflichten)',
},
{
id: 'eh-matching',
name: 'Erwartungshorizont-Abgleich',
description: 'Automatischer Abgleich von Schuelerantworten mit Erwartungshorizonten',
riskLevel: 'limited',
justification: 'Empfehlung, keine Entscheidung. Zeigt Uebereinstimmungen auf, bewertet nicht eigenstaendig.',
humanInLoop: true,
transparencyMeasures: [
'Visualisierung der Matching-Logik',
'Confidence-Score angezeigt',
'Manuelle Korrektur jederzeit moeglich',
],
aiActArticle: 'Art. 52 (Transparenzpflichten)',
},
{
id: 'report-drafts',
name: 'Zeugnis-Textentwurf',
description: 'KI-generierte Entwuerfe fuer Zeugnistexte und Beurteilungen',
riskLevel: 'limited',
justification: 'Entwurf, der von der Lehrkraft finalisiert wird. Keine automatische Uebernahme.',
humanInLoop: true,
transparencyMeasures: [
'Entwurf-Wasserzeichen',
'Pflicht zur manuellen Freigabe',
'Vollstaendig editierbar',
],
aiActArticle: 'Art. 52 (Transparenzpflichten)',
},
{
id: 'edu-search',
name: 'Bildungssuche (edu-search)',
description: 'Semantische Suche in Lehrplaenen und Bildungsmaterialien',
riskLevel: 'minimal',
justification: 'Informationsretrieval ohne Bewertungsfunktion. Reine Suchfunktion.',
humanInLoop: true,
transparencyMeasures: ['Quellenangaben', 'Ranking-Transparenz'],
aiActArticle: 'Art. 69 (Freiwillige Verhaltenskodizes)',
},
]
// =============================================================================
// DATA - Warning Lines (What we must never build)
// =============================================================================
const WARNING_LINES: WarningLine[] = [
{
id: 'auto-grading',
title: 'Automatische Notenvergabe',
description: 'KI berechnet und vergibt Noten ohne menschliche Pruefung',
wouldTrigger: 'high',
currentStatus: 'safe',
recommendation: 'Noten immer als Vorschlag, nie als finale Entscheidung',
},
{
id: 'student-classification',
title: 'Schuelerklassifikation',
description: 'Automatische Einteilung in Leistungsgruppen (leistungsstark/schwach)',
wouldTrigger: 'high',
currentStatus: 'safe',
recommendation: 'Keine automatische Kategorisierung von Schuelern implementieren',
},
{
id: 'promotion-decisions',
title: 'Versetzungsentscheidungen',
description: 'Automatisierte Logik fuer Versetzung/Nichtversetzung',
wouldTrigger: 'high',
currentStatus: 'safe',
recommendation: 'Versetzungsentscheidungen ausschliesslich bei Lehrkraeften belassen',
},
{
id: 'unreviewed-assessments',
title: 'Ungeprueft freigegebene Bewertungen',
description: 'KI-Bewertungen ohne menschliche Kontrolle an Schueler/Eltern',
wouldTrigger: 'high',
currentStatus: 'safe',
recommendation: 'Immer manuellen Freigabe-Schritt vor Veroeffentlichung',
},
{
id: 'behavioral-profiling',
title: 'Verhaltensprofilierung',
description: 'Erstellung von Persoenlichkeits- oder Verhaltensprofilen von Schuelern',
wouldTrigger: 'unacceptable',
currentStatus: 'safe',
recommendation: 'Keine Verhaltensanalyse oder Profiling implementieren',
},
{
id: 'algorithmic-optimization',
title: 'Algorithmische Schuloptimierung',
description: 'KI optimiert Schulentscheidungen (Klassenzuteilung, Ressourcen)',
wouldTrigger: 'high',
currentStatus: 'safe',
recommendation: 'Schulorganisatorische Entscheidungen bei Menschen belassen',
},
{
id: 'auto-accept',
title: 'Auto-Accept Funktionen',
description: 'Ein-Klick-Uebernahme von KI-Vorschlaegen ohne Pruefung',
wouldTrigger: 'high',
currentStatus: 'safe',
recommendation: 'Immer bewusste Bestaetigungsschritte einbauen',
},
{
id: 'emotion-detection',
title: 'Emotionserkennung',
description: 'Analyse von Emotionen oder psychischem Zustand von Schuelern',
wouldTrigger: 'unacceptable',
currentStatus: 'safe',
recommendation: 'Keine biometrische oder emotionale Analyse',
},
]
// =============================================================================
// HELPER FUNCTIONS
// =============================================================================
const getRiskLevelInfo = (level: RiskLevel) => {
switch (level) {
case 'unacceptable':
return {
label: 'Unzulaessig',
color: 'bg-black text-white',
borderColor: 'border-black',
description: 'Verboten nach EU-AI-Act',
}
case 'high':
return {
label: 'Hoch',
color: 'bg-red-600 text-white',
borderColor: 'border-red-600',
description: 'Strenge Anforderungen, Konformitaetsbewertung',
}
case 'limited':
return {
label: 'Begrenzt',
color: 'bg-amber-500 text-white',
borderColor: 'border-amber-500',
description: 'Transparenzpflichten',
}
case 'minimal':
return {
label: 'Minimal',
color: 'bg-green-600 text-white',
borderColor: 'border-green-600',
description: 'Freiwillige Verhaltenskodizes',
}
}
}
const getStatusInfo = (status: 'safe' | 'approaching' | 'violated') => {
switch (status) {
case 'safe':
return { label: 'Sicher', color: 'bg-green-100 text-green-700', icon: '✓' }
case 'approaching':
return { label: 'Annaehernd', color: 'bg-amber-100 text-amber-700', icon: '⚠' }
case 'violated':
return { label: 'Verletzt', color: 'bg-red-100 text-red-700', icon: '✗' }
}
}
// =============================================================================
// COMPONENT
// =============================================================================
export default function AIActClassificationPage() {
const [activeTab, setActiveTab] = useState<'overview' | 'modules' | 'warnings' | 'documentation'>('overview')
const [expandedModule, setExpandedModule] = useState<string | null>(null)
// Calculate statistics
const stats = {
totalModules: MODULE_ASSESSMENTS.length,
minimalRisk: MODULE_ASSESSMENTS.filter((m) => m.riskLevel === 'minimal').length,
limitedRisk: MODULE_ASSESSMENTS.filter((m) => m.riskLevel === 'limited').length,
highRisk: MODULE_ASSESSMENTS.filter((m) => m.riskLevel === 'high').length,
humanInLoop: MODULE_ASSESSMENTS.filter((m) => m.humanInLoop).length,
warningsTotal: WARNING_LINES.length,
warningsSafe: WARNING_LINES.filter((w) => w.currentStatus === 'safe').length,
}
const generateMemo = () => {
const date = new Date().toLocaleDateString('de-DE', {
year: 'numeric',
month: 'long',
day: 'numeric',
})
const memo = `
================================================================================
EU-AI-ACT RISIKOKLASSIFIZIERUNG - BREAKPILOT
================================================================================
Erstellungsdatum: ${date}
Version: 1.0
Verantwortlich: Breakpilot GmbH
--------------------------------------------------------------------------------
1. ZUSAMMENFASSUNG
--------------------------------------------------------------------------------
System: Breakpilot KI-Assistenzsystem fuer Bildung
Gesamtrisikokategorie: LIMITED RISK (Art. 52 EU-AI-Act)
Begruendung:
- KI liefert ausschliesslich Vorschlaege und Entwuerfe
- Kein automatisiertes Entscheiden ueber Schueler
- Mensch-in-the-Loop ist technisch erzwungen
- Keine Schuelerklassifikation oder Profiling
- Alle paedagogischen Entscheidungen verbleiben bei Lehrkraeften
--------------------------------------------------------------------------------
2. MODUL-BEWERTUNG
--------------------------------------------------------------------------------
${MODULE_ASSESSMENTS.map(
(m) => `
${m.name}
Risikostufe: ${getRiskLevelInfo(m.riskLevel).label.toUpperCase()}
Begruendung: ${m.justification}
Human-in-Loop: ${m.humanInLoop ? 'JA' : 'NEIN'}
AI-Act Artikel: ${m.aiActArticle}
`
).join('')}
--------------------------------------------------------------------------------
3. TRANSPARENZMASSNAHMEN
--------------------------------------------------------------------------------
Alle KI-generierten Inhalte sind:
- Klar als KI-Vorschlag gekennzeichnet
- Vollstaendig editierbar durch die Lehrkraft
- Mit Quellenangaben versehen (wo zutreffend)
- Erst nach manueller Freigabe wirksam
Zusaetzliche UI-Hinweise:
- "Dieser Text wurde durch KI vorgeschlagen"
- "Endverantwortung liegt bei der Lehrkraft"
- Confidence-Scores wo relevant
--------------------------------------------------------------------------------
4. HUMAN-IN-THE-LOOP GARANTIEN
--------------------------------------------------------------------------------
Technisch erzwungene Massnahmen:
- Kein Auto-Accept fuer KI-Vorschlaege
- Kein 1-Click-Bewerten
- Pflicht-Bestaetigung vor Freigabe
- Audit-Trail aller Aenderungen
--------------------------------------------------------------------------------
5. WARNLINIEN (NICHT IMPLEMENTIEREN)
--------------------------------------------------------------------------------
${WARNING_LINES.map(
(w) => `
[${getStatusInfo(w.currentStatus).icon}] ${w.title}
Wuerde ausloesen: ${getRiskLevelInfo(w.wouldTrigger).label}
Status: ${getStatusInfo(w.currentStatus).label}
`
).join('')}
--------------------------------------------------------------------------------
6. RECHTLICHE EINORDNUNG
--------------------------------------------------------------------------------
Breakpilot faellt NICHT unter die High-Risk Kategorie des EU-AI-Act, da:
1. Keine automatisierten Entscheidungen ueber natuerliche Personen
2. Keine Bewertung von Schuelern ohne menschliche Kontrolle
3. Keine Zugangs- oder Selektionsentscheidungen
4. Reine Assistenzfunktion mit Human-in-the-Loop
Die Transparenzpflichten nach Art. 52 werden durch entsprechende
UI-Kennzeichnungen und Nutzerinformationen erfuellt.
--------------------------------------------------------------------------------
7. MANAGEMENT-STATEMENT
--------------------------------------------------------------------------------
"Breakpilot ist ein KI-Assistenzsystem mit begrenztem Risiko gemaess EU-AI-Act.
Die KI trifft keine Entscheidungen, sondern unterstuetzt Lehrkraefte transparent
und nachvollziehbar. Alle paedagogischen und rechtlichen Entscheidungen
verbleiben beim Menschen."
================================================================================
Dieses Dokument dient der internen Compliance-Dokumentation und kann
Auditoren auf Anfrage vorgelegt werden.
================================================================================
`
return memo
}
const downloadMemo = () => {
const memo = generateMemo()
const blob = new Blob([memo], { type: 'text/plain;charset=utf-8' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = `breakpilot-ai-act-klassifizierung-${new Date().toISOString().split('T')[0]}.txt`
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
URL.revokeObjectURL(url)
}
const tabs = [
{ id: 'overview', name: 'Uebersicht', icon: '📊' },
{ id: 'modules', name: 'Module', icon: '🧩' },
{ id: 'warnings', name: 'Warnlinien', icon: '⚠️' },
{ id: 'documentation', name: 'Dokumentation', icon: '📄' },
]
return (
<div className="min-h-screen bg-slate-50">
{/* Header */}
<div className="bg-white border-b border-slate-200">
<div className="max-w-7xl mx-auto px-6 py-6">
<div className="flex items-center gap-4">
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-blue-600 to-indigo-700 flex items-center justify-center">
<span className="text-2xl">🤖</span>
</div>
<div>
<h1 className="text-2xl font-bold text-slate-900">EU-AI-Act Klassifizierung</h1>
<p className="text-slate-600">Risikoklassifizierung und Compliance-Dokumentation</p>
</div>
</div>
</div>
</div>
<div className="max-w-7xl mx-auto px-6 py-6">
{/* Page Purpose */}
<PagePurpose
title="KI-Risikoklassifizierung nach EU-AI-Act"
purpose="Selbstbewertung und Dokumentation der Risikokategorien aller KI-Module gemaess EU-AI-Act. Definiert Warnlinien fuer Features, die nicht implementiert werden duerfen."
audience={['Management', 'DSB', 'Compliance Officer', 'Auditor', 'Investoren']}
gdprArticles={['EU-AI-Act Art. 52', 'EU-AI-Act Art. 69', 'EU-AI-Act Anhang III']}
/>
{/* Stats Cards */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mt-6">
<div className="bg-white rounded-xl border border-slate-200 p-4">
<div className="text-sm text-slate-500">Module gesamt</div>
<div className="text-2xl font-bold text-slate-900">{stats.totalModules}</div>
</div>
<div className="bg-white rounded-xl border border-slate-200 p-4">
<div className="text-sm text-slate-500">Minimal Risk</div>
<div className="text-2xl font-bold text-green-600">{stats.minimalRisk}</div>
</div>
<div className="bg-white rounded-xl border border-slate-200 p-4">
<div className="text-sm text-slate-500">Limited Risk</div>
<div className="text-2xl font-bold text-amber-600">{stats.limitedRisk}</div>
</div>
<div className="bg-white rounded-xl border border-slate-200 p-4">
<div className="text-sm text-slate-500">Human-in-Loop</div>
<div className="text-2xl font-bold text-blue-600">{stats.humanInLoop}/{stats.totalModules}</div>
</div>
</div>
{/* Classification Banner */}
<div className="mt-6 bg-gradient-to-r from-amber-50 to-amber-100 border border-amber-200 rounded-xl p-6">
<div className="flex items-start gap-4">
<div className="w-16 h-16 rounded-full bg-amber-200 flex items-center justify-center flex-shrink-0">
<span className="text-3xl"></span>
</div>
<div>
<h2 className="text-xl font-bold text-amber-900">Gesamtklassifizierung: LIMITED RISK</h2>
<p className="text-amber-800 mt-1">
Breakpilot ist ein KI-Assistenzsystem mit <strong>begrenztem Risiko</strong> gemaess EU-AI-Act (Art. 52).
Es gelten Transparenzpflichten, aber keine Konformitaetsbewertung.
</p>
<div className="flex flex-wrap gap-2 mt-3">
<span className="px-3 py-1 bg-amber-200 text-amber-800 rounded-full text-sm font-medium">
Art. 52 Transparenz
</span>
<span className="px-3 py-1 bg-green-200 text-green-800 rounded-full text-sm font-medium">
Human-in-the-Loop
</span>
<span className="px-3 py-1 bg-blue-200 text-blue-800 rounded-full text-sm font-medium">
Assistiv, nicht autonom
</span>
</div>
</div>
</div>
</div>
{/* Tabs */}
<div className="flex gap-2 mt-6 border-b border-slate-200">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id as typeof activeTab)}
className={`px-4 py-3 text-sm font-medium border-b-2 transition-colors ${
activeTab === tab.id
? 'border-purple-600 text-purple-600'
: 'border-transparent text-slate-600 hover:text-slate-900'
}`}
>
<span className="mr-2">{tab.icon}</span>
{tab.name}
</button>
))}
</div>
{/* Tab Content */}
<div className="mt-6">
{/* Overview Tab */}
{activeTab === 'overview' && (
<div className="space-y-6">
{/* Risk Level Pyramid */}
<div className="bg-white rounded-xl border border-slate-200 p-6">
<h3 className="font-semibold text-slate-900 mb-4">EU-AI-Act Risikopyramide</h3>
<div className="space-y-3">
{/* Unacceptable */}
<div className="flex items-center gap-4">
<div className="w-32 text-right">
<span className="px-3 py-1 bg-black text-white text-xs rounded font-medium">
Unzulaessig
</span>
</div>
<div className="flex-1 h-8 bg-slate-100 rounded relative overflow-hidden">
<div className="absolute inset-y-0 left-0 w-0 bg-black rounded" />
<span className="absolute inset-0 flex items-center justify-center text-xs text-slate-500">
0 Module - Social Scoring, Manipulation verboten
</span>
</div>
</div>
{/* High */}
<div className="flex items-center gap-4">
<div className="w-32 text-right">
<span className="px-3 py-1 bg-red-600 text-white text-xs rounded font-medium">
Hoch
</span>
</div>
<div className="flex-1 h-8 bg-slate-100 rounded relative overflow-hidden">
<div className="absolute inset-y-0 left-0 w-0 bg-red-600 rounded" />
<span className="absolute inset-0 flex items-center justify-center text-xs text-slate-500">
0 Module - Keine automatischen Entscheidungen
</span>
</div>
</div>
{/* Limited */}
<div className="flex items-center gap-4">
<div className="w-32 text-right">
<span className="px-3 py-1 bg-amber-500 text-white text-xs rounded font-medium">
Begrenzt
</span>
</div>
<div className="flex-1 h-8 bg-slate-100 rounded relative overflow-hidden">
<div
className="absolute inset-y-0 left-0 bg-amber-500 rounded transition-all"
style={{ width: `${(stats.limitedRisk / stats.totalModules) * 100}%` }}
/>
<span className="absolute inset-0 flex items-center justify-center text-xs font-medium text-slate-700">
{stats.limitedRisk} Module - Transparenzpflichten
</span>
</div>
</div>
{/* Minimal */}
<div className="flex items-center gap-4">
<div className="w-32 text-right">
<span className="px-3 py-1 bg-green-600 text-white text-xs rounded font-medium">
Minimal
</span>
</div>
<div className="flex-1 h-8 bg-slate-100 rounded relative overflow-hidden">
<div
className="absolute inset-y-0 left-0 bg-green-600 rounded transition-all"
style={{ width: `${(stats.minimalRisk / stats.totalModules) * 100}%` }}
/>
<span className="absolute inset-0 flex items-center justify-center text-xs font-medium text-slate-700">
{stats.minimalRisk} Module - Freiwillige Kodizes
</span>
</div>
</div>
</div>
</div>
{/* Key Arguments */}
<div className="bg-white rounded-xl border border-slate-200 p-6">
<h3 className="font-semibold text-slate-900 mb-4">Kernargumente fuer Limited Risk</h3>
<div className="grid md:grid-cols-2 gap-4">
<div className="flex items-start gap-3 p-4 bg-green-50 rounded-lg">
<span className="text-xl"></span>
<div>
<div className="font-medium text-green-900">Assistiv, nicht autonom</div>
<div className="text-sm text-green-700">KI liefert Vorschlaege, keine Entscheidungen</div>
</div>
</div>
<div className="flex items-start gap-3 p-4 bg-green-50 rounded-lg">
<span className="text-xl"></span>
<div>
<div className="font-medium text-green-900">Human-in-the-Loop</div>
<div className="text-sm text-green-700">Lehrkraft hat immer das letzte Wort</div>
</div>
</div>
<div className="flex items-start gap-3 p-4 bg-green-50 rounded-lg">
<span className="text-xl"></span>
<div>
<div className="font-medium text-green-900">Keine Schuelerklassifikation</div>
<div className="text-sm text-green-700">Keine Kategorisierung oder Profiling</div>
</div>
</div>
<div className="flex items-start gap-3 p-4 bg-green-50 rounded-lg">
<span className="text-xl"></span>
<div>
<div className="font-medium text-green-900">Transparente Kennzeichnung</div>
<div className="text-sm text-green-700">KI-Inhalte sind klar markiert</div>
</div>
</div>
</div>
</div>
{/* Management Statement */}
<div className="bg-gradient-to-br from-slate-800 to-slate-900 rounded-xl p-6 text-white">
<div className="flex items-start gap-4">
<span className="text-3xl">💬</span>
<div>
<h3 className="font-semibold text-lg">Management-Statement (Pitch-faehig)</h3>
<blockquote className="mt-3 text-slate-300 italic border-l-4 border-amber-500 pl-4">
&ldquo;Breakpilot ist ein KI-Assistenzsystem mit begrenztem Risiko gemaess EU-AI-Act.
Die KI trifft keine Entscheidungen, sondern unterstuetzt Lehrkraefte transparent und nachvollziehbar.
Alle paedagogischen und rechtlichen Entscheidungen verbleiben beim Menschen.&rdquo;
</blockquote>
</div>
</div>
</div>
</div>
)}
{/* Modules Tab */}
{activeTab === 'modules' && (
<div className="space-y-4">
<div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
<table className="w-full">
<thead className="bg-slate-50 border-b border-slate-200">
<tr>
<th className="text-left px-4 py-3 text-xs font-medium text-slate-500 uppercase">Modul</th>
<th className="text-left px-4 py-3 text-xs font-medium text-slate-500 uppercase">Risikostufe</th>
<th className="text-left px-4 py-3 text-xs font-medium text-slate-500 uppercase">Human-in-Loop</th>
<th className="text-left px-4 py-3 text-xs font-medium text-slate-500 uppercase">AI-Act Artikel</th>
<th className="px-4 py-3"></th>
</tr>
</thead>
<tbody className="divide-y divide-slate-100">
{MODULE_ASSESSMENTS.map((module) => {
const riskInfo = getRiskLevelInfo(module.riskLevel)
const isExpanded = expandedModule === module.id
return (
<>
<tr key={module.id} className="hover:bg-slate-50">
<td className="px-4 py-3">
<div className="font-medium text-slate-800">{module.name}</div>
<div className="text-sm text-slate-500">{module.description}</div>
</td>
<td className="px-4 py-3">
<span className={`px-3 py-1 rounded text-xs font-medium ${riskInfo.color}`}>
{riskInfo.label}
</span>
</td>
<td className="px-4 py-3">
{module.humanInLoop ? (
<span className="text-green-600 font-medium"> Ja</span>
) : (
<span className="text-red-600 font-medium"> Nein</span>
)}
</td>
<td className="px-4 py-3 text-sm text-slate-600">{module.aiActArticle}</td>
<td className="px-4 py-3">
<button
onClick={() => setExpandedModule(isExpanded ? null : module.id)}
className="text-purple-600 hover:text-purple-800 text-sm"
>
{isExpanded ? 'Weniger' : 'Details'}
</button>
</td>
</tr>
{isExpanded && (
<tr key={`${module.id}-details`}>
<td colSpan={5} className="px-4 py-4 bg-slate-50">
<div className="space-y-3">
<div>
<div className="text-xs font-medium text-slate-500 uppercase mb-1">Begruendung</div>
<div className="text-sm text-slate-700">{module.justification}</div>
</div>
<div>
<div className="text-xs font-medium text-slate-500 uppercase mb-1">
Transparenzmassnahmen
</div>
<ul className="text-sm text-slate-700 list-disc list-inside">
{module.transparencyMeasures.map((measure, i) => (
<li key={i}>{measure}</li>
))}
</ul>
</div>
</div>
</td>
</tr>
)}
</>
)
})}
</tbody>
</table>
</div>
</div>
)}
{/* Warnings Tab */}
{activeTab === 'warnings' && (
<div className="space-y-6">
<div className="bg-red-50 border border-red-200 rounded-xl p-6">
<div className="flex items-start gap-4">
<span className="text-3xl">🚫</span>
<div>
<h3 className="font-semibold text-red-900">
Warnlinien: Was wir NIEMALS bauen duerfen
</h3>
<p className="text-red-700 mt-1">
Diese Features wuerden Breakpilot in die High-Risk oder Unzulaessig-Kategorie verschieben.
Sie sind explizit von der Roadmap ausgeschlossen.
</p>
</div>
</div>
</div>
<div className="grid gap-4">
{WARNING_LINES.map((warning) => {
const statusInfo = getStatusInfo(warning.currentStatus)
const riskInfo = getRiskLevelInfo(warning.wouldTrigger)
return (
<div
key={warning.id}
className={`bg-white rounded-xl border-2 ${
warning.currentStatus === 'safe'
? 'border-green-200'
: warning.currentStatus === 'approaching'
? 'border-amber-300'
: 'border-red-400'
} p-4`}
>
<div className="flex items-start justify-between">
<div className="flex items-start gap-3">
<div
className={`w-10 h-10 rounded-full flex items-center justify-center text-lg ${statusInfo.color}`}
>
{statusInfo.icon}
</div>
<div>
<h4 className="font-semibold text-slate-900">{warning.title}</h4>
<p className="text-sm text-slate-600 mt-1">{warning.description}</p>
</div>
</div>
<div className="flex items-center gap-2">
<span className="text-xs text-slate-500">Wuerde ausloesen:</span>
<span className={`px-2 py-1 rounded text-xs font-medium ${riskInfo.color}`}>
{riskInfo.label}
</span>
</div>
</div>
<div className="mt-3 pl-13 ml-13">
<div className="flex items-center gap-2 text-sm">
<span className="text-slate-500">Empfehlung:</span>
<span className="text-slate-700">{warning.recommendation}</span>
</div>
</div>
</div>
)
})}
</div>
{/* Safe Zone Indicator */}
<div className="bg-green-50 border border-green-200 rounded-xl p-6">
<div className="flex items-center gap-4">
<div className="w-16 h-16 rounded-full bg-green-200 flex items-center justify-center">
<span className="text-3xl"></span>
</div>
<div>
<h3 className="font-semibold text-green-900">
Alle Warnlinien eingehalten: {stats.warningsSafe}/{stats.warningsTotal}
</h3>
<p className="text-green-700 mt-1">
Breakpilot befindet sich sicher im Limited/Minimal Risk Bereich des EU-AI-Act.
</p>
</div>
</div>
</div>
</div>
)}
{/* Documentation Tab */}
{activeTab === 'documentation' && (
<div className="space-y-6">
<div className="bg-white rounded-xl border border-slate-200 p-6">
<div className="flex items-start justify-between">
<div>
<h3 className="font-semibold text-slate-900">Klassifizierungs-Memo exportieren</h3>
<p className="text-slate-600 mt-1">
Generiert ein vollstaendiges Compliance-Dokument zur Vorlage bei Auditoren oder Investoren.
</p>
</div>
<button
onClick={downloadMemo}
className="px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors flex items-center gap-2"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
/>
</svg>
Als TXT herunterladen
</button>
</div>
</div>
{/* Preview */}
<div className="bg-white rounded-xl border border-slate-200 p-6">
<h3 className="font-semibold text-slate-900 mb-4">Vorschau</h3>
<pre className="bg-slate-900 text-slate-100 p-4 rounded-lg overflow-x-auto text-xs font-mono whitespace-pre-wrap max-h-96 overflow-y-auto">
{generateMemo()}
</pre>
</div>
{/* Human-in-the-Loop Documentation */}
<div className="bg-white rounded-xl border border-slate-200 p-6">
<h3 className="font-semibold text-slate-900 mb-4">Human-in-the-Loop Nachweis</h3>
<div className="space-y-4">
<div className="p-4 bg-blue-50 rounded-lg">
<h4 className="font-medium text-blue-900">Technische Massnahmen</h4>
<ul className="mt-2 text-sm text-blue-800 space-y-1">
<li> Kein Auto-Accept Button fuer KI-Vorschlaege</li>
<li> Mindestens 2 Klicks fuer Uebernahme erforderlich</li>
<li> Alle KI-Outputs sind editierbar</li>
<li> Pflicht-Review vor Freigabe an Schueler/Eltern</li>
<li> Audit-Trail dokumentiert alle menschlichen Eingriffe</li>
</ul>
</div>
<div className="p-4 bg-blue-50 rounded-lg">
<h4 className="font-medium text-blue-900">UI-Kennzeichnungen</h4>
<ul className="mt-2 text-sm text-blue-800 space-y-1">
<li> &ldquo;KI-Vorschlag&rdquo; Label auf allen generierten Inhalten</li>
<li> &ldquo;Endverantwortung liegt bei der Lehrkraft&rdquo; Hinweis</li>
<li> Confidence-Scores wo relevant</li>
<li> Quellenangaben fuer RAG-basierte Inhalte</li>
</ul>
</div>
</div>
</div>
</div>
)}
</div>
</div>
</div>
)
}