'use client' import { useState } from 'react' import AdminLayout from '@/components/admin/AdminLayout' import { WizardStepper, WizardNavigation, EducationCard, ArchitectureContext, TestRunner, TestSummary, type WizardStep, type TestCategoryResult, type FullTestResults, type EducationContent, type ArchitectureContextType, } from '@/components/wizard' // ============================================== // Constants // ============================================== const BACKEND_URL = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8000' const STEPS: WizardStep[] = [ { id: 'welcome', name: 'Willkommen', icon: '👋', status: 'pending' }, { id: 'api-health', name: 'API Status', icon: '💚', status: 'pending', category: 'api-health' }, { id: 'matrix', name: 'Matrix', icon: '💬', status: 'pending', category: 'matrix' }, { id: 'jitsi', name: 'Jitsi', icon: '📹', status: 'pending', category: 'jitsi' }, { id: 'summary', name: 'Zusammenfassung', icon: '📊', status: 'pending' }, ] const EDUCATION_CONTENT: Record = { 'welcome': { title: 'Willkommen zum Communication Wizard', content: [ 'Sichere Kommunikation ist das Rueckgrat moderner Bildungsplattformen.', '', 'BreakPilot nutzt zwei Open-Source Systeme:', '• Matrix Synapse: Dezentraler Messenger (Ende-zu-Ende verschluesselt)', '• Jitsi Meet: Video-Konferenzen (WebRTC-basiert)', '', 'Beide Systeme sind DSGVO-konform und self-hosted.', '', 'In diesem Wizard testen wir:', '• Matrix Homeserver und Federation', '• Jitsi Video-Konferenz Server', '• Integration mit der Schulverwaltung', ], }, 'api-health': { title: 'Communication API - Backend Integration', content: [ 'Die Communication API verbindet Matrix und Jitsi mit BreakPilot.', '', 'Funktionen:', '• Automatische Raum-Erstellung fuer Klassen', '• Eltern-Lehrer DM-Raeume', '• Meeting-Planung mit Kalender-Integration', '• Benachrichtigungen bei neuen Nachrichten', '', 'Endpunkte:', '• /api/v1/communication/admin/stats', '• /api/v1/communication/admin/matrix/users', '• /api/v1/communication/rooms', ], }, 'matrix': { title: 'Matrix Synapse - Dezentraler Messenger', content: [ 'Matrix ist ein offenes Protokoll fuer sichere Kommunikation.', '', 'Vorteile gegenueber WhatsApp/Teams:', '• Ende-zu-Ende Verschluesselung (E2EE)', '• Dezentral: Kein Single Point of Failure', '• Federation: Kommunikation mit anderen Schulen', '• Self-Hosted: Volle Datenkontrolle', '', 'Raum-Typen in BreakPilot:', '• Klassen-Info (Ankuendigungen)', '• Elternvertreter-Raum', '• Lehrer-Eltern DM', '• Fachgruppen', ], }, 'jitsi': { title: 'Jitsi Meet - Video-Konferenzen', content: [ 'Jitsi ist eine Open-Source Alternative zu Zoom/Teams.', '', 'Features:', '• WebRTC: Keine Software-Installation noetig', '• Bildschirmfreigabe und Whiteboard', '• Breakout-Raeume fuer Gruppenarbeit', '• Aufzeichnung (optional, lokal)', '', 'Anwendungsfaelle:', '• Elternsprechtage (online)', '• Fernunterricht bei Schulausfall', '• Lehrerkonferenzen', '• Foerdergespraeche', ], }, 'summary': { title: 'Test-Zusammenfassung', content: [ 'Hier sehen Sie eine Uebersicht aller durchgefuehrten Tests:', '• Matrix Homeserver Verfuegbarkeit', '• Jitsi Server Status', '• API-Integration', ], }, } const ARCHITECTURE_CONTEXTS: Record = { 'api-health': { layer: 'api', services: ['backend', 'consent-service'], dependencies: ['PostgreSQL', 'Matrix Synapse', 'Jitsi'], dataFlow: ['Browser', 'FastAPI', 'Go Service', 'Matrix/Jitsi'], }, 'matrix': { layer: 'service', services: ['matrix'], dependencies: ['PostgreSQL', 'Federation', 'TURN Server'], dataFlow: ['Element Client', 'Matrix Synapse', 'Federation', 'PostgreSQL'], }, 'jitsi': { layer: 'service', services: ['jitsi'], dependencies: ['Prosody XMPP', 'JVB', 'TURN/STUN'], dataFlow: ['Browser', 'Nginx', 'Prosody', 'Jitsi Videobridge'], }, } // ============================================== // Main Component // ============================================== export default function CommunicationWizardPage() { const [currentStep, setCurrentStep] = useState(0) const [steps, setSteps] = useState(STEPS) const [categoryResults, setCategoryResults] = useState>({}) const [fullResults, setFullResults] = useState(null) const [isLoading, setIsLoading] = useState(false) const [error, setError] = useState(null) const currentStepData = steps[currentStep] const isTestStep = currentStepData?.category !== undefined const isWelcome = currentStepData?.id === 'welcome' const isSummary = currentStepData?.id === 'summary' const runCategoryTest = async (category: string) => { setIsLoading(true) setError(null) try { const response = await fetch(`${BACKEND_URL}/api/admin/communication-tests/${category}`, { method: 'POST', }) if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`) } const result: TestCategoryResult = await response.json() setCategoryResults((prev) => ({ ...prev, [category]: result })) setSteps((prev) => prev.map((step) => step.category === category ? { ...step, status: result.failed === 0 ? 'completed' : 'failed' } : step ) ) } catch (err) { setError(err instanceof Error ? err.message : 'Unbekannter Fehler') } finally { setIsLoading(false) } } const runAllTests = async () => { setIsLoading(true) setError(null) try { const response = await fetch(`${BACKEND_URL}/api/admin/communication-tests/run-all`, { method: 'POST', }) if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`) } const results: FullTestResults = await response.json() setFullResults(results) setSteps((prev) => prev.map((step) => { if (step.category) { const catResult = results.categories.find((c) => c.category === step.category) if (catResult) { return { ...step, status: catResult.failed === 0 ? 'completed' : 'failed' } } } return step }) ) const newCategoryResults: Record = {} results.categories.forEach((cat) => { newCategoryResults[cat.category] = cat }) setCategoryResults(newCategoryResults) } catch (err) { setError(err instanceof Error ? err.message : 'Unbekannter Fehler') } finally { setIsLoading(false) } } const goToNext = () => { if (currentStep < steps.length - 1) { setSteps((prev) => prev.map((step, idx) => idx === currentStep && step.status === 'pending' ? { ...step, status: 'completed' } : step ) ) setCurrentStep((prev) => prev + 1) } } const goToPrev = () => { if (currentStep > 0) { setCurrentStep((prev) => prev - 1) } } const handleStepClick = (index: number) => { if (index <= currentStep || steps[index - 1]?.status !== 'pending') { setCurrentStep(index) } } return ( {/* Header */}
💬

Communication Test Wizard

Matrix Messenger & Jitsi Video

← Zurueck zu Communication
{/* Stepper */}
{/* Content */}
{currentStepData?.icon}

Schritt {currentStep + 1}: {currentStepData?.name}

{currentStep + 1} von {steps.length}

{isTestStep && currentStepData?.category && ARCHITECTURE_CONTEXTS[currentStepData.category] && ( )} {error && (
Fehler: {error}
)} {isWelcome && (
)} {isTestStep && currentStepData?.category && ( runCategoryTest(currentStepData.category!)} /> )} {isSummary && (
{!fullResults ? (

Fuehren Sie alle Tests aus um eine Zusammenfassung zu sehen.

) : ( )}
)}
Diese Tests pruefen die Matrix- und Jitsi-Integration. Bei Fragen wenden Sie sich an das IT-Team.
) }