Files
breakpilot-lehrer/admin-lehrer/app/(admin)/ai/magic-help/page.tsx
Benjamin Admin 9ba420fa91
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 42s
CI / test-go-edu-search (push) Successful in 34s
CI / test-python-klausur (push) Failing after 2m51s
CI / test-python-agent-core (push) Successful in 21s
CI / test-nodejs-website (push) Successful in 29s
Fix: Remove broken getKlausurApiUrl and clean up empty lines
sed replacement left orphaned hostname references in story page
and empty lines in getApiBase functions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-24 16:02:04 +02:00

162 lines
5.9 KiB
TypeScript

'use client'
import { AIModuleSidebarResponsive } from '@/components/ai/AIModuleSidebar'
import { PagePurpose } from '@/components/common/PagePurpose'
import { TABS } from './types'
import { useMagicHelp } from './useMagicHelp'
import {
GlobalDragOverlay,
KeyboardShortcutsModal,
TabOverview,
TabTest,
TabBatch,
TabTraining,
TabArchitecture,
TabSettings,
} from './_components'
export default function MagicHelpPage() {
const h = useMagicHelp()
const getStatusBadge = () => {
if (!h.status) return null
switch (h.status.status) {
case 'available':
return <span className="px-3 py-1 text-xs font-medium rounded-full bg-green-100 text-green-700">Verfuegbar</span>
case 'not_installed':
return <span className="px-3 py-1 text-xs font-medium rounded-full bg-red-100 text-red-700">Nicht installiert</span>
case 'error':
return <span className="px-3 py-1 text-xs font-medium rounded-full bg-yellow-100 text-yellow-700">Fehler</span>
}
}
return (
<div className="space-y-6 relative">
<GlobalDragOverlay active={h.globalDragActive} />
<KeyboardShortcutsModal open={h.showShortcutHint} onClose={() => h.setShowShortcutHint(false)} />
{/* Header */}
<div className="flex items-center justify-between">
<div>
<h1 className="text-2xl font-bold text-slate-900 flex items-center gap-2">
<span className="text-2xl"></span>
Magic Help - Handschrifterkennung
</h1>
<p className="text-slate-500 mt-1">
KI-gestuetzte Klausurkorrektur mit TrOCR und Privacy-by-Design
</p>
</div>
<div className="flex items-center gap-3">
<button
onClick={() => h.setShowShortcutHint(true)}
className="p-2 text-slate-400 hover:text-slate-600 transition-colors"
title="Tastenkuerzel anzeigen (?)"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
</svg>
</button>
{getStatusBadge()}
</div>
</div>
{/* Page Purpose */}
<PagePurpose
title="Magic Help"
purpose="Testen und verbessern Sie die TrOCR-Handschrifterkennung. Laden Sie Bilder hoch, um die OCR-Qualitaet zu pruefen, und trainieren Sie das Modell mit LoRA Fine-Tuning. Teil der KI-Daten-Pipeline: Exportieren Sie Trainingsdaten zu OCR-Labeling oder importieren Sie Ground Truth fuer Fine-Tuning."
audience={['Entwickler', 'Administratoren', 'QA-Team']}
architecture={{
services: ['klausur-service (Python)', 'TrOCR (PyTorch)'],
databases: ['Modell-Cache', 'LoRA-Adapter'],
}}
relatedPages={[
{ name: 'OCR-Labeling', href: '/ai/ocr-labeling', description: 'Ground Truth erstellen' },
{ name: 'RAG Pipeline', href: '/ai/rag-pipeline', description: 'Erkannte Texte indexieren' },
]}
collapsible={true}
defaultCollapsed={true}
/>
<AIModuleSidebarResponsive currentModule="magic-help" />
{/* Quick paste hint */}
<div className="bg-gradient-to-r from-purple-50 to-blue-50 border border-purple-200 rounded-lg px-4 py-2 flex items-center gap-3 text-sm">
<span className="text-purple-600">💡</span>
<span className="text-slate-600">
<strong>Tipp:</strong> Druecke <kbd className="px-1.5 py-0.5 bg-white rounded border text-xs font-mono">Ctrl+V</kbd> um ein Bild aus der Zwischenablage einzufuegen, oder ziehe es einfach irgendwo ins Fenster.
</span>
</div>
{/* Tabs */}
<div className="flex gap-2 border-b border-slate-200 pb-2">
{TABS.map((tab) => (
<button
key={tab.id}
onClick={() => h.setActiveTab(tab.id)}
className={`px-4 py-2 rounded-t-lg text-sm font-medium transition-colors ${
h.activeTab === tab.id
? 'bg-purple-600 text-white'
: 'text-slate-600 hover:text-slate-900 hover:bg-slate-100'
}`}
title={tab.shortcut}
>
<span className="mr-2">{tab.icon}</span>
{tab.label}
</button>
))}
</div>
{/* Tab Content */}
{h.activeTab === 'overview' && (
<TabOverview status={h.status} loading={h.loading} onRefresh={h.fetchStatus} />
)}
{h.activeTab === 'test' && (
<TabTest
ocrResult={h.ocrResult}
ocrLoading={h.ocrLoading}
imagePreview={h.imagePreview}
uploadedImage={h.uploadedImage}
settings={h.settings}
showHeatmap={h.showHeatmap}
onToggleHeatmap={() => h.setShowHeatmap(prev => !prev)}
onFileUpload={h.handleFileUpload}
onManualOCR={h.handleManualOCR}
onClearImage={h.clearUploadedImage}
onSendToTraining={h.sendToTraining}
/>
)}
{h.activeTab === 'batch' && <TabBatch />}
{h.activeTab === 'training' && (
<TabTraining
status={h.status}
examples={h.examples}
trainingImage={h.trainingImage}
trainingText={h.trainingText}
fineTuning={h.fineTuning}
settings={h.settings}
showTrainingDashboard={h.showTrainingDashboard}
onSetTrainingImage={h.setTrainingImage}
onSetTrainingText={h.setTrainingText}
onAddExample={h.handleAddTrainingExample}
onFineTune={h.handleFineTune}
onToggleDashboard={() => h.setShowTrainingDashboard(prev => !prev)}
/>
)}
{h.activeTab === 'architecture' && <TabArchitecture />}
{h.activeTab === 'settings' && (
<TabSettings
settings={h.settings}
settingsSaved={h.settingsSaved}
onUpdateSettings={h.setSettings}
onSave={h.saveSettings}
/>
)}
</div>
)
}