Files
breakpilot-lehrer/studio-v2/app/dashboard-experimental/page.tsx
Benjamin Admin b4613e26f3 [split-required] Split 500-850 LOC files (batch 2)
backend-lehrer (10 files):
- game/database.py (785 → 5), correction_api.py (683 → 4)
- classroom_engine/antizipation.py (676 → 5)
- llm_gateway schools/edu_search already done in prior batch

klausur-service (12 files):
- orientation_crop_api.py (694 → 5), pdf_export.py (677 → 4)
- zeugnis_crawler.py (676 → 5), grid_editor_api.py (671 → 5)
- eh_templates.py (658 → 5), mail/api.py (651 → 5)
- qdrant_service.py (638 → 5), training_api.py (625 → 4)

website (6 pages):
- middleware (696 → 8), mail (733 → 6), consent (628 → 8)
- compliance/risks (622 → 5), export (502 → 5), brandbook (629 → 7)

studio-v2 (3 components):
- B2BMigrationWizard (848 → 3), CleanupPanel (765 → 2)
- dashboard-experimental (739 → 2)

admin-lehrer (4 files):
- uebersetzungen (769 → 4), manager (670 → 2)
- ChunkBrowserQA (675 → 6), dsfa/page (674 → 5)

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

204 lines
9.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
import { useState, useEffect } from 'react'
import { useRouter } from 'next/navigation'
import { PerformanceProvider, usePerformance } from '@/lib/spatial-ui/PerformanceContext'
import { FocusProvider } from '@/lib/spatial-ui/FocusContext'
import { FloatingMessage } from '@/components/spatial-ui/FloatingMessage'
import {
GlassCard, AnalogClock, Compass, BarChart, TemperatureDisplay,
ProgressRing, StatDisplay, ListItem, ActionButton, QualityIndicator,
} from './_components/DashboardWidgets'
// =============================================================================
// MAIN DASHBOARD
// =============================================================================
function DashboardContent() {
const router = useRouter()
const { settings } = usePerformance()
const [mousePos, setMousePos] = useState({ x: 0, y: 0 })
const [time, setTime] = useState(new Date())
useEffect(() => {
const timer = setInterval(() => setTime(new Date()), 1000)
return () => clearInterval(timer)
}, [])
useEffect(() => {
if (!settings.enableParallax) return
const handleMouseMove = (e: MouseEvent) => setMousePos({ x: e.clientX, y: e.clientY })
window.addEventListener('mousemove', handleMouseMove)
return () => window.removeEventListener('mousemove', handleMouseMove)
}, [settings.enableParallax])
const windowWidth = typeof window !== 'undefined' ? window.innerWidth : 1920
const windowHeight = typeof window !== 'undefined' ? window.innerHeight : 1080
const parallax = settings.enableParallax
? { x: (mousePos.x / windowWidth - 0.5) * 15, y: (mousePos.y / windowHeight - 0.5) * 15 }
: { x: 0, y: 0 }
const greeting = time.getHours() < 12 ? 'Guten Morgen' : time.getHours() < 18 ? 'Guten Tag' : 'Guten Abend'
const weeklyData = [
{ label: 'Mo', value: 4 }, { label: 'Di', value: 7 }, { label: 'Mi', value: 3 },
{ label: 'Do', value: 8 }, { label: 'Fr', value: 6, highlight: true },
{ label: 'Sa', value: 2 }, { label: 'So', value: 0 },
]
return (
<div className="min-h-screen relative overflow-hidden">
{/* Background */}
<div
className="absolute inset-0 bg-gradient-to-br from-slate-900 via-indigo-950 to-slate-900"
style={{ transform: `translate(${parallax.x * 0.5}px, ${parallax.y * 0.5}px) scale(1.05)`, transition: 'transform 0.3s ease-out' }}
>
<div className="absolute inset-0 opacity-30" style={{
backgroundImage: `radial-gradient(2px 2px at 20px 30px, white, transparent),
radial-gradient(2px 2px at 40px 70px, rgba(255,255,255,0.8), transparent),
radial-gradient(1px 1px at 90px 40px, white, transparent),
radial-gradient(2px 2px at 160px 120px, rgba(255,255,255,0.9), transparent),
radial-gradient(1px 1px at 230px 80px, white, transparent),
radial-gradient(2px 2px at 300px 150px, rgba(255,255,255,0.7), transparent)`,
backgroundSize: '400px 200px',
}} />
<div className="absolute w-[500px] h-[500px] rounded-full opacity-20" style={{
background: 'radial-gradient(circle, rgba(99, 102, 241, 0.5) 0%, transparent 70%)',
left: '10%', top: '20%', transform: `translate(${parallax.x}px, ${parallax.y}px)`, transition: 'transform 0.5s ease-out',
}} />
<div className="absolute w-[400px] h-[400px] rounded-full opacity-15" style={{
background: 'radial-gradient(circle, rgba(167, 139, 250, 0.5) 0%, transparent 70%)',
right: '5%', bottom: '10%', transform: `translate(${-parallax.x * 0.8}px, ${-parallax.y * 0.8}px)`, transition: 'transform 0.5s ease-out',
}} />
</div>
{/* Content */}
<div className="relative z-10 min-h-screen p-6">
{/* Header */}
<header className="flex items-start justify-between mb-8">
<div>
<p className="text-white/40 text-sm font-medium tracking-wide uppercase mb-1">
{time.toLocaleDateString('de-DE', { weekday: 'long', day: 'numeric', month: 'long' })}
</p>
<h1 className="text-4xl font-light text-white tracking-tight">{greeting}</h1>
</div>
<div className="flex items-center gap-3">
<GlassCard size="sm" className="!p-3">
<div className="flex items-center gap-2">
<span className="text-lg">🔔</span>
<span className="text-white font-medium text-sm">3</span>
</div>
</GlassCard>
<GlassCard size="sm" className="!p-3">
<div className="w-8 h-8 rounded-full bg-gradient-to-br from-blue-400 to-purple-500" />
</GlassCard>
</div>
</header>
{/* Main Grid */}
<div className="grid grid-cols-12 gap-4 max-w-7xl mx-auto">
<div className="col-span-3">
<GlassCard size="lg" delay={50}>
<div className="flex flex-col items-center">
<AnalogClock />
<p className="text-white text-2xl font-light mt-4">
{time.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' })}
</p>
</div>
</GlassCard>
</div>
<div className="col-span-3">
<GlassCard size="lg" delay={100}><TemperatureDisplay temp={8} condition="partly_cloudy" /></GlassCard>
</div>
<div className="col-span-3">
<GlassCard size="lg" delay={150}>
<div className="flex flex-col items-center">
<Compass direction={225} />
<p className="text-white/50 text-sm mt-3">SW Wind</p>
<p className="text-white text-lg font-light">12 km/h</p>
</div>
</GlassCard>
</div>
<div className="col-span-3">
<GlassCard size="lg" delay={200}>
<StatDisplay icon="📋" value="12" label="Offene Korrekturen" />
<div className="mt-4 pt-4 border-t border-white/10 flex justify-around">
<div className="text-center"><p className="text-xl font-light text-white">28</p><p className="text-white/40 text-xs">Diese Woche</p></div>
<div className="text-center"><p className="text-xl font-light text-white">156</p><p className="text-white/40 text-xs">Gesamt</p></div>
</div>
</GlassCard>
</div>
<div className="col-span-6">
<GlassCard size="lg" delay={250}>
<div className="flex items-center justify-between mb-4">
<h2 className="text-white text-sm font-medium uppercase tracking-wide opacity-60">Korrekturen diese Woche</h2>
<span className="text-white/40 text-sm">30 gesamt</span>
</div>
<BarChart data={weeklyData} maxValue={10} />
</GlassCard>
</div>
<div className="col-span-3">
<GlassCard size="lg" delay={300}>
<div className="flex justify-around">
<ProgressRing progress={75} label="Fortschritt" value="75%" color="#60a5fa" />
<ProgressRing progress={92} label="Qualitaet" value="92%" color="#a78bfa" />
</div>
</GlassCard>
</div>
<div className="col-span-3">
<GlassCard size="lg" delay={350}>
<StatDisplay icon="⏱" value="4.2" unit="h" label="Zeit gespart" />
<p className="text-center text-white/30 text-xs mt-3">durch KI-Unterstuetzung</p>
</GlassCard>
</div>
<div className="col-span-8">
<GlassCard size="lg" delay={400}>
<div className="flex items-center justify-between mb-3">
<h2 className="text-white text-sm font-medium uppercase tracking-wide opacity-60">Aktuelle Klausuren</h2>
<button className="text-white/40 text-xs hover:text-white transition-colors">Alle anzeigen</button>
</div>
<div className="space-y-1">
<ListItem icon="📝" title="Deutsch LK - Textanalyse" subtitle="24 Schueler" value="18/24" delay={450} />
<ListItem icon="✅" title="Deutsch GK - Eroerterung" subtitle="Abgeschlossen" value="28/28" delay={500} />
<ListItem icon="📝" title="Vorabitur - Gedichtanalyse" subtitle="22 Schueler" value="10/22" delay={550} />
</div>
</GlassCard>
</div>
<div className="col-span-4">
<GlassCard size="lg" delay={450}>
<h2 className="text-white text-sm font-medium uppercase tracking-wide opacity-60 mb-4">Schnellaktionen</h2>
<div className="space-y-2">
<ActionButton icon="" label="Neue Klausur" primary delay={500} />
<ActionButton icon="📤" label="Arbeiten hochladen" delay={550} />
<ActionButton icon="🎨" label="Worksheet Editor" onClick={() => router.push('/worksheet-editor')} delay={600} />
</div>
</GlassCard>
</div>
</div>
</div>
<FloatingMessage autoDismissMs={12000} maxQueue={3} position="top-right" offset={{ x: 24, y: 24 }} />
<QualityIndicator />
</div>
)
}
// =============================================================================
// MAIN PAGE
// =============================================================================
export default function ExperimentalDashboard() {
return (
<PerformanceProvider>
<FocusProvider>
<DashboardContent />
</FocusProvider>
</PerformanceProvider>
)
}