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>
This commit is contained in:
243
website/app/admin/onboarding/page.tsx
Normal file
243
website/app/admin/onboarding/page.tsx
Normal file
@@ -0,0 +1,243 @@
|
||||
'use client'
|
||||
|
||||
import AdminLayout from '@/components/admin/AdminLayout'
|
||||
import SystemInfoSection, { SYSTEM_INFO_CONFIGS } from '@/components/admin/SystemInfoSection'
|
||||
import { AVAILABLE_WIZARDS, MODULE_ARCHITECTURE } from '@/lib/architecture-data'
|
||||
|
||||
interface WizardCardProps {
|
||||
module: string
|
||||
available: boolean
|
||||
steps: number
|
||||
priority: 'high' | 'medium' | 'low'
|
||||
}
|
||||
|
||||
const PRIORITY_STYLES = {
|
||||
high: 'border-red-200 bg-red-50',
|
||||
medium: 'border-yellow-200 bg-yellow-50',
|
||||
low: 'border-gray-200 bg-gray-50',
|
||||
}
|
||||
|
||||
const PRIORITY_LABELS = {
|
||||
high: { text: 'Hohe Prioritaet', color: 'text-red-700 bg-red-100' },
|
||||
medium: { text: 'Mittlere Prioritaet', color: 'text-yellow-700 bg-yellow-100' },
|
||||
low: { text: 'Niedrige Prioritaet', color: 'text-gray-700 bg-gray-100' },
|
||||
}
|
||||
|
||||
const MODULE_ICONS: Record<string, string> = {
|
||||
middleware: '🔧',
|
||||
consent: '📋',
|
||||
dsr: '🔒',
|
||||
security: '🛡️',
|
||||
rbac: '👥',
|
||||
communication: '💬',
|
||||
mail: '📧',
|
||||
gpu: '🎮',
|
||||
llm: '🤖',
|
||||
rag: '📚',
|
||||
'unity-bridge': '🔌',
|
||||
}
|
||||
|
||||
function WizardCard({ module, available, steps, priority }: WizardCardProps) {
|
||||
const architecture = MODULE_ARCHITECTURE[module]
|
||||
const priorityStyle = PRIORITY_STYLES[priority]
|
||||
const priorityLabel = PRIORITY_LABELS[priority]
|
||||
const icon = MODULE_ICONS[module] || '📦'
|
||||
|
||||
return (
|
||||
<div className={`rounded-xl border-2 p-6 transition-all ${priorityStyle} ${
|
||||
available ? 'hover:shadow-lg cursor-pointer' : 'opacity-60'
|
||||
}`}>
|
||||
{/* Header */}
|
||||
<div className="flex items-start justify-between mb-4">
|
||||
<div className="flex items-center">
|
||||
<span className="text-3xl mr-3">{icon}</span>
|
||||
<div>
|
||||
<h3 className="font-semibold text-gray-900">{architecture?.displayName || module}</h3>
|
||||
<p className="text-sm text-gray-600">{architecture?.description || ''}</p>
|
||||
</div>
|
||||
</div>
|
||||
<span className={`text-xs px-2 py-1 rounded-full ${priorityLabel.color}`}>
|
||||
{priorityLabel.text}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Services */}
|
||||
{architecture && (
|
||||
<div className="mb-4">
|
||||
<h4 className="text-xs font-medium text-gray-500 uppercase tracking-wide mb-2">
|
||||
Beteiligte Services
|
||||
</h4>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{architecture.primaryServices.map((service) => (
|
||||
<span
|
||||
key={service}
|
||||
className="px-2 py-1 bg-white rounded text-xs text-gray-700 border"
|
||||
>
|
||||
{service}
|
||||
</span>
|
||||
))}
|
||||
{architecture.databases.map((db) => (
|
||||
<span
|
||||
key={db}
|
||||
className="px-2 py-1 bg-blue-50 rounded text-xs text-blue-700 border border-blue-200"
|
||||
>
|
||||
{db}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Footer */}
|
||||
<div className="flex items-center justify-between pt-4 border-t border-gray-200">
|
||||
<span className="text-sm text-gray-500">{steps} Schritte</span>
|
||||
{available ? (
|
||||
<a
|
||||
href={`/admin/${module}/wizard`}
|
||||
className="inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-lg text-sm font-medium hover:bg-blue-700 transition-colors"
|
||||
>
|
||||
Wizard starten →
|
||||
</a>
|
||||
) : (
|
||||
<span className="text-sm text-gray-400 italic">Demnachst verfuegbar</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function OnboardingPage() {
|
||||
const availableCount = AVAILABLE_WIZARDS.filter((w) => w.available).length
|
||||
const totalCount = AVAILABLE_WIZARDS.length
|
||||
|
||||
return (
|
||||
<AdminLayout
|
||||
title="Onboarding Center"
|
||||
description="Interaktive Lern-Wizards fuer alle Admin-Module"
|
||||
>
|
||||
{/* Hero Section */}
|
||||
<div className="bg-gradient-to-r from-blue-600 to-purple-600 rounded-xl p-8 mb-8 text-white">
|
||||
<div className="flex items-center mb-4">
|
||||
<span className="text-4xl mr-4">🎓</span>
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold">Willkommen im Onboarding Center</h2>
|
||||
<p className="text-blue-100 mt-1">
|
||||
Lernen Sie alle Admin-Module interaktiv kennen und testen Sie gleichzeitig alle Funktionen
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-3 gap-4 mt-6">
|
||||
<div className="bg-white/10 rounded-lg p-4 text-center">
|
||||
<div className="text-3xl font-bold">{availableCount}</div>
|
||||
<div className="text-sm text-blue-100">Verfuegbare Wizards</div>
|
||||
</div>
|
||||
<div className="bg-white/10 rounded-lg p-4 text-center">
|
||||
<div className="text-3xl font-bold">{totalCount}</div>
|
||||
<div className="text-sm text-blue-100">Geplante Module</div>
|
||||
</div>
|
||||
<div className="bg-white/10 rounded-lg p-4 text-center">
|
||||
<div className="text-3xl font-bold">~45</div>
|
||||
<div className="text-sm text-blue-100">Minuten Onboarding</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* What You Learn */}
|
||||
<div className="bg-white rounded-xl border p-6 mb-8">
|
||||
<h3 className="font-semibold text-gray-900 mb-4 flex items-center">
|
||||
<span className="mr-2">💡</span>
|
||||
Was Sie in den Wizards lernen
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div className="flex items-start">
|
||||
<span className="text-2xl mr-3">📖</span>
|
||||
<div>
|
||||
<h4 className="font-medium text-gray-900">Lernmaterial</h4>
|
||||
<p className="text-sm text-gray-600">
|
||||
Warum jede Funktion wichtig ist und welche Probleme sie loest
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start">
|
||||
<span className="text-2xl mr-3">🧪</span>
|
||||
<div>
|
||||
<h4 className="font-medium text-gray-900">Interaktive Tests</h4>
|
||||
<p className="text-sm text-gray-600">
|
||||
Alle Funktionen durchklicken und automatisch verifizieren
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start">
|
||||
<span className="text-2xl mr-3">🏗️</span>
|
||||
<div>
|
||||
<h4 className="font-medium text-gray-900">Architektur-Kontext</h4>
|
||||
<p className="text-sm text-gray-600">
|
||||
Wo Sie sich im System befinden und welche Services beteiligt sind
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Wizard Grid */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-semibold text-gray-900 mb-4">Verfuegbare Wizards</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{AVAILABLE_WIZARDS.filter((w) => w.available).map((wizard) => (
|
||||
<WizardCard key={wizard.module} {...wizard} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Coming Soon */}
|
||||
<div className="mt-8">
|
||||
<h3 className="text-lg font-semibold text-gray-900 mb-4">Demnachst verfuegbar</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{AVAILABLE_WIZARDS.filter((w) => !w.available).map((wizard) => (
|
||||
<WizardCard key={wizard.module} {...wizard} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quick Start Guide */}
|
||||
<div className="mt-8 bg-slate-900 rounded-xl p-6 text-white">
|
||||
<h3 className="font-semibold mb-4 flex items-center">
|
||||
<span className="mr-2">🚀</span>
|
||||
Schnellstart-Empfehlung
|
||||
</h3>
|
||||
<ol className="space-y-3">
|
||||
<li className="flex items-start">
|
||||
<span className="w-6 h-6 rounded-full bg-blue-500 flex items-center justify-center text-sm font-bold mr-3 flex-shrink-0">
|
||||
1
|
||||
</span>
|
||||
<div>
|
||||
<strong>Middleware Wizard</strong> - Verstehen Sie die Sicherheitsschicht, die alle Anfragen durchlaufen
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start">
|
||||
<span className="w-6 h-6 rounded-full bg-blue-500 flex items-center justify-center text-sm font-bold mr-3 flex-shrink-0">
|
||||
2
|
||||
</span>
|
||||
<div>
|
||||
<strong>Consent Wizard</strong> - Lernen Sie die DSGVO-konforme Einwilligungsverwaltung
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start">
|
||||
<span className="w-6 h-6 rounded-full bg-blue-500 flex items-center justify-center text-sm font-bold mr-3 flex-shrink-0">
|
||||
3
|
||||
</span>
|
||||
<div>
|
||||
<strong>Security Wizard</strong> - DevSecOps Praktiken und Sicherheitsscans verstehen
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
{/* System Info Section - For Internal/External Audits */}
|
||||
<div className="mt-8 border-t border-slate-200 pt-8">
|
||||
<SystemInfoSection config={SYSTEM_INFO_CONFIGS.onboarding} />
|
||||
</div>
|
||||
</AdminLayout>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user