'use client' /** * Companion Module Developer Dashboard * * Zentrales Dashboard fuer die Entwicklung des Companion/Lesson-Modus: * - Entwicklungsroadmap mit Phasen * - Feature Tracking * - Lehrer-Feedback Sammlung * - Backlog Management * - System-Infos */ import AdminLayout from '@/components/admin/AdminLayout' import SystemInfoSection, { SYSTEM_INFO_CONFIGS } from '@/components/admin/SystemInfoSection' import { useState, useEffect } from 'react' // ==================== TYPES ==================== interface RoadmapPhase { id: string name: string status: 'completed' | 'in_progress' | 'planned' | 'future' progress: number startDate?: string endDate?: string description: string features: string[] } interface Feature { id: string title: string description: string priority: 'critical' | 'high' | 'medium' | 'low' status: 'done' | 'in_progress' | 'todo' | 'backlog' phase: string effort: 'small' | 'medium' | 'large' | 'epic' assignee?: string dueDate?: string feedback?: string[] } interface TeacherFeedback { id: string teacher: string date: string type: 'bug' | 'feature_request' | 'improvement' | 'praise' | 'question' priority: 'critical' | 'high' | 'medium' | 'low' status: 'new' | 'acknowledged' | 'planned' | 'implemented' | 'declined' title: string description: string relatedFeature?: string response?: string } // ==================== INITIAL DATA ==================== const roadmapPhases: RoadmapPhase[] = [ { id: 'phase-1', name: 'Phase 1: Core Engine', status: 'completed', progress: 100, startDate: '2026-01-10', endDate: '2026-01-14', description: 'Grundlegende State Machine und API-Endpunkte', features: [ 'Finite State Machine (5 Phasen)', 'Timer Service mit Countdown', 'Phasenspezifische Suggestions', 'REST API Endpoints', 'In-Memory Session Storage', ], }, { id: 'phase-2', name: 'Phase 2: Frontend Integration', status: 'completed', progress: 100, startDate: '2026-01-14', endDate: '2026-01-14', description: 'Integration in das Studio-Frontend', features: [ 'Lesson-Modus im Companion', 'Timer-Anzeige mit Warning/Overtime', 'Phasen-Timeline Visualisierung', 'Suggestions pro Phase', 'Session Start/End UI', ], }, { id: 'phase-2b', name: 'Phase 2b: Teacher UX Optimierung', status: 'completed', progress: 100, startDate: '2026-01-15', endDate: '2026-01-15', description: 'Forschungsbasierte UX-Verbesserungen fuer intuitive Lehrer-Bedienung', features: [ 'Visual Pie Timer (Kreis statt Zahlen)', 'Phasen-Farbschema (Blau→Orange→Gruen→Lila→Grau)', 'Quick Actions Bar (+5min, Pause, Skip)', 'Tablet-First Responsive Design', 'Large Touch Targets (48x48px min)', 'High Contrast fuer Beamer', 'Audio Cues (sanfte Toene)', ], }, { id: 'phase-3', name: 'Phase 3: Persistenz', status: 'completed', progress: 100, startDate: '2026-01-15', endDate: '2026-01-15', description: 'Datenbank-Anbindung und Session-Persistenz', features: [ 'PostgreSQL Integration (done)', 'SQLAlchemy Models (done)', 'Session Repository (done)', 'Alembic Migration Scripts (done)', 'Session History API (done)', 'Hybrid Storage (Memory+DB) (done)', 'Lehrer-spezifische Settings (backlog)', 'Keycloak Auth Integration (backlog)', ], }, { id: 'phase-4', name: 'Phase 4: Content Integration', status: 'completed', progress: 100, startDate: '2026-01-15', endDate: '2026-01-15', description: 'Verknuepfung mit Learning Units', features: [ 'Lesson Templates (done)', 'Fachspezifische Unit-Vorschlaege (done)', 'Hausaufgaben-Tracker (done)', 'Material-Verknuepfung (done)', ], }, { id: 'phase-5', name: 'Phase 5: Analytics', status: 'completed', progress: 100, startDate: '2026-01-15', endDate: '2026-01-15', description: 'Unterrichtsanalyse und Optimierung (ohne wertende Metriken)', features: [ 'Phasen-Dauer Statistiken (done)', 'Overtime-Analyse (done)', 'Post-Lesson Reflection API (done)', 'Lehrer-Dashboard UI (done)', 'HTML/PDF Export (done)', ], }, { id: 'phase-6', name: 'Phase 6: Real-time', status: 'completed', progress: 100, startDate: '2026-01-15', endDate: '2026-01-15', description: 'WebSocket-basierte Echtzeit-Updates', features: [ 'WebSocket API Endpoint (done)', 'Connection Manager mit Multi-Device Support (done)', 'Timer Broadcast Loop (1-Sekunden-Genauigkeit) (done)', 'Client-seitiger WebSocket Handler (done)', 'Automatischer Reconnect mit Fallback zu Polling (done)', 'Phase Change & Session End Notifications (done)', 'Connection Status Indicator (done)', 'WebSocket Tests (done)', ], }, { id: 'phase-7', name: 'Phase 7: Erweiterungen', status: 'completed', progress: 100, startDate: '2026-01-15', endDate: '2026-01-15', description: 'Lehrer-Feedback und Authentifizierung', features: [ 'Teacher Feedback API (done)', 'Feedback Modal im Lehrer-Frontend (done)', 'Keycloak Auth Integration (done)', 'Optional Auth Dependency (done)', 'Feedback DB Model & Migration (done)', 'Feedback Repository (done)', ], }, { id: 'phase-8', name: 'Phase 8: Schuljahres-Begleiter', status: 'in_progress', progress: 85, startDate: '2026-01-15', description: '2-Schichten-Modell: Makro-Phasen (Schuljahr) + Mikro-Engine (Events/Routinen)', features: [ 'Kontext-Datenmodell (TeacherContextDB, SchoolyearEventDB, RecurringRoutineDB) (done)', 'Alembic Migration 007 (done)', 'GET /v1/context Endpoint (done)', 'Events & Routinen CRUD-APIs (done)', 'Bundeslaender & Schularten Stammdaten (done)', 'Antizipations-Engine mit 12 Regeln (done)', 'GET /v1/suggestions Endpoint (done)', 'Dynamische Sidebar /v1/sidebar (done)', 'Schuljahres-Pfad /v1/path (done)', 'Frontend ContextBar Component (done)', 'Frontend Dynamic Sidebar (done)', 'Frontend PathPanel Component (done)', 'Main Content Actions Integration (done)', 'Onboarding-Flow (geplant)', ], }, { id: 'phase-9', name: 'Phase 9: Zukunft', status: 'future', progress: 0, description: 'Weitere geplante Features', features: [ 'Push Notifications', 'Dark Mode', 'Lesson Templates Library (erweitert)', 'Multi-Language Support', 'KI-Assistenz fuer Unterrichtsplanung', ], }, ] const initialFeatures: Feature[] = [ // Phase 1 - Done { id: 'f1', title: 'LessonPhase Enum', description: '7 Zustaende: not_started, 5 Phasen, ended', priority: 'critical', status: 'done', phase: 'phase-1', effort: 'small' }, { id: 'f2', title: 'LessonSession Dataclass', description: 'Session-Datenmodell mit History', priority: 'critical', status: 'done', phase: 'phase-1', effort: 'medium' }, { id: 'f3', title: 'FSM Transitions', description: 'Erlaubte Phasen-Uebergaenge', priority: 'critical', status: 'done', phase: 'phase-1', effort: 'medium' }, { id: 'f4', title: 'PhaseTimer Service', description: 'Countdown, Warning, Overtime', priority: 'high', status: 'done', phase: 'phase-1', effort: 'medium' }, { id: 'f5', title: 'SuggestionEngine', description: 'Phasenspezifische Aktivitaets-Vorschlaege', priority: 'high', status: 'done', phase: 'phase-1', effort: 'large' }, { id: 'f6', title: 'REST API Endpoints', description: '10 Endpoints unter /api/classroom', priority: 'critical', status: 'done', phase: 'phase-1', effort: 'large' }, // Phase 2 - Done { id: 'f7', title: 'Mode Toggle (3 Modi)', description: 'Begleiter, Stunde, Klassisch', priority: 'high', status: 'done', phase: 'phase-2', effort: 'small' }, { id: 'f8', title: 'Timer-Display', description: 'Grosser Countdown mit Styling', priority: 'high', status: 'done', phase: 'phase-2', effort: 'medium' }, { id: 'f9', title: 'Phasen-Timeline', description: 'Horizontale 5-Phasen-Anzeige', priority: 'high', status: 'done', phase: 'phase-2', effort: 'medium' }, { id: 'f10', title: 'Control Buttons', description: 'Naechste Phase, Beenden', priority: 'high', status: 'done', phase: 'phase-2', effort: 'small' }, { id: 'f11', title: 'Suggestions Cards', description: 'Aktivitaets-Vorschlaege UI', priority: 'medium', status: 'done', phase: 'phase-2', effort: 'medium' }, { id: 'f12', title: 'Session Start Form', description: 'Klasse, Fach, Thema auswaehlen', priority: 'high', status: 'done', phase: 'phase-2', effort: 'small' }, // Phase 3 - In Progress (Persistenz) { id: 'f13', title: 'PostgreSQL Models', description: 'SQLAlchemy Models fuer Sessions (LessonSessionDB, PhaseHistoryDB, TeacherSettingsDB)', priority: 'critical', status: 'done', phase: 'phase-3', effort: 'medium' }, { id: 'f14', title: 'Session Repository', description: 'CRUD Operationen fuer Sessions (SessionRepository, TeacherSettingsRepository)', priority: 'critical', status: 'done', phase: 'phase-3', effort: 'medium' }, { id: 'f15', title: 'Migration Scripts', description: 'Alembic Migrationen fuer Classroom Tables', priority: 'high', status: 'done', phase: 'phase-3', effort: 'small' }, { id: 'f16', title: 'Teacher Settings', description: 'Individuelle Phasen-Dauern speichern (API + Settings Modal UI)', priority: 'medium', status: 'done', phase: 'phase-7', effort: 'medium' }, { id: 'f17', title: 'Session History API', description: 'GET /history/{teacher_id} mit Pagination', priority: 'medium', status: 'done', phase: 'phase-3', effort: 'small' }, // Phase 4 - In Progress (Content) { id: 'f18', title: 'Unit-Vorschlaege', description: 'Fachspezifische Learning Units pro Phase (Mathe, Deutsch, Englisch, Bio, Physik, Informatik)', priority: 'high', status: 'done', phase: 'phase-4', effort: 'large' }, { id: 'f19', title: 'Material-Verknuepfung', description: 'Dokumente an Phasen anhaengen (PhaseMaterial Model, Repository, 8 API-Endpoints, Frontend-Integration)', priority: 'medium', status: 'done', phase: 'phase-4', effort: 'medium' }, { id: 'f20', title: 'Hausaufgaben-Tracker', description: 'CRUD API fuer Hausaufgaben mit Status und Faelligkeit', priority: 'medium', status: 'done', phase: 'phase-4', effort: 'medium' }, // ==================== NEUE UX FEATURES (aus Research) ==================== // P0 - KRITISCH (UX Research basiert) { id: 'f21', title: 'Visual Pie Timer', description: 'Kreisfoermiger Countdown mit Farbverlauf (Gruen→Gelb→Rot) - reduziert Stress laut Forschung', priority: 'critical', status: 'done', phase: 'phase-2', effort: 'large' }, { id: 'f22', title: 'Database Persistence', description: 'PostgreSQL statt In-Memory - Sessions ueberleben Neustart (Hybrid Storage)', priority: 'critical', status: 'done', phase: 'phase-3', effort: 'large' }, { id: 'f23', title: 'Teacher Auth Integration', description: 'Keycloak-Anbindung mit optionalem Demo-User Fallback', priority: 'critical', status: 'done', phase: 'phase-7', effort: 'large' }, { id: 'f24', title: 'Tablet-First Responsive', description: 'Optimiert fuer 10" Touch-Screens, Einhand-Bedienung im Klassenraum', priority: 'critical', status: 'done', phase: 'phase-2b', effort: 'medium' }, // P1 - WICHTIG (UX Research basiert) { id: 'f25', title: 'Phasen-Farbschema', description: 'Forschungsbasierte Farben: Blau(Einstieg), Orange(Erarbeitung), Gruen(Sicherung), Lila(Transfer), Grau(Reflexion)', priority: 'high', status: 'done', phase: 'phase-2b', effort: 'medium' }, { id: 'f26', title: 'Quick Actions Bar', description: '+5min, Pause, Skip-Phase als One-Click Touch-Buttons (min 56px)', priority: 'high', status: 'done', phase: 'phase-2b', effort: 'medium' }, { id: 'f27', title: 'Pause Timer API', description: 'POST /sessions/{id}/pause - Timer anhalten bei Stoerungen', priority: 'high', status: 'done', phase: 'phase-2b', effort: 'small' }, { id: 'f28', title: 'Extend Phase API', description: 'POST /sessions/{id}/extend?minutes=5 - Phase verlaengern', priority: 'high', status: 'done', phase: 'phase-2b', effort: 'small' }, { id: 'f29', title: 'Non-Intrusive Suggestions', description: 'Vorschlaege in dedizierter Sektion, nicht als stoerende Popups', priority: 'high', status: 'done', phase: 'phase-2', effort: 'medium' }, { id: 'f30', title: 'WebSocket Real-Time Timer', description: 'Sub-Sekunden Genauigkeit statt 5s Polling', priority: 'high', status: 'done', phase: 'phase-6', effort: 'large' }, { id: 'f31', title: 'Mobile Breakpoints', description: 'Responsive Design fuer 600px, 900px, 1200px Screens', priority: 'high', status: 'done', phase: 'phase-2b', effort: 'medium' }, { id: 'f32', title: 'Large Touch Targets', description: 'Alle Buttons min 48x48px fuer sichere Touch-Bedienung', priority: 'high', status: 'done', phase: 'phase-2b', effort: 'small' }, // P2 - NICE-TO-HAVE (UX Research basiert) { id: 'f33', title: 'Audio Cues', description: 'Sanfte Toene bei Phasenwechsel und Warnungen (Taste A zum Toggle)', priority: 'medium', status: 'done', phase: 'phase-2b', effort: 'small' }, { id: 'f34', title: 'Keyboard Shortcuts', description: 'Space=Pause, N=Next Phase, E=Extend, H=High Contrast - fuer Desktop-Nutzung', priority: 'medium', status: 'done', phase: 'phase-2b', effort: 'small' }, { id: 'f35', title: 'Offline Timer Fallback', description: 'Client-seitige Timer-Berechnung bei Verbindungsverlust', priority: 'medium', status: 'done', phase: 'phase-2b', effort: 'medium' }, { id: 'f36', title: 'Post-Lesson Analytics', description: 'Phasen-Dauer Statistiken ohne wertende Metriken (SessionSummary, TeacherAnalytics, 4 API-Endpoints)', priority: 'medium', status: 'done', phase: 'phase-5', effort: 'large' }, { id: 'f37', title: 'Lesson Templates', description: '5 System-Templates + eigene Vorlagen erstellen/speichern', priority: 'medium', status: 'done', phase: 'phase-4', effort: 'medium' }, { id: 'f38', title: 'ARIA Labels', description: 'Screen-Reader Unterstuetzung fuer Barrierefreiheit', priority: 'medium', status: 'done', phase: 'phase-2b', effort: 'small' }, { id: 'f39', title: 'High Contrast Mode', description: 'Erhoehter Kontrast fuer Beamer/Projektor (Taste H)', priority: 'medium', status: 'done', phase: 'phase-2b', effort: 'small' }, { id: 'f40', title: 'Export to PDF', description: 'Stundenprotokoll als druckbares HTML mit Browser-PDF-Export (Strg+P)', priority: 'low', status: 'done', phase: 'phase-5', effort: 'medium' }, { id: 'f41', title: 'Overtime-Analyse', description: 'Phase-by-Phase Overtime-Statistiken und Trends', priority: 'medium', status: 'done', phase: 'phase-5', effort: 'medium' }, { id: 'f42', title: 'Post-Lesson Reflection', description: 'Reflexions-Notizen nach Stundenende (CRUD API, DB-Model)', priority: 'medium', status: 'done', phase: 'phase-5', effort: 'medium' }, { id: 'f43', title: 'Phase Duration Trends', description: 'Visualisierung der Phasendauer-Entwicklung', priority: 'medium', status: 'done', phase: 'phase-5', effort: 'small' }, { id: 'f44', title: 'Analytics Dashboard UI', description: 'Lehrer-Frontend fuer Analytics-Anzeige (Phasen-Bars, Overtime, Reflection)', priority: 'high', status: 'done', phase: 'phase-5', effort: 'medium' }, // Phase 6 - Real-time (WebSocket) { id: 'f45', title: 'WebSocket API Endpoint', description: 'Real-time Verbindung unter /api/classroom/ws/{session_id}', priority: 'critical', status: 'done', phase: 'phase-6', effort: 'large' }, { id: 'f46', title: 'Connection Manager', description: 'Multi-Device Support mit Session-basierter Verbindungsverwaltung', priority: 'critical', status: 'done', phase: 'phase-6', effort: 'medium' }, { id: 'f47', title: 'Timer Broadcast Loop', description: 'Hintergrund-Task sendet Timer-Updates jede Sekunde an alle Clients', priority: 'critical', status: 'done', phase: 'phase-6', effort: 'medium' }, { id: 'f48', title: 'Client WebSocket Handler', description: 'Frontend-Integration mit automatischem Reconnect und Fallback zu Polling', priority: 'high', status: 'done', phase: 'phase-6', effort: 'large' }, { id: 'f49', title: 'Phase Change Notifications', description: 'Echtzeit-Benachrichtigung bei Phasenwechsel an alle Devices', priority: 'high', status: 'done', phase: 'phase-6', effort: 'small' }, { id: 'f50', title: 'Session End Notifications', description: 'Automatische Benachrichtigung bei Stundenende', priority: 'high', status: 'done', phase: 'phase-6', effort: 'small' }, { id: 'f51', title: 'Connection Status Indicator', description: 'UI-Element zeigt Live/Polling/Offline Status', priority: 'medium', status: 'done', phase: 'phase-6', effort: 'small' }, { id: 'f52', title: 'WebSocket Status API', description: 'GET /ws/status zeigt aktive Sessions und Verbindungszahlen', priority: 'low', status: 'done', phase: 'phase-6', effort: 'small' }, // Phase 7 - Erweiterungen (Auth & Feedback) { id: 'f53', title: 'Teacher Feedback API', description: 'POST/GET /feedback Endpoints fuer Bug-Reports und Feature-Requests', priority: 'high', status: 'done', phase: 'phase-7', effort: 'large' }, { id: 'f54', title: 'Feedback Modal UI', description: 'Floating Action Button und Modal im Lehrer-Frontend', priority: 'high', status: 'done', phase: 'phase-7', effort: 'medium' }, { id: 'f55', title: 'Feedback DB Model', description: 'TeacherFeedbackDB SQLAlchemy Model mit Alembic Migration', priority: 'high', status: 'done', phase: 'phase-7', effort: 'medium' }, { id: 'f56', title: 'Feedback Repository', description: 'CRUD-Operationen fuer Feedback mit Status-Management', priority: 'high', status: 'done', phase: 'phase-7', effort: 'medium' }, { id: 'f57', title: 'Keycloak Auth Integration', description: 'Optional Auth Dependency mit Demo-User Fallback', priority: 'critical', status: 'done', phase: 'phase-7', effort: 'medium' }, { id: 'f58', title: 'Feedback Stats API', description: 'GET /feedback/stats fuer Dashboard-Statistiken', priority: 'medium', status: 'done', phase: 'phase-7', effort: 'small' }, // Phase 8 - Schuljahres-Begleiter (2-Schichten-Modell) { id: 'f59', title: 'TeacherContextDB Model', description: 'Makro-Kontext pro Lehrer (Bundesland, Schulart, Schuljahr, Phase)', priority: 'critical', status: 'done', phase: 'phase-8', effort: 'medium' }, { id: 'f60', title: 'SchoolyearEventDB Model', description: 'Events (Klausuren, Elternabende, Klassenfahrten, etc.)', priority: 'critical', status: 'done', phase: 'phase-8', effort: 'medium' }, { id: 'f61', title: 'RecurringRoutineDB Model', description: 'Wiederkehrende Routinen (Konferenzen, Sprechstunden, etc.)', priority: 'critical', status: 'done', phase: 'phase-8', effort: 'medium' }, { id: 'f62', title: 'Alembic Migration 007', description: 'DB-Migration fuer teacher_contexts, schoolyear_events, recurring_routines', priority: 'critical', status: 'done', phase: 'phase-8', effort: 'small' }, { id: 'f63', title: 'GET /v1/context Endpoint', description: 'Makro-Kontext abrufen (Schuljahr, Woche, Phase, Flags)', priority: 'critical', status: 'done', phase: 'phase-8', effort: 'large' }, { id: 'f64', title: 'PUT /v1/context Endpoint', description: 'Kontext aktualisieren (Bundesland, Schulart, Schuljahr)', priority: 'high', status: 'done', phase: 'phase-8', effort: 'medium' }, { id: 'f65', title: 'Events CRUD-API', description: 'GET/POST/DELETE /v1/events mit Status und Vorbereitung', priority: 'high', status: 'done', phase: 'phase-8', effort: 'large' }, { id: 'f66', title: 'Routines CRUD-API', description: 'GET/POST/DELETE /v1/routines mit Wiederholungsmustern', priority: 'high', status: 'done', phase: 'phase-8', effort: 'large' }, { id: 'f67', title: 'Stammdaten-APIs', description: '/v1/federal-states, /v1/school-types, /v1/macro-phases, /v1/event-types', priority: 'medium', status: 'done', phase: 'phase-8', effort: 'small' }, { id: 'f68', title: 'Context Repositories', description: 'TeacherContextRepository, SchoolyearEventRepository, RecurringRoutineRepository', priority: 'high', status: 'done', phase: 'phase-8', effort: 'large' }, { id: 'f69', title: 'Antizipations-Engine', description: 'Signal-Collector + Regel-Engine (12 Regeln) fuer proaktive Vorschlaege', priority: 'high', status: 'done', phase: 'phase-8', effort: 'epic' }, { id: 'f70', title: 'GET /v1/suggestions Endpoint', description: 'Kontextbasierte Vorschlaege mit active_contexts[]', priority: 'high', status: 'done', phase: 'phase-8', effort: 'large' }, { id: 'f71', title: 'GET /v1/sidebar Endpoint', description: 'Dynamisches Sidebar-Model (Companion vs Classic Mode)', priority: 'medium', status: 'done', phase: 'phase-8', effort: 'medium' }, { id: 'f72', title: 'GET /v1/path Endpoint', description: 'Schuljahres-Meilensteine mit Status (DONE, CURRENT, UPCOMING)', priority: 'medium', status: 'done', phase: 'phase-8', effort: 'medium' }, { id: 'f73', title: 'ContextBar Component', description: 'Schuljahr, Woche, Bundesland Anzeige im Header', priority: 'medium', status: 'done', phase: 'phase-8', effort: 'medium' }, { id: 'f74', title: 'Begleiter-Sidebar', description: 'Top 5 relevante Module + Alle Module + Suche', priority: 'medium', status: 'done', phase: 'phase-8', effort: 'large' }, { id: 'f75', title: 'PathPanel Component', description: 'Vertikaler Schuljahres-Pfad mit "Du bist hier" Markierung', priority: 'medium', status: 'done', phase: 'phase-8', effort: 'medium' }, { id: 'f76', title: 'Onboarding-Flow', description: 'Bundesland, Schulart, Schuljahres-Start, erste Klassen', priority: 'high', status: 'backlog', phase: 'phase-8', effort: 'large' }, { id: 'f77', title: 'Complete Onboarding API', description: 'POST /v1/context/complete-onboarding zum Abschliessen', priority: 'high', status: 'done', phase: 'phase-8', effort: 'small' }, ] const initialFeedback: TeacherFeedback[] = [ { id: 'fb1', teacher: 'Frau Mueller', date: '2026-01-14', type: 'feature_request', priority: 'high', status: 'implemented', title: 'Individuelle Phasen-Dauern', description: 'Ich moechte die Dauern der einzelnen Phasen selbst festlegen koennen, je nach Unterrichtseinheit.', relatedFeature: 'f16', response: 'In Phase 7 implementiert: Einstellungen-Button oeffnet Modal zur Konfiguration der Phasendauern.', }, { id: 'fb2', teacher: 'Herr Schmidt', date: '2026-01-14', type: 'improvement', priority: 'medium', status: 'implemented', title: 'Akustisches Signal bei Phasen-Ende', description: 'Ein kurzer Ton wuerde helfen, das Ende einer Phase nicht zu verpassen.', relatedFeature: 'f33', response: 'Audio Cues wurden in Phase 2b implementiert - sanfte Toene statt harter Alarme. Taste A zum Toggle.', }, { id: 'fb3', teacher: 'Frau Wagner', date: '2026-01-15', type: 'praise', priority: 'low', status: 'acknowledged', title: 'Super einfache Bedienung!', description: 'Die Stunden-Steuerung ist sehr intuitiv. Meine erste Stunde damit hat super geklappt.', }, { id: 'fb4', teacher: 'Herr Becker', date: '2026-01-15', type: 'bug', priority: 'high', status: 'implemented', title: 'Timer stoppt bei Browser-Tab-Wechsel', description: 'Wenn ich den Browser-Tab wechsle und zurueckkomme, zeigt der Timer manchmal falsche Werte.', relatedFeature: 'f35', response: 'Offline Timer Fallback in Phase 2b implementiert + WebSocket Real-time in Phase 6.', }, { id: 'fb5', teacher: 'Frau Klein', date: '2026-01-15', type: 'feature_request', priority: 'critical', status: 'implemented', title: 'Pause-Funktion', description: 'Manchmal muss ich die Stunde kurz unterbrechen (Stoerung, Durchsage). Eine Pause-Funktion waere super.', relatedFeature: 'f27', response: 'Pause Timer API und Quick Actions Bar wurden in Phase 2b implementiert. Tastenkuerzel: Leertaste.', }, { id: 'fb6', teacher: 'Herr Hoffmann', date: '2026-01-15', type: 'feature_request', priority: 'high', status: 'implemented', title: 'Visueller Timer statt Zahlen', description: 'Der numerische Countdown ist manchmal stressig. Ein visueller Kreis-Timer waere entspannter.', relatedFeature: 'f21', response: 'Visual Pie Timer mit Farbverlauf (Gruen→Gelb→Rot) wurde in Phase 2b implementiert.', }, { id: 'fb7', teacher: 'Frau Richter', date: '2026-01-15', type: 'feature_request', priority: 'high', status: 'implemented', title: 'Tablet-Nutzung im Klassenraum', description: 'Ich laufe waehrend des Unterrichts herum. Die Anzeige muesste auch auf meinem iPad gut funktionieren.', relatedFeature: 'f24', response: 'Tablet-First Responsive Design wurde in Phase 2b implementiert. Touch-Targets min 48x48px.', }, { id: 'fb8', teacher: 'Herr Weber', date: '2026-01-15', type: 'improvement', priority: 'medium', status: 'implemented', title: '+5 Minuten Button', description: 'Manchmal brauche ich einfach nur 5 Minuten mehr fuer eine Phase. Ein Schnell-Button waere praktisch.', relatedFeature: 'f28', response: 'In Quick Actions Bar integriert. Tastenkuerzel: E.', }, { id: 'fb9', teacher: 'Frau Schneider', date: '2026-01-15', type: 'praise', priority: 'low', status: 'acknowledged', title: 'Phasen-Vorschlaege sind hilfreich', description: 'Die Aktivitaets-Vorschlaege pro Phase geben mir gute Ideen. Weiter so!', }, { id: 'fb10', teacher: 'Herr Meier', date: '2026-01-15', type: 'feature_request', priority: 'medium', status: 'implemented', title: 'Stundenvorlage speichern', description: 'Fuer Mathe-Stunden nutze ich immer die gleiche Phasen-Aufteilung. Waere cool, das als Template zu speichern.', relatedFeature: 'f37', response: 'Lesson Templates wurden in Phase 4 implementiert. 5 System-Templates + eigene Vorlagen moeglich.', }, ] // ==================== SYSTEM INFO CONFIG ==================== const companionSystemInfo = { title: 'Companion Module System Info', description: 'Technische Details zur Classroom State Machine', version: '1.1.0', architecture: { layers: [ { title: 'Frontend Layer', components: [ 'companion.py (Lesson-Modus UI)', 'Mode Toggle (Begleiter/Stunde/Klassisch)', 'Timer Display Component', 'Phase Timeline Component', 'Suggestions Cards', 'Material Design Icons (CDN)', ], color: 'bg-blue-50', }, { title: 'API Layer', components: [ 'classroom_api.py (FastAPI Router)', 'POST /sessions - Session erstellen', 'POST /sessions/{id}/start - Stunde starten', 'POST /sessions/{id}/next-phase - Naechste Phase', 'POST /sessions/{id}/pause - Timer pausieren', 'POST /sessions/{id}/extend - Phase verlaengern', 'GET /sessions/{id}/timer - Timer Status', 'GET /sessions/{id}/suggestions - Vorschlaege', 'GET /history/{teacher_id} - Session History', 'GET /health - Health Check mit DB-Status', 'GET/PUT /v1/context - Schuljahres-Kontext', 'GET/POST/DELETE /v1/events - Events CRUD', 'GET/POST/DELETE /v1/routines - Routinen CRUD', 'GET /v1/federal-states, /v1/school-types, etc.', ], color: 'bg-green-50', }, { title: 'Engine Layer', components: [ 'classroom_engine/ Package', 'models.py - LessonPhase, LessonSession', 'fsm.py - LessonStateMachine', 'timer.py - PhaseTimer', 'suggestions.py - SuggestionEngine', 'context_models.py - TeacherContextDB, SchoolyearEventDB, RecurringRoutineDB', 'antizipation.py - AntizipationsEngine (geplant)', ], color: 'bg-amber-50', }, { title: 'Storage Layer', components: [ 'Hybrid Storage (Memory + PostgreSQL)', 'SessionRepository (CRUD)', 'TeacherSettingsRepository', 'TeacherContextRepository (Phase 8)', 'SchoolyearEventRepository (Phase 8)', 'RecurringRoutineRepository (Phase 8)', 'Alembic Migrations (007: Phase 8 Tables)', 'Session History API', ], color: 'bg-purple-50', }, ], }, features: [ { name: '5-Phasen-Modell', status: 'active' as const, description: 'Einstieg, Erarbeitung, Sicherung, Transfer, Reflexion' }, { name: 'Timer mit Warning', status: 'active' as const, description: '2 Minuten Warnung vor Phasen-Ende' }, { name: 'Overtime Detection', status: 'active' as const, description: 'Anzeige wenn Phase ueberzogen wird' }, { name: 'Phasen-Suggestions', status: 'active' as const, description: '3-6 Aktivitaets-Vorschlaege pro Phase' }, { name: 'Visual Pie Timer', status: 'active' as const, description: 'Kreisfoermiger Countdown mit Farbverlauf' }, { name: 'Quick Actions Bar', status: 'active' as const, description: '+5min, Pause, Skip Buttons' }, { name: 'Tablet-First Design', status: 'active' as const, description: 'Touch-optimiert fuer Tablets' }, { name: 'Phasen-Farbschema', status: 'active' as const, description: 'Blau→Orange→Gruen→Lila→Grau' }, { name: 'Keyboard Shortcuts', status: 'active' as const, description: 'Space=Pause, N=Next, E=Extend, H=Contrast' }, { name: 'Audio Cues', status: 'active' as const, description: 'Sanfte Toene bei Phasenwechsel' }, { name: 'Offline Timer', status: 'active' as const, description: 'Client-seitige Fallback bei Verbindungsverlust' }, { name: 'DB Persistenz', status: 'active' as const, description: 'PostgreSQL Hybrid Storage' }, { name: 'Session History', status: 'active' as const, description: 'GET /history/{teacher_id} API' }, { name: 'Alembic Migrations', status: 'active' as const, description: 'Versionierte DB-Schema-Aenderungen' }, { name: 'Teacher Auth', status: 'active' as const, description: 'Keycloak Integration mit Optional Fallback (Phase 7)' }, { name: 'WebSocket Real-time', status: 'active' as const, description: 'Echtzeit-Updates mit 1-Sekunden-Genauigkeit (Phase 6)' }, { name: 'Schuljahres-Kontext', status: 'active' as const, description: 'Makro-Phasen, Bundesland, Schulart (Phase 8)' }, { name: 'Events & Routinen', status: 'active' as const, description: 'Klausuren, Konferenzen, Elternabende (Phase 8)' }, { name: 'Antizipations-Engine', status: 'active' as const, description: '12 Regeln fuer proaktive Vorschlaege (Phase 8)' }, { name: 'Dynamische Sidebar', status: 'active' as const, description: 'Top 5 relevante Module + Alle Module (Phase 8)' }, { name: 'Schuljahres-Pfad', status: 'active' as const, description: '7 Meilensteine mit Fortschrittsanzeige (Phase 8)' }, ], roadmap: [ { phase: 'Phase 1: Core Engine', priority: 'high' as const, items: ['FSM', 'Timer', 'Suggestions', 'API'] }, { phase: 'Phase 2: Frontend', priority: 'high' as const, items: ['Lesson-Modus UI', 'Timer Display', 'Timeline'] }, { phase: 'Phase 2b: UX Optimierung', priority: 'high' as const, items: ['Visual Timer', 'Farbschema', 'Tablet-First', 'Quick Actions'] }, { phase: 'Phase 3: Persistenz', priority: 'high' as const, items: ['PostgreSQL', 'Keycloak Auth', 'Session History'] }, { phase: 'Phase 4: Content', priority: 'medium' as const, items: ['Unit-Vorschlaege', 'Templates', 'Hausaufgaben'] }, { phase: 'Phase 5: Analytics', priority: 'medium' as const, items: ['Statistiken (ohne Bewertung)', 'PDF Export'] }, { phase: 'Phase 6: Real-time', priority: 'low' as const, items: ['WebSocket', 'Offline Fallback', 'Multi-Device'] }, ], technicalDetails: [ { component: 'Backend', technology: 'Python FastAPI', version: '0.123+', description: 'Async REST API' }, { component: 'State Machine', technology: 'Python Enum + Dataclass', description: 'Finite State Machine Pattern' }, { component: 'Timer', technology: 'datetime.utcnow()', description: 'Server-side Time Calculation' }, { component: 'Frontend', technology: 'Vanilla JavaScript ES6+', description: 'In companion.py eingebettet' }, { component: 'Icons', technology: 'Material Design Icons', description: 'Via Google Fonts CDN (Apache-2.0)' }, { component: 'WebSocket', technology: 'FastAPI WebSocket', description: 'Echtzeit-Updates mit 1-Sekunden-Genauigkeit + Polling Fallback' }, { component: 'Database', technology: 'PostgreSQL + SQLAlchemy 2.0', description: 'Hybrid Storage (Memory + DB)' }, { component: 'Migrations', technology: 'Alembic 1.14', description: 'Versionierte Schema-Migrationen' }, ], privacyNotes: [ 'Keine Schueler-Daten werden gespeichert', 'Session-Daten sind nur waehrend der Stunde verfuegbar', 'Lehrer-ID wird fuer Session-Zuordnung verwendet', 'Keine Tracking-Cookies oder externe Services', 'Analytics ohne bewertende Metriken (keine "70% Redezeit"-Anzeigen)', ], } // ==================== COMPONENT ==================== export default function CompanionDevPage() { const [features, setFeatures] = useState(initialFeatures) const [feedback, setFeedback] = useState(initialFeedback) const [activeTab, setActiveTab] = useState<'roadmap' | 'features' | 'feedback' | 'backlog'>('roadmap') const [selectedPhase, setSelectedPhase] = useState(null) const [feedbackFilter, setFeedbackFilter] = useState('all') // Data version - increment when adding new features/feedback to force refresh const DATA_VERSION = '8.2.0' // Phase 8e: Frontend UI-Komponenten (ContextBar, Sidebar, PathPanel) // Load from localStorage with version check useEffect(() => { const savedVersion = localStorage.getItem('companion-dev-version') const savedFeatures = localStorage.getItem('companion-dev-features') const savedFeedback = localStorage.getItem('companion-dev-feedback') // If version mismatch or no version, use initial data and save new version if (savedVersion !== DATA_VERSION) { console.log(`Companion Dev: Data version updated from ${savedVersion} to ${DATA_VERSION}`) localStorage.setItem('companion-dev-version', DATA_VERSION) localStorage.setItem('companion-dev-features', JSON.stringify(initialFeatures)) localStorage.setItem('companion-dev-feedback', JSON.stringify(initialFeedback)) // State already initialized with initialFeatures/initialFeedback, no need to setFeatures return } // Load saved data if version matches if (savedFeatures) setFeatures(JSON.parse(savedFeatures)) if (savedFeedback) setFeedback(JSON.parse(savedFeedback)) }, []) // Save to localStorage useEffect(() => { localStorage.setItem('companion-dev-features', JSON.stringify(features)) }, [features]) useEffect(() => { localStorage.setItem('companion-dev-feedback', JSON.stringify(feedback)) }, [feedback]) const getPhaseStats = () => { const total = roadmapPhases.length const completed = roadmapPhases.filter(p => p.status === 'completed').length const inProgress = roadmapPhases.filter(p => p.status === 'in_progress').length return { total, completed, inProgress } } const getFeatureStats = () => { const total = features.length const done = features.filter(f => f.status === 'done').length const inProgress = features.filter(f => f.status === 'in_progress').length return { total, done, inProgress, percentage: Math.round((done / total) * 100) } } const getFeedbackStats = () => { const total = feedback.length const newCount = feedback.filter(f => f.status === 'new').length const bugs = feedback.filter(f => f.type === 'bug').length const requests = feedback.filter(f => f.type === 'feature_request').length return { total, newCount, bugs, requests } } const updateFeatureStatus = (id: string, status: Feature['status']) => { setFeatures(features.map(f => f.id === id ? { ...f, status } : f)) } const updateFeedbackStatus = (id: string, status: TeacherFeedback['status']) => { setFeedback(feedback.map(f => f.id === id ? { ...f, status } : f)) } const phaseStats = getPhaseStats() const featureStats = getFeatureStats() const feedbackStats = getFeedbackStats() const statusColors = { done: 'bg-green-100 text-green-800', in_progress: 'bg-blue-100 text-blue-800', todo: 'bg-amber-100 text-amber-800', backlog: 'bg-slate-100 text-slate-600', } const priorityColors = { critical: 'bg-red-500 text-white', high: 'bg-orange-500 text-white', medium: 'bg-yellow-500 text-white', low: 'bg-slate-400 text-white', } const feedbackTypeIcons: Record = { bug: 'M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z', feature_request: 'M12 6v6m0 0v6m0-6h6m-6 0H6', improvement: 'M13 10V3L4 14h7v7l9-11h-7z', praise: 'M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z', question: 'M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z', } const filteredFeedback = feedbackFilter === 'all' ? feedback : feedback.filter(f => f.type === feedbackFilter || f.status === feedbackFilter) return ( {/* Stats Overview */}
Roadmap-Phasen
{phaseStats.completed}/{phaseStats.total}
{phaseStats.inProgress} in Arbeit
Features
{featureStats.percentage}%
{featureStats.done}/{featureStats.total} fertig
Neues Feedback
{feedbackStats.newCount}
{feedbackStats.total} gesamt
Offene Bugs
{feedbackStats.bugs}
{feedbackStats.requests} Feature-Requests
{/* Tab Navigation */}
{/* Roadmap Tab */} {activeTab === 'roadmap' && (
{roadmapPhases.map((phase, index) => (
{phase.status === 'completed' ? '✓' : index + 1}

{phase.name}

{phase.description}

{phase.status === 'completed' ? 'Abgeschlossen' : phase.status === 'in_progress' ? 'In Arbeit' : phase.status === 'planned' ? 'Geplant' : 'Zukunft'} {phase.startDate && (
{phase.startDate} {phase.endDate ? `- ${phase.endDate}` : ''}
)}
{/* Progress Bar */}
Fortschritt {phase.progress}%
{/* Features */}
{phase.features.map((feature, i) => ( {feature} ))}
))}
)} {/* Features Tab */} {activeTab === 'features' && (
{/* Phase Filter */}
{roadmapPhases.map(phase => ( ))}
{/* Features List */}
{features .filter(f => !selectedPhase || f.phase === selectedPhase) .map(feature => (
{feature.priority}
{feature.title}
{feature.description}
{feature.effort}
))}
)} {/* Feedback Tab */} {activeTab === 'feedback' && (
{/* Filter */}
{['all', 'new', 'bug', 'feature_request', 'improvement'].map(filter => ( ))}
{/* Feedback List */}
{filteredFeedback.map(fb => (
{fb.title} {fb.priority}

{fb.description}

{fb.teacher} {fb.date} {fb.relatedFeature && ( → {features.find(f => f.id === fb.relatedFeature)?.title} )}
{fb.response && (
Antwort: {fb.response}
)}
))}
{/* Add Feedback Button */}
)} {/* Backlog Tab */} {activeTab === 'backlog' && (
{/* Todo Column */}

{features.filter(f => f.status === 'todo').length} Todo

{features.filter(f => f.status === 'todo').map(f => (
{f.title}
{f.description}
{f.priority} {f.effort}
))}
{/* In Progress Column */}

{features.filter(f => f.status === 'in_progress').length} In Arbeit

{features.filter(f => f.status === 'in_progress').map(f => (
{f.title}
{f.description}
{f.priority}
))}
{/* Backlog Column */}

{features.filter(f => f.status === 'backlog').length} Backlog

{features.filter(f => f.status === 'backlog').map(f => (
{f.title}
{f.description}
{f.priority}
))}
)}
{/* System Info Section */}
) }